user_manager_view.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
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/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"
26
27#if defined(OS_WIN)
28#include "chrome/browser/shell_integration.h"
29#include "ui/base/win/shell.h"
30#include "ui/views/win/hwnd_util.h"
31#endif
32
33namespace {
34
35// Default window size.
36const int kWindowWidth = 900;
37const int kWindowHeight = 700;
38
39}
40
41namespace chrome {
42
43// Declared in browser_dialogs.h so others don't have to depend on this header.
44void ShowUserManager(const base::FilePath& profile_path_to_focus) {
45  UserManagerView::Show(
46      profile_path_to_focus, profiles::USER_MANAGER_NO_TUTORIAL);
47}
48
49void ShowUserManagerWithTutorial(profiles::UserManagerTutorialMode tutorial) {
50  UserManagerView::Show(base::FilePath(), tutorial);
51}
52
53void HideUserManager() {
54  UserManagerView::Hide();
55}
56
57}  // namespace chrome
58
59// static
60UserManagerView* UserManagerView::instance_ = NULL;
61
62UserManagerView::UserManagerView()
63    : web_view_(NULL),
64      keep_alive_(new AutoKeepAlive(NULL)) {
65}
66
67UserManagerView::~UserManagerView() {
68}
69
70// static
71void UserManagerView::Show(const base::FilePath& profile_path_to_focus,
72                           profiles::UserManagerTutorialMode tutorial_mode) {
73  ProfileMetrics::LogProfileSwitchUser(ProfileMetrics::OPEN_USER_MANAGER);
74  if (instance_) {
75    // If there's a user manager window open already, just activate it.
76    instance_->GetWidget()->Activate();
77    return;
78  }
79
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,
84      tutorial_mode,
85      base::Bind(&UserManagerView::OnGuestProfileCreated,
86                 base::Passed(make_scoped_ptr(new UserManagerView)),
87                 profile_path_to_focus));
88}
89
90// static
91void UserManagerView::Hide() {
92  if (instance_)
93    instance_->GetWidget()->Close();
94}
95
96// static
97bool UserManagerView::IsShowing() {
98  return instance_ ? instance_->GetWidget()->IsActive() : false;
99}
100
101// static
102void 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));
109}
110
111void UserManagerView::Init(
112    const base::FilePath& profile_path_to_focus,
113    Profile* guest_profile,
114    const GURL& url) {
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));
120
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.
125  //
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.
130  gfx::Rect bounds;
131  if (!profile_path_to_focus.empty()) {
132    ProfileManager* manager = g_browser_process->profile_manager();
133    if (manager) {
134      Profile* profile = manager->GetProfileByPath(profile_path_to_focus);
135      DCHECK(profile);
136      Browser* browser = chrome::FindLastActiveWithProfile(profile,
137          chrome::GetActiveDesktop());
138      if (browser) {
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));
145      }
146    }
147  }
148
149  DialogDelegate::CreateDialogWidgetWithBounds(this, NULL, NULL, bounds);
150
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));
156
157#if defined(OS_WIN)
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()));
163#endif
164  GetWidget()->Show();
165
166  web_view_->LoadInitialURL(url);
167  web_view_->RequestFocus();
168}
169
170bool 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();
174  return true;
175}
176
177gfx::Size UserManagerView::GetPreferredSize() const {
178  return gfx::Size(kWindowWidth, kWindowHeight);
179}
180
181bool UserManagerView::CanResize() const {
182  return true;
183}
184
185bool UserManagerView::CanMaximize() const {
186  return true;
187}
188
189base::string16 UserManagerView::GetWindowTitle() const {
190  return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
191}
192
193int UserManagerView::GetDialogButtons() const {
194  return ui::DIALOG_BUTTON_NONE;
195}
196
197void 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)
202    instance_ = NULL;
203}
204
205bool UserManagerView::UseNewStyleForThisDialog() const {
206  return false;
207}
208