1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file. 458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/ui/views/profiles/user_manager_view.h" 658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/browser_process.h" 858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h" 958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile_metrics.h" 1123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome/browser/profiles/profile_window.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/profiles/profiles_state.h" 1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/ui/browser.h" 140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/browser/ui/browser_dialogs.h" 1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/ui/user_manager.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/ui/views/auto_keep_alive.h" 196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/chromium_strings.h" 2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/public/browser/web_contents.h" 2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "ui/gfx/screen.h" 2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/views/controls/webview/webview.h" 2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/views/layout/fill_layout.h" 2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/views/view.h" 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/views/widget/widget.h" 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/window/dialog_client_view.h" 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_WIN) 3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/shell_integration.h" 3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/base/win/shell.h" 3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/views/win/hwnd_util.h" 3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace { 3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// An open User Manager window. There can only be one open at a time. This 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// is reset to NULL when the window is closed. 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciUserManagerView* instance_ = NULL; 4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace 420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// UserManager ----------------------------------------------------------------- 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid UserManager::Show( 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::FilePath& profile_path_to_focus, 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profiles::UserManagerTutorialMode tutorial_mode, 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profiles::UserManagerProfileSelected profile_open_action) { 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProfileMetrics::LogProfileSwitchUser(ProfileMetrics::OPEN_USER_MANAGER); 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (instance_) { 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If we are showing the User Manager after locking a profile, change the 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // active profile to Guest. 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profiles::SetActiveProfileToGuestIfLocked(); 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // If there's a user manager window open already, just activate it. 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) instance_->GetWidget()->Activate(); 5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Create the guest profile, if necessary, and open the user manager 6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // from the guest profile. 6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) profiles::CreateGuestProfileForUserManager( 6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) profile_path_to_focus, 6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) tutorial_mode, 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profile_open_action, 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&UserManagerView::OnGuestProfileCreated, 6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Passed(make_scoped_ptr(new UserManagerView)), 6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) profile_path_to_focus)); 6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid UserManager::Hide() { 720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (instance_) 730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) instance_->GetWidget()->Close(); 740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool UserManager::IsShowing() { 770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return instance_ ? instance_->GetWidget()->IsActive() : false; 780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// UserManagerView ------------------------------------------------------------- 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciUserManagerView::UserManagerView() 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : web_view_(NULL), 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci keep_alive_(new AutoKeepAlive(NULL)) { 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciUserManagerView::~UserManagerView() { 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// static 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void UserManagerView::OnGuestProfileCreated( 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<UserManagerView> instance, 9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const base::FilePath& profile_path_to_focus, 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Profile* guest_profile, 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string& url) { 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If we are showing the User Manager after locking a profile, change the 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // active profile to Guest. 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profiles::SetActiveProfileToGuestIfLocked(); 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!instance_); 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) instance_ = instance.release(); // |instance_| takes over ownership. 10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) instance_->Init(profile_path_to_focus, guest_profile, GURL(url)); 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void UserManagerView::Init( 10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const base::FilePath& profile_path_to_focus, 10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) Profile* guest_profile, 10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const GURL& url) { 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) web_view_ = new views::WebView(guest_profile); 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch web_view_->set_allow_accelerators(true); 111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) AddChildView(web_view_); 112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SetLayoutManager(new views::FillLayout); 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AddAccelerator(ui::Accelerator(ui::VKEY_W, ui::EF_CONTROL_DOWN)); 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // If the user manager is being displayed from an existing profile, use 11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // its last active browser to determine where the user manager should be 11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // placed. This is used so that we can center the dialog on the correct 11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // monitor in a multiple-monitor setup. 11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // 12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // If |profile_path_to_focus| is empty (for example, starting up chrome 12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // when all existing profiles are locked) or we can't find an active 12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // browser, bounds will remain empty and the user manager will be centered on 12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // the default monitor by default. 12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gfx::Rect bounds; 12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!profile_path_to_focus.empty()) { 12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ProfileManager* manager = g_browser_process->profile_manager(); 12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (manager) { 12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) Profile* profile = manager->GetProfileByPath(profile_path_to_focus); 12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(profile); 13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) Browser* browser = chrome::FindLastActiveWithProfile(profile, 13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) chrome::GetActiveDesktop()); 13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (browser) { 13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gfx::NativeView native_view = 13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) views::Widget::GetWidgetForNativeWindow( 13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) browser->window()->GetNativeWindow())->GetNativeView(); 13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bounds = gfx::Screen::GetScreenFor(native_view)-> 13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) GetDisplayNearestWindow(native_view).work_area(); 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bounds.ClampToCenteredSize(gfx::Size(UserManager::kWindowWidth, 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UserManager::kWindowHeight)); 14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DialogDelegate::CreateDialogWidgetWithBounds(this, NULL, NULL, bounds); 14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Since the User Manager can be the only top level window, we don't 147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // want to accidentally quit all of Chrome if the user is just trying to 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // unfocus the selected pod in the WebView. 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetDialogClientView()->RemoveAccelerator( 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_WIN) 1530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Set the app id for the task manager to the app id of its parent 1540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ui::win::SetAppIdForWindow( 1550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ShellIntegration::GetChromiumModelIdForProfile( 1560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) guest_profile->GetPath()), 157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) views::HWNDForWidget(GetWidget())); 15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetWidget()->Show(); 1600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) web_view_->LoadInitialURL(url); 162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) web_view_->RequestFocus(); 16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool UserManagerView::AcceleratorPressed(const ui::Accelerator& accelerator) { 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_EQ(ui::VKEY_W, accelerator.key_code()); 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_EQ(ui::EF_CONTROL_DOWN, accelerator.modifiers()); 168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetWidget()->Close(); 169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size UserManagerView::GetPreferredSize() const { 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return gfx::Size(UserManager::kWindowWidth, UserManager::kWindowHeight); 17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool UserManagerView::CanResize() const { 17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool UserManagerView::CanMaximize() const { 18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool UserManagerView::CanMinimize() const { 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 UserManagerView::GetWindowTitle() const { 1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); 19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)int UserManagerView::GetDialogButtons() const { 19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return ui::DIALOG_BUTTON_NONE; 19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void UserManagerView::WindowClosing() { 19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Now that the window is closed, we can allow a new one to be opened. 19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // (WindowClosing comes in asynchronously from the call to Close() and we 19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // may have already opened a new instance). 20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (instance_ == this) 20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) instance_ = NULL; 20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool UserManagerView::UseNewStyleForThisDialog() const { 20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 207