| 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/certificate_viewer_mac.h" | 5 #import "chrome/browser/ui/cocoa/certificate_viewer_mac.h" |
| 6 | 6 |
| 7 #include <Security/Security.h> | 7 #include <Security/Security.h> |
| 8 #include <SecurityInterface/SFCertificatePanel.h> | 8 #include <SecurityInterface/SFCertificatePanel.h> |
| 9 #import <objc/runtime.h> |
| 9 #include <vector> | 10 #include <vector> |
| 10 | 11 |
| 11 #include "base/mac/foundation_util.h" | 12 #include "base/mac/foundation_util.h" |
| 13 #include "base/mac/mac_util.h" |
| 12 #include "base/mac/scoped_cftyperef.h" | 14 #include "base/mac/scoped_cftyperef.h" |
| 13 #include "base/macros.h" | 15 #include "base/macros.h" |
| 14 #include "chrome/browser/certificate_viewer.h" | 16 #include "chrome/browser/certificate_viewer.h" |
| 15 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" | 17 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" |
| 16 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h" | 18 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h" |
| 17 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_con
troller.h" | 19 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_con
troller.h" |
| 18 #include "net/cert/x509_certificate.h" | 20 #include "net/cert/x509_certificate.h" |
| 19 #include "net/cert/x509_util_mac.h" | 21 #include "net/cert/x509_util_mac.h" |
| 20 #import "ui/base/cocoa/window_size_constants.h" | 22 #import "ui/base/cocoa/window_size_constants.h" |
| 21 | 23 |
| 22 class SSLCertificateViewerCocoaBridge; | 24 class SSLCertificateViewerCocoaBridge; |
| 23 | 25 |
| 26 namespace { |
| 27 |
| 28 // The maximum height of the certificate panel. Imposed whenever Sierra's buggy |
| 29 // autolayout algorithm tries to change it. Doesn't affect user resizes. |
| 30 const CGFloat kMaxPanelSetFrameHeight = 400; |
| 31 |
| 32 // Pointer to the real implementation of -[SFCertificatePanel setFrame:..]. This |
| 33 // is cached so a correct lookup is performed before we add the override. |
| 34 IMP g_real_certificate_panel_setframe = nullptr; |
| 35 |
| 36 // Provide a workaround for a buggy autolayout algorithm in macOS Sierra when |
| 37 // running Chrome linked against the 10.10 SDK on macOS 10.12. |
| 38 // See http://crbug.com/643123 for more details. |
| 39 // Note it's not possible to inherit from SFCertificatePanel without triggering |
| 40 // *** Assertion failure in -[BrowserCrApplication |
| 41 // _commonBeginModalSessionForWindow:relativeToWindow:modalDelegate: |
| 42 // didEndSelector:contextInfo:], .../AppKit.subproj/NSApplication.m:4077 |
| 43 // After that assertion, the sheet simply refuses to continue loading. |
| 44 // It's also not possible to swizzle the -setFrame: method because |
| 45 // SFCertificatePanel doesn't define it. Attempting to swizzle that would |
| 46 // replace the implementation on NSWindow and constrain all dialogs. |
| 47 // So, provide a regular C method and append it to the SFCertificatePanel |
| 48 // implementation using the objc runtime. |
| 49 // TODO(tapted): Remove all of this when Chrome's SDK target gets bumped. |
| 50 id SFCertificatePanelSetFrameOverride(id self, |
| 51 SEL _cmd, |
| 52 NSRect frame, |
| 53 BOOL display, |
| 54 BOOL animate) { |
| 55 if (frame.size.height > kMaxPanelSetFrameHeight) |
| 56 frame.size.height = kMaxPanelSetFrameHeight; |
| 57 |
| 58 DCHECK(g_real_certificate_panel_setframe); |
| 59 return g_real_certificate_panel_setframe(self, _cmd, frame, display, animate); |
| 60 } |
| 61 |
| 62 void MaybeConstrainPanelSizeForSierraBug() { |
| 63 #if defined(MAC_OS_X_VERSION_10_11) && \ |
| 64 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11 |
| 65 // This is known not to be required when linking against the 10.11 SDK. Early |
| 66 // exit in that case but assume anything earlier is broken. |
| 67 return; |
| 68 #endif |
| 69 |
| 70 // It's also not required when running on El Capitan or earlier. |
| 71 if (base::mac::IsAtMostOS10_11() || g_real_certificate_panel_setframe) |
| 72 return; |
| 73 |
| 74 const SEL kSetFrame = @selector(setFrame:display:animate:); |
| 75 Method real_method = |
| 76 class_getInstanceMethod([SFCertificatePanel class], kSetFrame); |
| 77 const char* type_encoding = method_getTypeEncoding(real_method); |
| 78 g_real_certificate_panel_setframe = method_getImplementation(real_method); |
| 79 DCHECK(g_real_certificate_panel_setframe); |
| 80 IMP method = reinterpret_cast<IMP>(&SFCertificatePanelSetFrameOverride); |
| 81 BOOL method_added = class_addMethod([SFCertificatePanel class], kSetFrame, |
| 82 method, type_encoding); |
| 83 DCHECK(method_added); |
| 84 } |
| 85 |
| 86 } // namespace |
| 87 |
| 24 @interface SFCertificatePanel (SystemPrivate) | 88 @interface SFCertificatePanel (SystemPrivate) |
| 25 // A system-private interface that dismisses a panel whose sheet was started by | 89 // A system-private interface that dismisses a panel whose sheet was started by |
| 26 // -beginSheetForWindow: | 90 // -beginSheetForWindow: |
| 27 // modalDelegate: | 91 // modalDelegate: |
| 28 // didEndSelector: | 92 // didEndSelector: |
| 29 // contextInfo: | 93 // contextInfo: |
| 30 // certificates: | 94 // certificates: |
| 31 // showGroup: | 95 // showGroup: |
| 32 // as though the user clicked the button identified by returnCode. Verified | 96 // as though the user clicked the button identified by returnCode. Verified |
| 33 // present in 10.8. | 97 // present in 10.8. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 constrainedWindow_ = | 201 constrainedWindow_ = |
| 138 CreateAndShowWebModalDialogMac(observer_.get(), webContents, self); | 202 CreateAndShowWebModalDialogMac(observer_.get(), webContents, self); |
| 139 } | 203 } |
| 140 | 204 |
| 141 - (NSWindow*)overlayWindow { | 205 - (NSWindow*)overlayWindow { |
| 142 return overlayWindow_; | 206 return overlayWindow_; |
| 143 } | 207 } |
| 144 | 208 |
| 145 - (void)showSheetForWindow:(NSWindow*)window { | 209 - (void)showSheetForWindow:(NSWindow*)window { |
| 146 overlayWindow_.reset([window retain]); | 210 overlayWindow_.reset([window retain]); |
| 211 |
| 212 MaybeConstrainPanelSizeForSierraBug(); |
| 213 |
| 147 [panel_ beginSheetForWindow:window | 214 [panel_ beginSheetForWindow:window |
| 148 modalDelegate:self | 215 modalDelegate:self |
| 149 didEndSelector:@selector(sheetDidEnd: | 216 didEndSelector:@selector(sheetDidEnd: |
| 150 returnCode: | 217 returnCode: |
| 151 context:) | 218 context:) |
| 152 contextInfo:NULL | 219 contextInfo:NULL |
| 153 certificates:certificates_ | 220 certificates:certificates_ |
| 154 showGroup:YES]; | 221 showGroup:YES]; |
| 155 } | 222 } |
| 156 | 223 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 return panel_; | 266 return panel_; |
| 200 } | 267 } |
| 201 | 268 |
| 202 - (void)onConstrainedWindowClosed { | 269 - (void)onConstrainedWindowClosed { |
| 203 panel_.reset(); | 270 panel_.reset(); |
| 204 constrainedWindow_.reset(); | 271 constrainedWindow_.reset(); |
| 205 [self release]; | 272 [self release]; |
| 206 } | 273 } |
| 207 | 274 |
| 208 @end | 275 @end |
| OLD | NEW |