summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavidben@chromium.org <davidben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-11 19:33:40 +0000
committerdavidben@chromium.org <davidben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-11 19:33:40 +0000
commit8004db2a466136e59d40c37c72d7d8b739b67862 (patch)
tree9bb61bc4b0d09c18b60eb92ea5eb1623cf27d8d8
parent8b8cc6412f10b7142370593ab07af8632e736f17 (diff)
downloadchromium_src-8004db2a466136e59d40c37c72d7d8b739b67862.zip
chromium_src-8004db2a466136e59d40c37c72d7d8b739b67862.tar.gz
chromium_src-8004db2a466136e59d40c37c72d7d8b739b67862.tar.bz2
Implement a tab-modal constrained sheet on OS X for certificate selection
R=thakis BUG=50710 TEST=SSL client auth on OS X still works Review URL: http://codereview.chromium.org/3050028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55768 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/cocoa/constrained_window_mac.h10
-rw-r--r--chrome/browser/cocoa/constrained_window_mac.mm18
-rw-r--r--chrome/browser/cocoa/ssl_client_certificate_selector.mm85
-rw-r--r--chrome/browser/ssl_client_certificate_selector.h4
4 files changed, 90 insertions, 27 deletions
diff --git a/chrome/browser/cocoa/constrained_window_mac.h b/chrome/browser/cocoa/constrained_window_mac.h
index 5054599..321f9c7b 100644
--- a/chrome/browser/cocoa/constrained_window_mac.h
+++ b/chrome/browser/cocoa/constrained_window_mac.h
@@ -60,6 +60,16 @@ class ConstrainedWindowMacDelegateSystemSheet
void set_sheet(id sheet) { systemSheet_.reset([sheet retain]); }
id sheet() { return systemSheet_; }
+ // Returns an NSArray to be passed as parameters to GTMWindowSheetController.
+ // Array's contents should be the arguments passed to the system sheet's
+ // beginSheetForWindow:... method. The window argument must be [NSNull null].
+ //
+ // The default implementation returns
+ // [null window, delegate, didEndSelector, null contextInfo]
+ // Subclasses may override this if they show a system sheet which takes
+ // different parameters.
+ virtual NSArray* GetSheetParameters(id delegate, SEL didEndSelector);
+
private:
virtual void RunSheet(GTMWindowSheetController* sheetController,
NSView* view);
diff --git a/chrome/browser/cocoa/constrained_window_mac.mm b/chrome/browser/cocoa/constrained_window_mac.mm
index eec4dba..e063896 100644
--- a/chrome/browser/cocoa/constrained_window_mac.mm
+++ b/chrome/browser/cocoa/constrained_window_mac.mm
@@ -11,15 +11,21 @@
ConstrainedWindowMacDelegate::~ConstrainedWindowMacDelegate() {}
-void ConstrainedWindowMacDelegateSystemSheet::RunSheet(
- GTMWindowSheetController* sheetController,
- NSView* view) {
- NSArray* params = [NSArray arrayWithObjects:
+NSArray* ConstrainedWindowMacDelegateSystemSheet::GetSheetParameters(
+ id delegate,
+ SEL didEndSelector) {
+ return [NSArray arrayWithObjects:
[NSNull null], // window, must be [NSNull null]
- delegate_.get(),
- [NSValue valueWithPointer:didEndSelector_],
+ delegate,
+ [NSValue valueWithPointer:didEndSelector],
[NSValue valueWithPointer:NULL], // context info for didEndSelector_.
nil];
+}
+
+void ConstrainedWindowMacDelegateSystemSheet::RunSheet(
+ GTMWindowSheetController* sheetController,
+ NSView* view) {
+ NSArray* params = GetSheetParameters(delegate_.get(), didEndSelector_);
[sheetController beginSystemSheet:systemSheet_
modalForView:view
withParameters:params];
diff --git a/chrome/browser/cocoa/ssl_client_certificate_selector.mm b/chrome/browser/cocoa/ssl_client_certificate_selector.mm
index 82d9822..48cb48a 100644
--- a/chrome/browser/cocoa/ssl_client_certificate_selector.mm
+++ b/chrome/browser/cocoa/ssl_client_certificate_selector.mm
@@ -15,12 +15,63 @@
#import "base/scoped_nsobject.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
+#import "chrome/browser/cocoa/constrained_window_mac.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/ssl/ssl_client_auth_handler.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "grit/generated_resources.h"
#include "net/base/x509_certificate.h"
+namespace {
+
+class ConstrainedSFChooseIdentityPanel
+ : public ConstrainedWindowMacDelegateSystemSheet {
+ public:
+ ConstrainedSFChooseIdentityPanel(SFChooseIdentityPanel* panel,
+ id delegate, SEL didEndSelector,
+ NSArray* identities, NSString* message)
+ : ConstrainedWindowMacDelegateSystemSheet(delegate, didEndSelector),
+ identities_([identities retain]),
+ message_([message retain]) {
+ set_sheet(panel);
+ }
+
+ virtual ~ConstrainedSFChooseIdentityPanel() {
+ // As required by ConstrainedWindowMacDelegate, close the sheet if
+ // it's still open.
+ if (is_sheet_open()) {
+ [NSApp endSheet:sheet()
+ returnCode:NSFileHandlingPanelCancelButton];
+ }
+ }
+
+ // ConstrainedWindowMacDelegateSystemSheet implementation:
+ virtual void DeleteDelegate() {
+ delete this;
+ }
+
+ // SFChooseIdentityPanel's beginSheetForWindow: method has more arguments
+ // than the usual one. Also pass the panel through contextInfo argument
+ // because the callback has the wrong signature.
+ virtual NSArray* GetSheetParameters(id delegate, SEL didEndSelector) {
+ return [NSArray arrayWithObjects:
+ [NSNull null], // window, must be [NSNull null]
+ delegate,
+ [NSValue valueWithPointer:didEndSelector],
+ [NSValue valueWithPointer:sheet()],
+ identities_.get(),
+ message_.get(),
+ nil];
+ }
+
+ private:
+ scoped_nsobject<NSArray> identities_;
+ scoped_nsobject<NSString> message_;
+ DISALLOW_COPY_AND_ASSIGN(ConstrainedSFChooseIdentityPanel);
+};
+
+} // namespace
+
@interface SSLClientCertificateSelectorCocoa : NSObject {
@private
// The handler to report back to.
@@ -31,11 +82,13 @@
scoped_nsobject<NSMutableArray> identities_;
// The corresponding list of certificates.
std::vector<scoped_refptr<net::X509Certificate> > certificates_;
+ // The currently open dialog.
+ ConstrainedWindow* window_;
}
- (id)initWithHandler:(SSLClientAuthHandler*)handler
certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo;
-- (void)displayDialog:(gfx::NativeWindow)parent;
+- (void)displayDialog:(TabContents*)parent;
@end
namespace browser {
@@ -50,7 +103,7 @@ void ShowSSLClientCertificateSelector(
[[[SSLClientCertificateSelectorCocoa alloc]
initWithHandler:delegate
certRequestInfo:cert_request_info] autorelease];
- [selector displayDialog:parent->GetMessageBoxRootWindow()];
+ [selector displayDialog:parent];
}
} // namespace browser
@@ -64,6 +117,7 @@ void ShowSSLClientCertificateSelector(
if ((self = [super init])) {
handler_ = handler;
certRequestInfo_ = certRequestInfo;
+ window_ = NULL;
}
return self;
}
@@ -85,6 +139,9 @@ void ShowSSLClientCertificateSelector(
// Finally, tell the backend which identity (or none) the user selected.
handler_->CertificateSelected(cert);
+ // Close the constrained window.
+ DCHECK(window_);
+ window_->CloseConstrainedWindow();
// Now that the panel has closed, release it. Note that the autorelease is
// needed. After this callback returns, the panel is still accessed, so a
@@ -92,7 +149,8 @@ void ShowSSLClientCertificateSelector(
[panel autorelease];
}
-- (void)displayDialog:(gfx::NativeWindow)parent {
+- (void)displayDialog:(TabContents*)parent {
+ DCHECK(!window_);
// Create an array of CFIdentityRefs for the certificates:
size_t numCerts = certRequestInfo_->client_certs.size();
identities_.reset([[NSMutableArray alloc] initWithCapacity:numCerts]);
@@ -129,25 +187,14 @@ void ShowSSLClientCertificateSelector(
CFRelease(sslPolicy);
}
+ window_ =
+ parent->CreateConstrainedDialog(new ConstrainedSFChooseIdentityPanel(
+ panel, self,
+ @selector(sheetDidEnd:returnCode:context:),
+ identities_, title));
// Note: SFChooseIdentityPanel does not take a reference to itself while the
// sheet is open. Don't release the ownership claim until the sheet has ended
// in |-sheetDidEnd:returnCode:context:|.
- if (parent) {
- // Open the cert panel as a sheet on the browser window. |panel| is passed
- // to itself as contextInfo because the didEndSelector has the wrong
- // signature; the NSWindow argument is the parent window. The panel also
- // retains a reference to its delegate, so no self retain is needed.
- [panel beginSheetForWindow:parent
- modalDelegate:self
- didEndSelector:@selector(sheetDidEnd:returnCode:context:)
- contextInfo:panel
- identities:identities_
- message:title];
- } else {
- // No available browser window, so run independently as a (blocking) dialog.
- int returnCode = [panel runModalForIdentities:identities_ message:title];
- [self sheetDidEnd:panel returnCode:returnCode context:panel];
- }
}
@end
diff --git a/chrome/browser/ssl_client_certificate_selector.h b/chrome/browser/ssl_client_certificate_selector.h
index 3b5c6e9..1886766 100644
--- a/chrome/browser/ssl_client_certificate_selector.h
+++ b/chrome/browser/ssl_client_certificate_selector.h
@@ -21,8 +21,8 @@ namespace browser {
// when the dialog closes in call cases; if the user cancels the dialog, we call
// with a NULL certificate.
//
-// Note: constrained dialog currently only implemented on Linux. On other
-// platforms, a window-modal dialog will be used.
+// Note: constrained dialog currently only implemented on Linux and OS X. On
+// Windows, a window-modal dialog will be used.
void ShowSSLClientCertificateSelector(
TabContents* parent,
net::SSLCertRequestInfo* cert_request_info,