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.
5 #include "chrome/browser/ui/views/profiles/user_manager_view.h"
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/ui/browser.h"
13 #include "chrome/browser/ui/browser_dialogs.h"
14 #include "chrome/browser/ui/browser_finder.h"
15 #include "chrome/browser/ui/browser_window.h"
16 #include "chrome/browser/ui/views/auto_keep_alive.h"
17 #include "chrome/grit/chromium_strings.h"
18 #include "content/public/browser/web_contents.h"
19 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/gfx/screen.h"
21 #include "ui/views/controls/webview/webview.h"
22 #include "ui/views/layout/fill_layout.h"
23 #include "ui/views/view.h"
24 #include "ui/views/widget/widget.h"
25 #include "ui/views/window/dialog_client_view.h"
28 #include "chrome/browser/shell_integration.h"
29 #include "ui/base/win/shell.h"
30 #include "ui/views/win/hwnd_util.h"
35 // Default window size.
36 const int kWindowWidth = 900;
37 const int kWindowHeight = 700;
43 // Declared in browser_dialogs.h so others don't have to depend on this header.
44 void ShowUserManager(const base::FilePath& profile_path_to_focus) {
45 UserManagerView::Show(
46 profile_path_to_focus, profiles::USER_MANAGER_NO_TUTORIAL);
49 void ShowUserManagerWithTutorial(profiles::UserManagerTutorialMode tutorial) {
50 UserManagerView::Show(base::FilePath(), tutorial);
53 void HideUserManager() {
54 UserManagerView::Hide();
60 UserManagerView* UserManagerView::instance_ = NULL;
62 UserManagerView::UserManagerView()
64 keep_alive_(new AutoKeepAlive(NULL)) {
67 UserManagerView::~UserManagerView() {
71 void UserManagerView::Show(const base::FilePath& profile_path_to_focus,
72 profiles::UserManagerTutorialMode tutorial_mode) {
73 ProfileMetrics::LogProfileSwitchUser(ProfileMetrics::OPEN_USER_MANAGER);
75 // If there's a user manager window open already, just activate it.
76 instance_->GetWidget()->Activate();
80 // Create the guest profile, if necessary, and open the user manager
81 // from the guest profile.
82 profiles::CreateGuestProfileForUserManager(
83 profile_path_to_focus,
85 base::Bind(&UserManagerView::OnGuestProfileCreated,
86 base::Passed(make_scoped_ptr(new UserManagerView)),
87 profile_path_to_focus));
91 void UserManagerView::Hide() {
93 instance_->GetWidget()->Close();
97 bool UserManagerView::IsShowing() {
98 return instance_ ? instance_->GetWidget()->IsActive() : false;
102 void UserManagerView::OnGuestProfileCreated(
103 scoped_ptr<UserManagerView> instance,
104 const base::FilePath& profile_path_to_focus,
105 Profile* guest_profile,
106 const std::string& url) {
107 instance_ = instance.release(); // |instance_| takes over ownership.
108 instance_->Init(profile_path_to_focus, guest_profile, GURL(url));
111 void UserManagerView::Init(
112 const base::FilePath& profile_path_to_focus,
113 Profile* guest_profile,
115 web_view_ = new views::WebView(guest_profile);
116 web_view_->set_allow_accelerators(true);
117 AddChildView(web_view_);
118 SetLayoutManager(new views::FillLayout);
119 AddAccelerator(ui::Accelerator(ui::VKEY_W, ui::EF_CONTROL_DOWN));
121 // If the user manager is being displayed from an existing profile, use
122 // its last active browser to determine where the user manager should be
123 // placed. This is used so that we can center the dialog on the correct
124 // monitor in a multiple-monitor setup.
126 // If |profile_path_to_focus| is empty (for example, starting up chrome
127 // when all existing profiles are locked) or we can't find an active
128 // browser, bounds will remain empty and the user manager will be centered on
129 // the default monitor by default.
131 if (!profile_path_to_focus.empty()) {
132 ProfileManager* manager = g_browser_process->profile_manager();
134 Profile* profile = manager->GetProfileByPath(profile_path_to_focus);
136 Browser* browser = chrome::FindLastActiveWithProfile(profile,
137 chrome::GetActiveDesktop());
139 gfx::NativeView native_view =
140 views::Widget::GetWidgetForNativeWindow(
141 browser->window()->GetNativeWindow())->GetNativeView();
142 bounds = gfx::Screen::GetScreenFor(native_view)->
143 GetDisplayNearestWindow(native_view).work_area();
144 bounds.ClampToCenteredSize(gfx::Size(kWindowWidth, kWindowHeight));
149 DialogDelegate::CreateDialogWidgetWithBounds(this, NULL, NULL, bounds);
151 // Since the User Manager can be the only top level window, we don't
152 // want to accidentally quit all of Chrome if the user is just trying to
153 // unfocus the selected pod in the WebView.
154 GetDialogClientView()->RemoveAccelerator(
155 ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
158 // Set the app id for the task manager to the app id of its parent
159 ui::win::SetAppIdForWindow(
160 ShellIntegration::GetChromiumModelIdForProfile(
161 guest_profile->GetPath()),
162 views::HWNDForWidget(GetWidget()));
166 web_view_->LoadInitialURL(url);
167 web_view_->RequestFocus();
170 bool UserManagerView::AcceleratorPressed(const ui::Accelerator& accelerator) {
171 DCHECK_EQ(ui::VKEY_W, accelerator.key_code());
172 DCHECK_EQ(ui::EF_CONTROL_DOWN, accelerator.modifiers());
173 GetWidget()->Close();
177 gfx::Size UserManagerView::GetPreferredSize() const {
178 return gfx::Size(kWindowWidth, kWindowHeight);
181 bool UserManagerView::CanResize() const {
185 bool UserManagerView::CanMaximize() const {
189 base::string16 UserManagerView::GetWindowTitle() const {
190 return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
193 int UserManagerView::GetDialogButtons() const {
194 return ui::DIALOG_BUTTON_NONE;
197 void UserManagerView::WindowClosing() {
198 // Now that the window is closed, we can allow a new one to be opened.
199 // (WindowClosing comes in asynchronously from the call to Close() and we
200 // may have already opened a new instance).
201 if (instance_ == this)
205 bool UserManagerView::UseNewStyleForThisDialog() const {