diff options
author | davidben@chromium.org <davidben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-11 19:33:40 +0000 |
---|---|---|
committer | davidben@chromium.org <davidben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-11 19:33:40 +0000 |
commit | 8004db2a466136e59d40c37c72d7d8b739b67862 (patch) | |
tree | 9bb61bc4b0d09c18b60eb92ea5eb1623cf27d8d8 | |
parent | 8b8cc6412f10b7142370593ab07af8632e736f17 (diff) | |
download | chromium_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.h | 10 | ||||
-rw-r--r-- | chrome/browser/cocoa/constrained_window_mac.mm | 18 | ||||
-rw-r--r-- | chrome/browser/cocoa/ssl_client_certificate_selector.mm | 85 | ||||
-rw-r--r-- | chrome/browser/ssl_client_certificate_selector.h | 4 |
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, |