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