Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.h" | 5 #import "chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.h" |
| 6 | 6 |
| 7 #import <SecurityInterface/SFChooseIdentityPanel.h> | 7 #import <SecurityInterface/SFChooseIdentityPanel.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 SSLClientCertificateSelectorCocoa* selector = | 98 SSLClientCertificateSelectorCocoa* selector = |
| 99 [[SSLClientCertificateSelectorCocoa alloc] | 99 [[SSLClientCertificateSelectorCocoa alloc] |
| 100 initWithBrowserContext:contents->GetBrowserContext() | 100 initWithBrowserContext:contents->GetBrowserContext() |
| 101 certRequestInfo:cert_request_info | 101 certRequestInfo:cert_request_info |
| 102 delegate:std::move(delegate)]; | 102 delegate:std::move(delegate)]; |
| 103 [selector displayForWebContents:contents]; | 103 [selector displayForWebContents:contents]; |
| 104 } | 104 } |
| 105 | 105 |
| 106 } // namespace chrome | 106 } // namespace chrome |
| 107 | 107 |
| 108 namespace { | |
| 109 | |
| 110 // These ClearTableViewDataSources... functions help work around a bug in macOS | |
| 111 // 10.12 where SFChooseIdentityPanel leaks a window and some views, including | |
| 112 // an NSTableView. Future events may make cause the table view to query its | |
| 113 // dataSource, which will have been deallocated. | |
| 114 // | |
| 115 // NSTableView.dataSource becomes a zeroing weak reference starting in 10.11, | |
|
Robert Sesek
2016/11/29 21:31:36
Use the availability macros to only do this work i
Sidney San Martín
2016/11/29 22:55:07
Done.
| |
| 116 // so this workaround can be removed once we're on the 10.11 SDK. | |
| 117 // | |
| 118 // rdar://29409207 | |
| 119 // BUG=653093 | |
|
Robert Sesek
2016/11/29 21:31:35
Make this a https://crbug.com/ URL please. (Could
Sidney San Martín
2016/11/29 22:55:07
Done.
| |
| 120 | |
| 121 void ClearTableViewDataSources(NSView* view){ | |
| 122 if (auto tableView = base::mac::ObjCCast<NSTableView>(view)) { | |
|
Robert Sesek
2016/11/29 21:31:35
naming: table_view
Sidney San Martín
2016/11/29 22:55:07
Done.
| |
| 123 tableView.dataSource = nil; | |
| 124 } else { | |
| 125 for (NSView* subview in view.subviews) { | |
| 126 ClearTableViewDataSources(subview); | |
| 127 } | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 void ClearTableViewDataSourcesIfWindowStillAround( | |
| 132 __unsafe_unretained NSWindow* leakedWindow) { | |
|
Robert Sesek
2016/11/29 21:31:35
naming: leaked_window
Robert Sesek
2016/11/29 21:31:35
Is the __unsafe_unretained so the block doesn't gr
Sidney San Martín
2016/11/29 22:55:07
Done.
Sidney San Martín
2016/11/29 22:55:07
That's the idea. Without ARC it's a noop, but I th
Robert Sesek
2016/11/30 00:23:32
I don't think this is a practice we currently foll
Sidney San Martín
2016/11/30 04:19:50
That's fair — and base::Unretained also gets that
| |
| 133 dispatch_async(dispatch_get_main_queue(), ^{ | |
|
Robert Sesek
2016/11/29 21:31:35
Why does this need to be done in dispatch_async()?
Sidney San Martín
2016/11/29 22:55:07
At the call site, the window is still in an autore
Robert Sesek
2016/11/30 00:23:32
It's Chrome's task posting system. You can use it
Sidney San Martín
2016/11/30 04:19:50
Done (mostly). If I get what you're saying, then m
Robert Sesek
2016/11/30 16:24:48
It is, but what you did is fine as well.
| |
| 134 for (NSWindow* window : [NSApp windows]) { | |
| 135 if (window == leakedWindow) { | |
| 136 ClearTableViewDataSources(window.contentView); | |
| 137 break; | |
| 138 } | |
| 139 } | |
| 140 }); | |
| 141 } | |
| 142 | |
| 143 } // namespace | |
| 144 | |
| 108 @implementation SSLClientCertificateSelectorCocoa | 145 @implementation SSLClientCertificateSelectorCocoa |
| 109 | 146 |
| 110 - (id)initWithBrowserContext:(const content::BrowserContext*)browserContext | 147 - (id)initWithBrowserContext:(const content::BrowserContext*)browserContext |
| 111 certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo | 148 certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo |
| 112 delegate: | 149 delegate: |
| 113 (std::unique_ptr<content::ClientCertificateDelegate>) | 150 (std::unique_ptr<content::ClientCertificateDelegate>) |
| 114 delegate { | 151 delegate { |
| 115 DCHECK(browserContext); | 152 DCHECK(browserContext); |
| 116 DCHECK(certRequestInfo); | 153 DCHECK(certRequestInfo); |
| 117 if ((self = [super init])) { | 154 if ((self = [super init])) { |
| 118 observer_.reset(new SSLClientAuthObserverCocoaBridge( | 155 observer_.reset(new SSLClientAuthObserverCocoaBridge( |
| 119 browserContext, certRequestInfo, std::move(delegate), self)); | 156 browserContext, certRequestInfo, std::move(delegate), self)); |
| 120 } | 157 } |
| 121 return self; | 158 return self; |
| 122 } | 159 } |
| 123 | 160 |
| 124 - (void)sheetDidEnd:(NSWindow*)parent | 161 - (void)sheetDidEnd:(NSWindow*)sheet |
| 125 returnCode:(NSInteger)returnCode | 162 returnCode:(NSInteger)returnCode |
| 126 context:(void*)context { | 163 context:(void*)context { |
| 127 net::X509Certificate* cert = NULL; | 164 net::X509Certificate* cert = NULL; |
| 128 if (returnCode == NSFileHandlingPanelOKButton) { | 165 if (returnCode == NSFileHandlingPanelOKButton) { |
| 129 CFRange range = CFRangeMake(0, CFArrayGetCount(identities_)); | 166 CFRange range = CFRangeMake(0, CFArrayGetCount(identities_)); |
| 130 CFIndex index = | 167 CFIndex index = |
| 131 CFArrayGetFirstIndexOfValue(identities_, range, [panel_ identity]); | 168 CFArrayGetFirstIndexOfValue(identities_, range, [panel_ identity]); |
| 132 if (index != -1) | 169 if (index != -1) |
| 133 cert = certificates_[index].get(); | 170 cert = certificates_[index].get(); |
| 134 else | 171 else |
| 135 NOTREACHED(); | 172 NOTREACHED(); |
| 136 } | 173 } |
| 137 | 174 |
| 175 // See comment at definition; this works around a 10.12 bug. | |
| 176 ClearTableViewDataSourcesIfWindowStillAround(sheet); | |
| 177 | |
| 138 if (!closePending_) { | 178 if (!closePending_) { |
| 139 // If |closePending_| is already set, |closeSheetWithAnimation:| was called | 179 // If |closePending_| is already set, |closeSheetWithAnimation:| was called |
| 140 // already to cancel the selection rather than continue with no | 180 // already to cancel the selection rather than continue with no |
| 141 // certificate. Otherwise, tell the backend which identity (or none) the | 181 // certificate. Otherwise, tell the backend which identity (or none) the |
| 142 // user selected. | 182 // user selected. |
| 143 userResponded_ = YES; | 183 userResponded_ = YES; |
| 144 observer_->CertificateSelected(cert); | 184 observer_->CertificateSelected(cert); |
| 145 | 185 |
| 146 constrainedWindow_->CloseWebContentsModalDialog(); | 186 constrainedWindow_->CloseWebContentsModalDialog(); |
| 147 } | 187 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 270 } | 310 } |
| 271 | 311 |
| 272 - (void)onConstrainedWindowClosed { | 312 - (void)onConstrainedWindowClosed { |
| 273 observer_->StopObserving(); | 313 observer_->StopObserving(); |
| 274 panel_.reset(); | 314 panel_.reset(); |
| 275 constrainedWindow_.reset(); | 315 constrainedWindow_.reset(); |
| 276 [self release]; | 316 [self release]; |
| 277 } | 317 } |
| 278 | 318 |
| 279 @end | 319 @end |
| OLD | NEW |