• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/ui/views/profiles/user_manager_view.h"
6 
7 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/lifetime/application_lifetime.h"
9 #include "chrome/browser/profiles/profile_manager.h"
10 #include "chrome/browser/profiles/profile_metrics.h"
11 #include "chrome/browser/profiles/profile_window.h"
12 #include "chrome/browser/profiles/profiles_state.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_dialogs.h"
15 #include "chrome/browser/ui/browser_finder.h"
16 #include "chrome/browser/ui/browser_window.h"
17 #include "chrome/browser/ui/user_manager.h"
18 #include "chrome/browser/ui/views/auto_keep_alive.h"
19 #include "chrome/grit/chromium_strings.h"
20 #include "content/public/browser/web_contents.h"
21 #include "ui/base/l10n/l10n_util.h"
22 #include "ui/gfx/screen.h"
23 #include "ui/views/controls/webview/webview.h"
24 #include "ui/views/layout/fill_layout.h"
25 #include "ui/views/view.h"
26 #include "ui/views/widget/widget.h"
27 #include "ui/views/window/dialog_client_view.h"
28 
29 #if defined(OS_WIN)
30 #include "chrome/browser/shell_integration.h"
31 #include "ui/base/win/shell.h"
32 #include "ui/views/win/hwnd_util.h"
33 #endif
34 
35 namespace {
36 
37 // An open User Manager window. There can only be one open at a time. This
38 // is reset to NULL when the window is closed.
39 UserManagerView* instance_ = NULL;
40 
41 } // namespace
42 
43 // UserManager -----------------------------------------------------------------
44 
Show(const base::FilePath & profile_path_to_focus,profiles::UserManagerTutorialMode tutorial_mode,profiles::UserManagerProfileSelected profile_open_action)45 void UserManager::Show(
46     const base::FilePath& profile_path_to_focus,
47     profiles::UserManagerTutorialMode tutorial_mode,
48     profiles::UserManagerProfileSelected profile_open_action) {
49   ProfileMetrics::LogProfileSwitchUser(ProfileMetrics::OPEN_USER_MANAGER);
50   if (instance_) {
51     // If we are showing the User Manager after locking a profile, change the
52     // active profile to Guest.
53     profiles::SetActiveProfileToGuestIfLocked();
54 
55     // If there's a user manager window open already, just activate it.
56     instance_->GetWidget()->Activate();
57     return;
58   }
59 
60   // Create the guest profile, if necessary, and open the user manager
61   // from the guest profile.
62   profiles::CreateGuestProfileForUserManager(
63       profile_path_to_focus,
64       tutorial_mode,
65       profile_open_action,
66       base::Bind(&UserManagerView::OnGuestProfileCreated,
67                  base::Passed(make_scoped_ptr(new UserManagerView)),
68                  profile_path_to_focus));
69 }
70 
Hide()71 void UserManager::Hide() {
72   if (instance_)
73     instance_->GetWidget()->Close();
74 }
75 
IsShowing()76 bool UserManager::IsShowing() {
77   return instance_ ? instance_->GetWidget()->IsActive() : false;
78 }
79 
80 // UserManagerView -------------------------------------------------------------
81 
UserManagerView()82 UserManagerView::UserManagerView()
83     : web_view_(NULL),
84       keep_alive_(new AutoKeepAlive(NULL)) {
85 }
86 
~UserManagerView()87 UserManagerView::~UserManagerView() {
88 }
89 
90 // static
OnGuestProfileCreated(scoped_ptr<UserManagerView> instance,const base::FilePath & profile_path_to_focus,Profile * guest_profile,const std::string & url)91 void UserManagerView::OnGuestProfileCreated(
92     scoped_ptr<UserManagerView> instance,
93     const base::FilePath& profile_path_to_focus,
94     Profile* guest_profile,
95     const std::string& url) {
96   // If we are showing the User Manager after locking a profile, change the
97   // active profile to Guest.
98   profiles::SetActiveProfileToGuestIfLocked();
99 
100   DCHECK(!instance_);
101   instance_ = instance.release();  // |instance_| takes over ownership.
102   instance_->Init(profile_path_to_focus, guest_profile, GURL(url));
103 }
104 
Init(const base::FilePath & profile_path_to_focus,Profile * guest_profile,const GURL & url)105 void UserManagerView::Init(
106     const base::FilePath& profile_path_to_focus,
107     Profile* guest_profile,
108     const GURL& url) {
109   web_view_ = new views::WebView(guest_profile);
110   web_view_->set_allow_accelerators(true);
111   AddChildView(web_view_);
112   SetLayoutManager(new views::FillLayout);
113   AddAccelerator(ui::Accelerator(ui::VKEY_W, ui::EF_CONTROL_DOWN));
114 
115   // If the user manager is being displayed from an existing profile, use
116   // its last active browser to determine where the user manager should be
117   // placed.  This is used so that we can center the dialog on the correct
118   // monitor in a multiple-monitor setup.
119   //
120   // If |profile_path_to_focus| is empty (for example, starting up chrome
121   // when all existing profiles are locked) or we can't find an active
122   // browser, bounds will remain empty and the user manager will be centered on
123   // the default monitor by default.
124   gfx::Rect bounds;
125   if (!profile_path_to_focus.empty()) {
126     ProfileManager* manager = g_browser_process->profile_manager();
127     if (manager) {
128       Profile* profile = manager->GetProfileByPath(profile_path_to_focus);
129       DCHECK(profile);
130       Browser* browser = chrome::FindLastActiveWithProfile(profile,
131           chrome::GetActiveDesktop());
132       if (browser) {
133         gfx::NativeView native_view =
134             views::Widget::GetWidgetForNativeWindow(
135                 browser->window()->GetNativeWindow())->GetNativeView();
136         bounds = gfx::Screen::GetScreenFor(native_view)->
137             GetDisplayNearestWindow(native_view).work_area();
138         bounds.ClampToCenteredSize(gfx::Size(UserManager::kWindowWidth,
139                                              UserManager::kWindowHeight));
140       }
141     }
142   }
143 
144   DialogDelegate::CreateDialogWidgetWithBounds(this, NULL, NULL, bounds);
145 
146   // Since the User Manager can be the only top level window, we don't
147   // want to accidentally quit all of Chrome if the user is just trying to
148   // unfocus the selected pod in the WebView.
149   GetDialogClientView()->RemoveAccelerator(
150       ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
151 
152 #if defined(OS_WIN)
153   // Set the app id for the task manager to the app id of its parent
154   ui::win::SetAppIdForWindow(
155       ShellIntegration::GetChromiumModelIdForProfile(
156           guest_profile->GetPath()),
157       views::HWNDForWidget(GetWidget()));
158 #endif
159   GetWidget()->Show();
160 
161   web_view_->LoadInitialURL(url);
162   web_view_->RequestFocus();
163 }
164 
AcceleratorPressed(const ui::Accelerator & accelerator)165 bool UserManagerView::AcceleratorPressed(const ui::Accelerator& accelerator) {
166   DCHECK_EQ(ui::VKEY_W, accelerator.key_code());
167   DCHECK_EQ(ui::EF_CONTROL_DOWN, accelerator.modifiers());
168   GetWidget()->Close();
169   return true;
170 }
171 
GetPreferredSize() const172 gfx::Size UserManagerView::GetPreferredSize() const {
173   return gfx::Size(UserManager::kWindowWidth, UserManager::kWindowHeight);
174 }
175 
CanResize() const176 bool UserManagerView::CanResize() const {
177   return true;
178 }
179 
CanMaximize() const180 bool UserManagerView::CanMaximize() const {
181   return true;
182 }
183 
CanMinimize() const184 bool UserManagerView::CanMinimize() const {
185   return true;
186 }
187 
GetWindowTitle() const188 base::string16 UserManagerView::GetWindowTitle() const {
189   return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
190 }
191 
GetDialogButtons() const192 int UserManagerView::GetDialogButtons() const {
193   return ui::DIALOG_BUTTON_NONE;
194 }
195 
WindowClosing()196 void UserManagerView::WindowClosing() {
197   // Now that the window is closed, we can allow a new one to be opened.
198   // (WindowClosing comes in asynchronously from the call to Close() and we
199   // may have already opened a new instance).
200   if (instance_ == this)
201     instance_ = NULL;
202 }
203 
UseNewStyleForThisDialog() const204 bool UserManagerView::UseNewStyleForThisDialog() const {
205   return false;
206 }
207