Index: chrome/browser/ui/cocoa/profiles/user_manager_mac.mm |
diff --git a/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm b/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm |
index 5c8b1ae7c3db6f0d4fb83d4fff9db488fd38ed7f..229de120062c7393dbd69a9080c0b7aa5cbf6566 100644 |
--- a/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm |
+++ b/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm |
@@ -12,11 +12,18 @@ |
#include "chrome/browser/profiles/profile_manager.h" |
#include "chrome/browser/profiles/profile_metrics.h" |
#include "chrome/browser/profiles/profiles_state.h" |
+#include "chrome/browser/signin/signin_promo.h" |
#include "chrome/browser/ui/browser_dialogs.h" |
#import "chrome/browser/ui/cocoa/browser_window_utils.h" |
#include "chrome/browser/ui/cocoa/chrome_event_processing_window.h" |
+#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h" |
+#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_window.h" |
+#include "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" |
#include "chrome/browser/ui/user_manager.h" |
#include "chrome/grit/chromium_strings.h" |
+#include "components/web_modal/web_contents_modal_dialog_host.h" |
+#include "components/web_modal/web_contents_modal_dialog_manager.h" |
+#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" |
#include "content/public/browser/native_web_keyboard_event.h" |
#include "content/public/browser/render_widget_host_view.h" |
#include "content/public/browser/web_contents.h" |
@@ -45,6 +52,62 @@ void ChangeAppControllerForProfile(Profile* profile, |
UserManagerMac* instance_ = NULL; // Weak. |
BOOL instance_under_construction_ = NO; |
+void CloseInstanceReauthDialog() { |
+ DCHECK(instance_); |
+ instance_->CloseReauthDialog(); |
+} |
+ |
+// The modal dialog host the User Manager uses to display the reauth dialog. |
+class UserManagerModalHost : public web_modal::WebContentsModalDialogHost { |
+ public: |
+ UserManagerModalHost(gfx::NativeView host_view) |
+ : host_view_(host_view) {} |
+ |
+ gfx::Size GetMaximumDialogSize() override { |
+ return gfx::Size( |
+ UserManager::kReauthDialogWidth, UserManager::kReauthDialogHeight); |
+ } |
+ |
+ ~UserManagerModalHost() override {} |
+ |
+ gfx::NativeView GetHostView() const override { |
+ return host_view_; |
+ } |
+ |
+ gfx::Point GetDialogPosition(const gfx::Size& size) override { |
+ return gfx::Point(0, 0); |
+ } |
+ |
+ void AddObserver(web_modal::ModalDialogHostObserver* observer) override {} |
+ void RemoveObserver(web_modal::ModalDialogHostObserver* observer) override {} |
+ |
+ private: |
+ gfx::NativeView host_view_; |
+}; |
+ |
+// The modal manager delegate allowing the display of constrained windows for |
+// the reauth dialog. |
+class UserManagerModalManagerDelegate : |
+ public web_modal::WebContentsModalDialogManagerDelegate { |
+ public: |
+ UserManagerModalManagerDelegate(gfx::NativeView host_view) { |
+ modal_host_.reset(new UserManagerModalHost(host_view)); |
+ } |
+ |
+ web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost() |
+ override { |
+ return modal_host_.get(); |
+ } |
+ |
+ bool IsWebContentsVisible(content::WebContents* web_contents) override { |
+ return true; |
+ } |
+ |
+ ~UserManagerModalManagerDelegate() override {} |
+ protected: |
+ scoped_ptr<UserManagerModalHost> modal_host_; |
+}; |
+ |
// Custom WebContentsDelegate that allows handling of hotkeys. |
class UserManagerWebContentsDelegate : public content::WebContentsDelegate { |
public: |
@@ -75,12 +138,109 @@ class UserManagerWebContentsDelegate : public content::WebContentsDelegate { |
} |
}; |
+class ReauthDialogDelegate : public UserManager::ReauthDialogObserver, |
+ public UserManagerWebContentsDelegate, |
+ public ConstrainedWindowMacDelegate { |
+ public: |
+ ReauthDialogDelegate(content::WebContents* web_contents, std::string email) |
+ : UserManager::ReauthDialogObserver(web_contents, email) {} |
+ |
+ // UserManager::ReauthDialogObserver: |
+ void CloseReauthDialog() override { |
+ CloseInstanceReauthDialog(); |
+ } |
+ |
+ // ConstrainedWindowMacDelegate: |
+ void OnConstrainedWindowClosed(ConstrainedWindowMac* window) override { |
+ CloseReauthDialog(); |
+ } |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ReauthDialogDelegate); |
+}; |
+ |
+// WindowController for the reauth dialog. |
+@interface ReauthDialogWindowController |
+ : NSWindowController <NSWindowDelegate> { |
+ @private |
+ std::string emailAddress_; |
+ content::WebContents* webContents_; |
+ scoped_ptr<ReauthDialogDelegate> webContentsDelegate_; |
+ scoped_ptr<ConstrainedWindowMac> constrained_window_; |
+ scoped_ptr<content::WebContents> reauthWebContents_; |
+} |
+- (id)initWithProfile:(Profile*)profile |
+ email:(std::string)email |
+ webContents:(content::WebContents*)webContents; |
+- (void)close; |
+@end |
+ |
+@implementation ReauthDialogWindowController |
+ |
+- (id)initWithProfile:(Profile*)profile |
+ email:(std::string)email |
+ webContents:(content::WebContents*)webContents { |
+ webContents_ = webContents; |
+ emailAddress_ = email; |
+ |
+ NSRect frame = NSMakeRect( |
+ 0, 0, UserManager::kReauthDialogWidth, UserManager::kReauthDialogHeight); |
+ base::scoped_nsobject<ConstrainedWindowCustomWindow> window( |
+ [[ConstrainedWindowCustomWindow alloc] initWithContentRect:frame]); |
+ if ((self = [super initWithWindow:window])) { |
+ webContents_ = webContents; |
+ |
+ reauthWebContents_.reset(content::WebContents::Create( |
+ content::WebContents::CreateParams(profile))); |
+ window.get().contentView = reauthWebContents_->GetNativeView(); |
+ webContentsDelegate_.reset( |
+ new ReauthDialogDelegate(reauthWebContents_.get(), emailAddress_)); |
+ reauthWebContents_->SetDelegate(webContentsDelegate_.get()); |
+ |
+ base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( |
+ [[CustomConstrainedWindowSheet alloc] |
+ initWithCustomWindow:[self window]]); |
+ constrained_window_.reset( |
+ new ConstrainedWindowMac( |
+ webContentsDelegate_.get(), webContents_, sheet)); |
+ [window setStyleMask:NSTitledWindowMask | NSClosableWindowMask]; |
+ |
+ // The close button needs to call CloseWebContentsModalDialog() on the |
+ // constrained window isntead of just [window close] so grab a reference to |
+ // it in the title bar and change its action. |
+ auto closeButton = [window standardWindowButton:NSWindowCloseButton]; |
+ [closeButton setTarget:self]; |
+ [closeButton setAction:@selector(closeButtonClicked:)]; |
+ [self show]; |
+ } |
+ |
+ return self; |
+} |
+ |
+- (void)show { |
+ GURL url = signin::GetReauthURLWithEmail(emailAddress_); |
+ reauthWebContents_->GetController().LoadURL(url, content::Referrer(), |
+ ui::PAGE_TRANSITION_AUTO_TOPLEVEL, |
+ std::string()); |
+} |
+ |
+- (void)closeButtonClicked:(NSButton*)button { |
+ [self close]; |
+} |
+ |
+- (void)close { |
+ constrained_window_->CloseWebContentsModalDialog(); |
+} |
+ |
+@end |
+ |
// Window controller for the User Manager view. |
@interface UserManagerWindowController : NSWindowController <NSWindowDelegate> { |
@private |
scoped_ptr<content::WebContents> webContents_; |
scoped_ptr<UserManagerWebContentsDelegate> webContentsDelegate_; |
UserManagerMac* userManagerObserver_; // Weak. |
+ scoped_ptr<UserManagerModalManagerDelegate> modal_manager_delegate_; |
+ base::scoped_nsobject<ReauthDialogWindowController> reauth_window_controller_; |
} |
- (void)windowWillClose:(NSNotification*)notification; |
- (void)dealloc; |
@@ -90,13 +250,14 @@ class UserManagerWebContentsDelegate : public content::WebContentsDelegate { |
- (void)show; |
- (void)close; |
- (BOOL)isVisible; |
+- (void)showReauthDialogWithProfile:(Profile*)profile email:(std::string)email; |
+- (void)closeReauthDialog; |
@end |
@implementation UserManagerWindowController |
- (id)initWithProfile:(Profile*)profile |
withObserver:(UserManagerMac*)userManagerObserver { |
- |
// Center the window on the screen that currently has focus. |
NSScreen* mainScreen = [NSScreen mainScreen]; |
CGFloat screenHeight = [mainScreen frame].size.height; |
@@ -127,7 +288,6 @@ class UserManagerWebContentsDelegate : public content::WebContentsDelegate { |
window.contentView = webContents_->GetNativeView(); |
webContentsDelegate_.reset(new UserManagerWebContentsDelegate()); |
webContents_->SetDelegate(webContentsDelegate_.get()); |
- DCHECK(window.contentView); |
[[NSNotificationCenter defaultCenter] |
addObserver:self |
@@ -140,6 +300,12 @@ class UserManagerWebContentsDelegate : public content::WebContentsDelegate { |
- (void)dealloc { |
[[NSNotificationCenter defaultCenter] removeObserver:self]; |
+ // Remove the ModalDailogManager that's about to be destroyed. |
+ auto manager = web_modal::WebContentsModalDialogManager::FromWebContents( |
+ webContents_.get()); |
+ if (manager) |
+ manager->SetDelegate(nullptr); |
+ |
[super dealloc]; |
} |
@@ -183,6 +349,26 @@ class UserManagerWebContentsDelegate : public content::WebContentsDelegate { |
userManagerObserver_->WindowWasClosed(); |
} |
+- (void)showReauthDialogWithProfile:(Profile*)profile email:(std::string)email { |
+ // Make sure there's a WebContentsModalDialogManager for this UserManager's |
+ // web contents. |
+ web_modal::WebContentsModalDialogManager::CreateForWebContents( |
groby-ooo-7-16
2015/08/11 21:24:50
I think I've explained things badly :(
AIUI, you
anthonyvd
2015/08/11 21:37:28
This Manager is attached to the UserManager's webC
|
+ webContents_.get()); |
+ modal_manager_delegate_.reset( |
+ new UserManagerModalManagerDelegate([[self window] contentView])); |
+ web_modal::WebContentsModalDialogManager::FromWebContents( |
+ webContents_.get())->SetDelegate(modal_manager_delegate_.get()); |
+ reauth_window_controller_.reset( |
+ [[ReauthDialogWindowController alloc] |
+ initWithProfile:profile |
+ email:email |
+ webContents:webContents_.get()]); |
+} |
+ |
+- (void)closeReauthDialog { |
+ [reauth_window_controller_ close]; |
+} |
+ |
@end |
@@ -238,7 +424,19 @@ void UserManager::OnUserManagerShown() { |
// static |
void UserManager::ShowReauthDialog(content::BrowserContext* browser_context, |
const std::string& email) { |
- // TODO(rogerta): See equivalent views implementation in user_manager_view.cc. |
+ DCHECK(instance_); |
+ instance_->ShowReauthDialog(browser_context, email); |
+} |
+ |
+void UserManagerMac::ShowReauthDialog(content::BrowserContext* browser_context, |
+ const std::string& email) { |
+ [window_controller_ |
+ showReauthDialogWithProfile:Profile::FromBrowserContext(browser_context) |
+ email:email]; |
+} |
+ |
+void UserManagerMac::CloseReauthDialog() { |
+ [window_controller_ closeReauthDialog]; |
} |
UserManagerMac::UserManagerMac(Profile* profile) { |
@@ -270,6 +468,7 @@ void UserManagerMac::LogTimeToOpen() { |
} |
void UserManagerMac::WindowWasClosed() { |
+ CloseReauthDialog(); |
instance_ = NULL; |
delete this; |
} |