Chromium Code Reviews| 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; |
| } |