Home | History | Annotate | Download | only in profiles
      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 
     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 
     71 void UserManager::Hide() {
     72   if (instance_)
     73     instance_->GetWidget()->Close();
     74 }
     75 
     76 bool UserManager::IsShowing() {
     77   return instance_ ? instance_->GetWidget()->IsActive() : false;
     78 }
     79 
     80 // UserManagerView -------------------------------------------------------------
     81 
     82 UserManagerView::UserManagerView()
     83     : web_view_(NULL),
     84       keep_alive_(new AutoKeepAlive(NULL)) {
     85 }
     86 
     87 UserManagerView::~UserManagerView() {
     88 }
     89 
     90 // static
     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 
    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 
    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 
    172 gfx::Size UserManagerView::GetPreferredSize() const {
    173   return gfx::Size(UserManager::kWindowWidth, UserManager::kWindowHeight);
    174 }
    175 
    176 bool UserManagerView::CanResize() const {
    177   return true;
    178 }
    179 
    180 bool UserManagerView::CanMaximize() const {
    181   return true;
    182 }
    183 
    184 bool UserManagerView::CanMinimize() const {
    185   return true;
    186 }
    187 
    188 base::string16 UserManagerView::GetWindowTitle() const {
    189   return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
    190 }
    191 
    192 int UserManagerView::GetDialogButtons() const {
    193   return ui::DIALOG_BUTTON_NONE;
    194 }
    195 
    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 
    204 bool UserManagerView::UseNewStyleForThisDialog() const {
    205   return false;
    206 }
    207