Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(403)

Side by Side Diff: chrome/browser/ui/cocoa/profiles/user_manager_mac.mm

Issue 1261433013: Implement online reauth UI for Locked Profiles on Mac (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use ConstrainedWindow. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/ui/cocoa/profiles/user_manager_mac.h ('k') | chrome/browser/ui/user_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 #include "chrome/browser/ui/cocoa/profiles/user_manager_mac.h" 5 #include "chrome/browser/ui/cocoa/profiles/user_manager_mac.h"
6 6
7 #include "base/mac/foundation_util.h" 7 #include "base/mac/foundation_util.h"
8 #include "chrome/app/chrome_command_ids.h" 8 #include "chrome/app/chrome_command_ids.h"
9 #import "chrome/browser/app_controller_mac.h" 9 #import "chrome/browser/app_controller_mac.h"
10 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/profiles/profile_avatar_icon_util.h" 11 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
12 #include "chrome/browser/profiles/profile_manager.h" 12 #include "chrome/browser/profiles/profile_manager.h"
13 #include "chrome/browser/profiles/profile_metrics.h" 13 #include "chrome/browser/profiles/profile_metrics.h"
14 #include "chrome/browser/profiles/profiles_state.h" 14 #include "chrome/browser/profiles/profiles_state.h"
15 #include "chrome/browser/signin/signin_promo.h"
15 #include "chrome/browser/ui/browser_dialogs.h" 16 #include "chrome/browser/ui/browser_dialogs.h"
16 #import "chrome/browser/ui/cocoa/browser_window_utils.h" 17 #import "chrome/browser/ui/cocoa/browser_window_utils.h"
17 #include "chrome/browser/ui/cocoa/chrome_event_processing_window.h" 18 #include "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
19 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sh eet.h"
20 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_wi ndow.h"
21 #include "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h"
18 #include "chrome/browser/ui/user_manager.h" 22 #include "chrome/browser/ui/user_manager.h"
19 #include "chrome/grit/chromium_strings.h" 23 #include "chrome/grit/chromium_strings.h"
24 #include "components/web_modal/web_contents_modal_dialog_host.h"
25 #include "components/web_modal/web_contents_modal_dialog_manager.h"
26 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
20 #include "content/public/browser/native_web_keyboard_event.h" 27 #include "content/public/browser/native_web_keyboard_event.h"
21 #include "content/public/browser/render_widget_host_view.h" 28 #include "content/public/browser/render_widget_host_view.h"
22 #include "content/public/browser/web_contents.h" 29 #include "content/public/browser/web_contents.h"
23 #include "content/public/browser/web_contents_delegate.h" 30 #include "content/public/browser/web_contents_delegate.h"
24 #include "ui/base/l10n/l10n_util_mac.h" 31 #include "ui/base/l10n/l10n_util_mac.h"
25 #include "ui/events/keycodes/keyboard_codes.h" 32 #include "ui/events/keycodes/keyboard_codes.h"
26 33
27 namespace { 34 namespace {
28 35
29 // Update the App Controller with a new Profile. Used when a Profile is locked 36 // Update the App Controller with a new Profile. Used when a Profile is locked
30 // to set the Controller to the Guest profile so the old Profile's bookmarks, 37 // to set the Controller to the Guest profile so the old Profile's bookmarks,
31 // etc... cannot be accessed. 38 // etc... cannot be accessed.
32 void ChangeAppControllerForProfile(Profile* profile, 39 void ChangeAppControllerForProfile(Profile* profile,
33 Profile::CreateStatus status) { 40 Profile::CreateStatus status) {
34 if (status == Profile::CREATE_STATUS_INITIALIZED) { 41 if (status == Profile::CREATE_STATUS_INITIALIZED) {
35 AppController* controller = 42 AppController* controller =
36 base::mac::ObjCCast<AppController>([NSApp delegate]); 43 base::mac::ObjCCast<AppController>([NSApp delegate]);
37 [controller windowChangedToProfile:profile]; 44 [controller windowChangedToProfile:profile];
38 } 45 }
39 } 46 }
40 47
41 } // namespace 48 } // namespace
42 49
43 // An open User Manager window. There can only be one open at a time. This 50 // An open User Manager window. There can only be one open at a time. This
44 // is reset to NULL when the window is closed. 51 // is reset to NULL when the window is closed.
45 UserManagerMac* instance_ = NULL; // Weak. 52 UserManagerMac* instance_ = NULL; // Weak.
46 BOOL instance_under_construction_ = NO; 53 BOOL instance_under_construction_ = NO;
47 54
55 void CloseInstanceReauthDialog() {
56 DCHECK(instance_);
57 instance_->CloseReauthDialog();
58 }
59
60 // The modal dialog host the User Manager uses to display the reauth dialog.
61 class UserManagerModalHost : public web_modal::WebContentsModalDialogHost {
62 public:
63 UserManagerModalHost(gfx::NativeView host_view)
64 : host_view_(host_view) {}
65
66 gfx::Size GetMaximumDialogSize() override {
67 return gfx::Size(
68 UserManager::kReauthDialogWidth, UserManager::kReauthDialogHeight);
69 }
70
71 ~UserManagerModalHost() override {}
72
73 gfx::NativeView GetHostView() const override {
74 return host_view_;
75 }
76
77 gfx::Point GetDialogPosition(const gfx::Size& size) override {
78 return gfx::Point(0, 0);
79 }
80
81 void AddObserver(web_modal::ModalDialogHostObserver* observer) override {}
82 void RemoveObserver(web_modal::ModalDialogHostObserver* observer) override {}
83
84 private:
85 gfx::NativeView host_view_;
86 };
87
88 // The modal manager delegate allowing the display of constrained windows for
89 // the reauth dialog.
90 class UserManagerModalManagerDelegate :
91 public web_modal::WebContentsModalDialogManagerDelegate {
92 public:
93 UserManagerModalManagerDelegate(gfx::NativeView host_view) {
94 modal_host_.reset(new UserManagerModalHost(host_view));
95 }
96
97 web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost()
98 override {
99 return modal_host_.get();
100 }
101
102 bool IsWebContentsVisible(content::WebContents* web_contents) override {
103 return true;
104 }
105
106 ~UserManagerModalManagerDelegate() override {}
107 protected:
108 scoped_ptr<UserManagerModalHost> modal_host_;
109 };
110
48 // Custom WebContentsDelegate that allows handling of hotkeys. 111 // Custom WebContentsDelegate that allows handling of hotkeys.
49 class UserManagerWebContentsDelegate : public content::WebContentsDelegate { 112 class UserManagerWebContentsDelegate : public content::WebContentsDelegate {
50 public: 113 public:
51 UserManagerWebContentsDelegate() {} 114 UserManagerWebContentsDelegate() {}
52 115
53 // WebContentsDelegate implementation. Forwards all unhandled keyboard events 116 // WebContentsDelegate implementation. Forwards all unhandled keyboard events
54 // to the current window. 117 // to the current window.
55 void HandleKeyboardEvent( 118 void HandleKeyboardEvent(
56 content::WebContents* source, 119 content::WebContents* source,
57 const content::NativeWebKeyboardEvent& event) override { 120 const content::NativeWebKeyboardEvent& event) override {
(...skipping 10 matching lines...) Expand all
68 event.windowsKeyCode == ui::VKEY_V); 131 event.windowsKeyCode == ui::VKEY_V);
69 132
70 // Only handle close window Chrome accelerators and text editing ones. 133 // Only handle close window Chrome accelerators and text editing ones.
71 if (chromeCommandId == IDC_CLOSE_WINDOW || chromeCommandId == IDC_EXIT || 134 if (chromeCommandId == IDC_CLOSE_WINDOW || chromeCommandId == IDC_EXIT ||
72 isTextEditingCommand) { 135 isTextEditingCommand) {
73 [[NSApp mainMenu] performKeyEquivalent:event.os_event]; 136 [[NSApp mainMenu] performKeyEquivalent:event.os_event];
74 } 137 }
75 } 138 }
76 }; 139 };
77 140
141 class ReauthDialogDelegate : public UserManager::ReauthDialogObserver,
142 public UserManagerWebContentsDelegate,
143 public ConstrainedWindowMacDelegate {
144 public:
145 ReauthDialogDelegate(content::WebContents* web_contents, std::string email)
146 : UserManager::ReauthDialogObserver(web_contents, email) {}
147
148 // UserManager::ReauthDialogObserver:
149 void CloseReauthDialog() override {
150 CloseInstanceReauthDialog();
151 }
152
153 // ConstrainedWindowMacDelegate:
154 void OnConstrainedWindowClosed(ConstrainedWindowMac* window) override {
155 CloseReauthDialog();
156 }
157
158 DISALLOW_COPY_AND_ASSIGN(ReauthDialogDelegate);
159 };
160
161 // WindowController for the reauth dialog.
162 @interface ReauthDialogWindowController
163 : NSWindowController <NSWindowDelegate> {
164 @private
165 std::string emailAddress_;
166 content::WebContents* webContents_;
167 scoped_ptr<ReauthDialogDelegate> webContentsDelegate_;
168 scoped_ptr<ConstrainedWindowMac> constrained_window_;
169 scoped_ptr<content::WebContents> reauthWebContents_;
170 }
171 - (id)initWithProfile:(Profile*)profile
172 email:(std::string)email
173 webContents:(content::WebContents*)webContents;
174 - (void)close;
175 @end
176
177 @implementation ReauthDialogWindowController
178
179 - (id)initWithProfile:(Profile*)profile
180 email:(std::string)email
181 webContents:(content::WebContents*)webContents {
182 webContents_ = webContents;
183 emailAddress_ = email;
184
185 NSRect frame = NSMakeRect(
186 0, 0, UserManager::kReauthDialogWidth, UserManager::kReauthDialogHeight);
187 base::scoped_nsobject<ConstrainedWindowCustomWindow> window(
188 [[ConstrainedWindowCustomWindow alloc] initWithContentRect:frame]);
189 if ((self = [super initWithWindow:window])) {
190 webContents_ = webContents;
191
192 reauthWebContents_.reset(content::WebContents::Create(
193 content::WebContents::CreateParams(profile)));
194 window.get().contentView = reauthWebContents_->GetNativeView();
195 webContentsDelegate_.reset(
196 new ReauthDialogDelegate(reauthWebContents_.get(), emailAddress_));
197 reauthWebContents_->SetDelegate(webContentsDelegate_.get());
198
199 base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
200 [[CustomConstrainedWindowSheet alloc]
201 initWithCustomWindow:[self window]]);
202 constrained_window_.reset(
203 new ConstrainedWindowMac(
204 webContentsDelegate_.get(), webContents_, sheet));
205 [window setStyleMask:NSTitledWindowMask | NSClosableWindowMask];
206
207 // The close button needs to call CloseWebContentsModalDialog() on the
208 // constrained window isntead of just [window close] so grab a reference to
209 // it in the title bar and change its action.
210 auto closeButton = [window standardWindowButton:NSWindowCloseButton];
211 [closeButton setTarget:self];
212 [closeButton setAction:@selector(closeButtonClicked:)];
213 [self show];
214 }
215
216 return self;
217 }
218
219 - (void)show {
220 GURL url = signin::GetReauthURLWithEmail(emailAddress_);
221 reauthWebContents_->GetController().LoadURL(url, content::Referrer(),
222 ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
223 std::string());
224 }
225
226 - (void)closeButtonClicked:(NSButton*)button {
227 [self close];
228 }
229
230 - (void)close {
231 constrained_window_->CloseWebContentsModalDialog();
232 }
233
234 @end
235
78 // Window controller for the User Manager view. 236 // Window controller for the User Manager view.
79 @interface UserManagerWindowController : NSWindowController <NSWindowDelegate> { 237 @interface UserManagerWindowController : NSWindowController <NSWindowDelegate> {
80 @private 238 @private
81 scoped_ptr<content::WebContents> webContents_; 239 scoped_ptr<content::WebContents> webContents_;
82 scoped_ptr<UserManagerWebContentsDelegate> webContentsDelegate_; 240 scoped_ptr<UserManagerWebContentsDelegate> webContentsDelegate_;
83 UserManagerMac* userManagerObserver_; // Weak. 241 UserManagerMac* userManagerObserver_; // Weak.
242 scoped_ptr<UserManagerModalManagerDelegate> modal_manager_delegate_;
243 base::scoped_nsobject<ReauthDialogWindowController> reauth_window_controller_;
84 } 244 }
85 - (void)windowWillClose:(NSNotification*)notification; 245 - (void)windowWillClose:(NSNotification*)notification;
86 - (void)dealloc; 246 - (void)dealloc;
87 - (id)initWithProfile:(Profile*)profile 247 - (id)initWithProfile:(Profile*)profile
88 withObserver:(UserManagerMac*)userManagerObserver; 248 withObserver:(UserManagerMac*)userManagerObserver;
89 - (void)showURL:(const GURL&)url; 249 - (void)showURL:(const GURL&)url;
90 - (void)show; 250 - (void)show;
91 - (void)close; 251 - (void)close;
92 - (BOOL)isVisible; 252 - (BOOL)isVisible;
253 - (void)showReauthDialogWithProfile:(Profile*)profile email:(std::string)email;
254 - (void)closeReauthDialog;
93 @end 255 @end
94 256
95 @implementation UserManagerWindowController 257 @implementation UserManagerWindowController
96 258
97 - (id)initWithProfile:(Profile*)profile 259 - (id)initWithProfile:(Profile*)profile
98 withObserver:(UserManagerMac*)userManagerObserver { 260 withObserver:(UserManagerMac*)userManagerObserver {
99
100 // Center the window on the screen that currently has focus. 261 // Center the window on the screen that currently has focus.
101 NSScreen* mainScreen = [NSScreen mainScreen]; 262 NSScreen* mainScreen = [NSScreen mainScreen];
102 CGFloat screenHeight = [mainScreen frame].size.height; 263 CGFloat screenHeight = [mainScreen frame].size.height;
103 CGFloat screenWidth = [mainScreen frame].size.width; 264 CGFloat screenWidth = [mainScreen frame].size.width;
104 265
105 NSRect contentRect = 266 NSRect contentRect =
106 NSMakeRect((screenWidth - UserManager::kWindowWidth) / 2, 267 NSMakeRect((screenWidth - UserManager::kWindowWidth) / 2,
107 (screenHeight - UserManager::kWindowHeight) / 2, 268 (screenHeight - UserManager::kWindowHeight) / 2,
108 UserManager::kWindowWidth, UserManager::kWindowHeight); 269 UserManager::kWindowWidth, UserManager::kWindowHeight);
109 ChromeEventProcessingWindow* window = [[ChromeEventProcessingWindow alloc] 270 ChromeEventProcessingWindow* window = [[ChromeEventProcessingWindow alloc]
(...skipping 10 matching lines...) Expand all
120 281
121 if ((self = [super initWithWindow:window])) { 282 if ((self = [super initWithWindow:window])) {
122 userManagerObserver_ = userManagerObserver; 283 userManagerObserver_ = userManagerObserver;
123 284
124 // Initialize the web view. 285 // Initialize the web view.
125 webContents_.reset(content::WebContents::Create( 286 webContents_.reset(content::WebContents::Create(
126 content::WebContents::CreateParams(profile))); 287 content::WebContents::CreateParams(profile)));
127 window.contentView = webContents_->GetNativeView(); 288 window.contentView = webContents_->GetNativeView();
128 webContentsDelegate_.reset(new UserManagerWebContentsDelegate()); 289 webContentsDelegate_.reset(new UserManagerWebContentsDelegate());
129 webContents_->SetDelegate(webContentsDelegate_.get()); 290 webContents_->SetDelegate(webContentsDelegate_.get());
130 DCHECK(window.contentView);
131 291
132 [[NSNotificationCenter defaultCenter] 292 [[NSNotificationCenter defaultCenter]
133 addObserver:self 293 addObserver:self
134 selector:@selector(windowWillClose:) 294 selector:@selector(windowWillClose:)
135 name:NSWindowWillCloseNotification 295 name:NSWindowWillCloseNotification
136 object:self.window]; 296 object:self.window];
137 } 297 }
138 return self; 298 return self;
139 } 299 }
140 300
141 - (void)dealloc { 301 - (void)dealloc {
142 [[NSNotificationCenter defaultCenter] removeObserver:self]; 302 [[NSNotificationCenter defaultCenter] removeObserver:self];
303 // Remove the ModalDailogManager that's about to be destroyed.
304 auto manager = web_modal::WebContentsModalDialogManager::FromWebContents(
305 webContents_.get());
306 if (manager)
307 manager->SetDelegate(nullptr);
308
143 [super dealloc]; 309 [super dealloc];
144 } 310 }
145 311
146 - (void)showURL:(const GURL&)url { 312 - (void)showURL:(const GURL&)url {
147 webContents_->GetController().LoadURL(url, content::Referrer(), 313 webContents_->GetController().LoadURL(url, content::Referrer(),
148 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, 314 ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
149 std::string()); 315 std::string());
150 content::RenderWidgetHostView* rwhv = webContents_->GetRenderWidgetHostView(); 316 content::RenderWidgetHostView* rwhv = webContents_->GetRenderWidgetHostView();
151 if (rwhv) 317 if (rwhv)
152 rwhv->SetBackgroundColor(profiles::kUserManagerBackgroundColor); 318 rwhv->SetBackgroundColor(profiles::kUserManagerBackgroundColor);
(...skipping 23 matching lines...) Expand all
176 -(BOOL)isVisible { 342 -(BOOL)isVisible {
177 return [[self window] isVisible]; 343 return [[self window] isVisible];
178 } 344 }
179 345
180 - (void)windowWillClose:(NSNotification*)notification { 346 - (void)windowWillClose:(NSNotification*)notification {
181 [[NSNotificationCenter defaultCenter] removeObserver:self]; 347 [[NSNotificationCenter defaultCenter] removeObserver:self];
182 DCHECK(userManagerObserver_); 348 DCHECK(userManagerObserver_);
183 userManagerObserver_->WindowWasClosed(); 349 userManagerObserver_->WindowWasClosed();
184 } 350 }
185 351
352 - (void)showReauthDialogWithProfile:(Profile*)profile email:(std::string)email {
353 // Make sure there's a WebContentsModalDialogManager for this UserManager's
354 // web contents.
355 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
356 webContents_.get());
357 modal_manager_delegate_.reset(
358 new UserManagerModalManagerDelegate([[self window] contentView]));
359 web_modal::WebContentsModalDialogManager::FromWebContents(
360 webContents_.get())->SetDelegate(modal_manager_delegate_.get());
361 reauth_window_controller_.reset(
362 [[ReauthDialogWindowController alloc]
363 initWithProfile:profile
364 email:email
365 webContents:webContents_.get()]);
366 }
367
368 - (void)closeReauthDialog {
369 [reauth_window_controller_ close];
370 }
371
186 @end 372 @end
187 373
188 374
189 // static 375 // static
190 void UserManager::Show( 376 void UserManager::Show(
191 const base::FilePath& profile_path_to_focus, 377 const base::FilePath& profile_path_to_focus,
192 profiles::UserManagerTutorialMode tutorial_mode, 378 profiles::UserManagerTutorialMode tutorial_mode,
193 profiles::UserManagerProfileSelected profile_open_action) { 379 profiles::UserManagerProfileSelected profile_open_action) {
194 DCHECK(profile_path_to_focus != ProfileManager::GetGuestProfilePath()); 380 DCHECK(profile_path_to_focus != ProfileManager::GetGuestProfilePath());
195 381
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 417
232 // static 418 // static
233 void UserManager::OnUserManagerShown() { 419 void UserManager::OnUserManagerShown() {
234 if (instance_) 420 if (instance_)
235 instance_->LogTimeToOpen(); 421 instance_->LogTimeToOpen();
236 } 422 }
237 423
238 // static 424 // static
239 void UserManager::ShowReauthDialog(content::BrowserContext* browser_context, 425 void UserManager::ShowReauthDialog(content::BrowserContext* browser_context,
240 const std::string& email) { 426 const std::string& email) {
241 // TODO(rogerta): See equivalent views implementation in user_manager_view.cc. 427 DCHECK(instance_);
428 instance_->ShowReauthDialog(browser_context, email);
429 }
430
431 void UserManagerMac::ShowReauthDialog(content::BrowserContext* browser_context,
432 const std::string& email) {
433 [window_controller_
434 showReauthDialogWithProfile:Profile::FromBrowserContext(browser_context)
435 email:email];
436 }
437
438 void UserManagerMac::CloseReauthDialog() {
439 [window_controller_ closeReauthDialog];
242 } 440 }
243 441
244 UserManagerMac::UserManagerMac(Profile* profile) { 442 UserManagerMac::UserManagerMac(Profile* profile) {
245 window_controller_.reset([[UserManagerWindowController alloc] 443 window_controller_.reset([[UserManagerWindowController alloc]
246 initWithProfile:profile withObserver:this]); 444 initWithProfile:profile withObserver:this]);
247 } 445 }
248 446
249 UserManagerMac::~UserManagerMac() { 447 UserManagerMac::~UserManagerMac() {
250 } 448 }
251 449
(...skipping 11 matching lines...) Expand all
263 void UserManagerMac::LogTimeToOpen() { 461 void UserManagerMac::LogTimeToOpen() {
264 if (user_manager_started_showing_ == base::Time()) 462 if (user_manager_started_showing_ == base::Time())
265 return; 463 return;
266 464
267 ProfileMetrics::LogTimeToOpenUserManager( 465 ProfileMetrics::LogTimeToOpenUserManager(
268 base::Time::Now() - user_manager_started_showing_); 466 base::Time::Now() - user_manager_started_showing_);
269 user_manager_started_showing_ = base::Time(); 467 user_manager_started_showing_ = base::Time();
270 } 468 }
271 469
272 void UserManagerMac::WindowWasClosed() { 470 void UserManagerMac::WindowWasClosed() {
471 CloseReauthDialog();
273 instance_ = NULL; 472 instance_ = NULL;
274 delete this; 473 delete this;
275 } 474 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/profiles/user_manager_mac.h ('k') | chrome/browser/ui/user_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698