diff options
author | noms@chromium.org <noms@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-04 18:07:50 +0000 |
---|---|---|
committer | noms@chromium.org <noms@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-04 18:07:50 +0000 |
commit | ff41e625781f4511a45df7c307e2c79f358836ac (patch) | |
tree | ddc5ff99b4332198dfd8aaef0d555854a5850678 | |
parent | 2e2bfd1c0d0aa4a815433db49ba205b56a609402 (diff) | |
download | chromium_src-ff41e625781f4511a45df7c307e2c79f358836ac.zip chromium_src-ff41e625781f4511a45df7c307e2c79f358836ac.tar.gz chromium_src-ff41e625781f4511a45df7c307e2c79f358836ac.tar.bz2 |
Fix up the sign-out flow for the --new-profile-management flag.
Changes that are happening in this CL:
- trying to open a profile that is signed out will take you to
the User Manager screen, with the pod for that profile focused
- once you sign out from a profile, this also will take you to the
User Manager screen
- actions from the User Manager screen that open a browser (i.e.
switching to a profile, guest mode) will close the User Manager
once the browser is opened
- the User Manager html page takes a hash parameter that is used
to explicitely focus a given pod
- the profiles::SwitchToProfile api has changes slightly, to
take a callback as a parameter
- a static function moved out from the avatar menu and into profiles::,
to join its brethren
BUG=304893,313471
Review URL: https://codereview.chromium.org/44583002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@232731 0039d316-1c4b-4281-b951-d872f2087c98
19 files changed, 304 insertions, 91 deletions
diff --git a/chrome/browser/chromeos/profiles/profile_list_chromeos.cc b/chrome/browser/chromeos/profiles/profile_list_chromeos.cc index b27e01c..c218277 100644 --- a/chrome/browser/chromeos/profiles/profile_list_chromeos.cc +++ b/chrome/browser/chromeos/profiles/profile_list_chromeos.cc @@ -60,6 +60,7 @@ void ProfileListChromeOS::RebuildMenu() { AvatarMenu::Item* item = new AvatarMenu::Item(i, i, icon); item->name = (*it)->GetDisplayName(); item->sync_state = profile_info_->GetUserNameOfProfileAtIndex(i); + item->profile_path = profile_info_->GetPathOfProfileAtIndex(i); item->managed = false; item->signed_in = true; item->active = profile_info_->GetPathOfProfileAtIndex(i) == diff --git a/chrome/browser/profiles/avatar_menu.cc b/chrome/browser/profiles/avatar_menu.cc index a32bf72..5bd91cd 100644 --- a/chrome/browser/profiles/avatar_menu.cc +++ b/chrome/browser/profiles/avatar_menu.cc @@ -20,6 +20,7 @@ #include "chrome/browser/profiles/profiles_state.h" #include "chrome/browser/ui/ash/chrome_shell_delegate.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/host_desktop.h" #include "chrome/browser/ui/startup/startup_browser_creator.h" #include "chrome/common/chrome_switches.h" @@ -39,22 +40,6 @@ using content::BrowserThread; namespace { -void OnProfileCreated(bool always_create, - chrome::HostDesktopType desktop_type, - Profile* profile, - Profile::CreateStatus status) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - if (status == Profile::CREATE_STATUS_INITIALIZED) { - profiles::FindOrCreateNewWindowForProfile( - profile, - chrome::startup::IS_NOT_PROCESS_STARTUP, - chrome::startup::IS_NOT_FIRST_RUN, - desktop_type, - always_create); - } -} - // Constants for the show profile switcher experiment const char kShowProfileSwitcherFieldTrialName[] = "ShowProfileSwitcher"; const char kAlwaysShowSwitcherGroupName[] = "AlwaysShow"; @@ -129,23 +114,19 @@ bool AvatarMenu::CompareItems(const Item* item1, const Item* item2) { base::i18n::ToLower(item2->name)) < 0; } -// static -void AvatarMenu::SwitchToGuestProfileWindow( - chrome::HostDesktopType desktop_type) { - ProfileManager* profile_manager = g_browser_process->profile_manager(); - profile_manager->CreateProfileAsync(ProfileManager::GetGuestProfilePath(), - base::Bind(&OnProfileCreated, - false, - desktop_type), - string16(), - string16(), - std::string()); -} - void AvatarMenu::SwitchToProfile(size_t index, bool always_create) { DCHECK(profiles::IsMultipleProfilesEnabled() || index == GetActiveProfileIndex()); const Item& item = GetItemAt(index); + + if (profiles::IsNewProfileManagementEnabled()) { + // Don't open a browser window for signed-out profiles. + if (item.signin_required) { + chrome::ShowUserManager(item.profile_path); + return; + } + } + base::FilePath path = profile_info_->GetPathOfProfileAtIndex(item.profile_index); @@ -153,7 +134,8 @@ void AvatarMenu::SwitchToProfile(size_t index, bool always_create) { if (browser_) desktop_type = browser_->host_desktop_type(); - profiles::SwitchToProfile(path, desktop_type, always_create); + profiles::SwitchToProfile(path, desktop_type, always_create, + profiles::ProfileSwitchingDoneCallback()); ProfileMetrics::LogProfileSwitchUser(ProfileMetrics::SWITCH_PROFILE_ICON); } diff --git a/chrome/browser/profiles/avatar_menu.h b/chrome/browser/profiles/avatar_menu.h index 80f24fd..13f9476 100644 --- a/chrome/browser/profiles/avatar_menu.h +++ b/chrome/browser/profiles/avatar_menu.h @@ -67,6 +67,9 @@ class AvatarMenu : public content::NotificationObserver { // The index in the |profile_cache| for this profile. size_t profile_index; + + // The path of this profile. + base::FilePath profile_path; }; // Constructor. |observer| can be NULL. |browser| can be NULL and a new one @@ -88,9 +91,6 @@ class AvatarMenu : public content::NotificationObserver { // Compare items by name. static bool CompareItems(const Item* item1, const Item* item2); - // Creates a new guest user window. - static void SwitchToGuestProfileWindow(chrome::HostDesktopType desktop_type); - // Opens a Browser with the specified profile in response to the user // selecting an item. If |always_create| is true then a new window is created // even if a window for that profile already exists. diff --git a/chrome/browser/profiles/avatar_menu_actions_desktop.cc b/chrome/browser/profiles/avatar_menu_actions_desktop.cc index 2ee503f..4335d15 100644 --- a/chrome/browser/profiles/avatar_menu_actions_desktop.cc +++ b/chrome/browser/profiles/avatar_menu_actions_desktop.cc @@ -9,7 +9,11 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_info_cache.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/profiles/profile_window.h" +#include "chrome/browser/profiles/profiles_state.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/common/chrome_switches.h" @@ -22,8 +26,10 @@ namespace { class SignoutTracker : public content::WebContentsObserver { public: - SignoutTracker(Profile* profile, const GURL& signout_landing_url, - content::WebContents* contents); + SignoutTracker(Profile* profile, + const GURL& signout_landing_url, + content::WebContents* contents, + Browser* browser); virtual void WebContentsDestroyed(content::WebContents* contents) OVERRIDE; virtual void DidStopLoading(content::RenderViewHost* render_view_host) @@ -33,22 +39,29 @@ class SignoutTracker : public content::WebContentsObserver { scoped_ptr<content::WebContents> contents_; GURL signout_landing_url_; Profile* profile_; + Browser* browser_; DISALLOW_COPY_AND_ASSIGN(SignoutTracker); }; SignoutTracker::SignoutTracker(Profile* profile, const GURL& signout_landing_url, - content::WebContents* contents) + content::WebContents* contents, + Browser* browser) : WebContentsObserver(contents), contents_(contents), signout_landing_url_(signout_landing_url), - profile_(profile) { + profile_(profile), + browser_(browser) { } void SignoutTracker::DidStopLoading(content::RenderViewHost* render_view_host) { // Only close when we reach the final landing; ignore redirects until then. if (web_contents()->GetURL() == signout_landing_url_) { + if (profiles::IsNewProfileManagementEnabled()) { + DCHECK(profile_); + chrome::ShowUserManager(profile_->GetPath()); + } Observe(NULL); BrowserList::CloseAllBrowsersWithProfile(profile_); delete this; /* success */ @@ -130,7 +143,10 @@ content::WebContents* AvatarMenuActionsDesktop::BeginSignOut() { content::WebContents* contents = content::WebContents::Create(create_params); // This object may be destructed when the menu closes but we need something // around to finish the sign-out process and close the profile windows. - new SignoutTracker(current_profile, GURL(landing_url), contents); + new SignoutTracker(current_profile, + GURL(landing_url), + contents, + browser_); contents->GetController().LoadURL( logout_url, content::Referrer(), content::PAGE_TRANSITION_GENERATED, std::string()); diff --git a/chrome/browser/profiles/profile_list_desktop.cc b/chrome/browser/profiles/profile_list_desktop.cc index e94d375..2892aba 100644 --- a/chrome/browser/profiles/profile_list_desktop.cc +++ b/chrome/browser/profiles/profile_list_desktop.cc @@ -53,6 +53,7 @@ void ProfileListDesktop::RebuildMenu() { AvatarMenu::Item* item = new AvatarMenu::Item(i, i, icon); item->name = profile_info_->GetNameOfProfileAtIndex(i); item->sync_state = profile_info_->GetUserNameOfProfileAtIndex(i); + item->profile_path = profile_info_->GetPathOfProfileAtIndex(i); item->managed = profile_info_->ProfileIsManagedAtIndex(i); item->signed_in = !item->sync_state.empty(); if (!item->signed_in) { diff --git a/chrome/browser/profiles/profile_manager_browsertest.cc b/chrome/browser/profiles/profile_manager_browsertest.cc index 00a88d3..9fd635a 100644 --- a/chrome/browser/profiles/profile_manager_browsertest.cc +++ b/chrome/browser/profiles/profile_manager_browsertest.cc @@ -23,6 +23,8 @@ namespace { +const profiles::ProfileSwitchingDoneCallback kOnProfileSwitchDoNothing; + // An observer that returns back to test code after a new profile is // initialized. void OnUnblockOnProfileCreation(Profile* profile, @@ -229,19 +231,22 @@ IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, EXPECT_EQ(1U, browser_list->size()); // Open a browser window for the first profile. - profiles::SwitchToProfile(path_profile1, desktop_type, false); + profiles::SwitchToProfile(path_profile1, desktop_type, false, + kOnProfileSwitchDoNothing); EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U); EXPECT_EQ(1U, browser_list->size()); EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath()); // Open a browser window for the second profile. - profiles::SwitchToProfile(path_profile2, desktop_type, false); + profiles::SwitchToProfile(path_profile2, desktop_type, false, + kOnProfileSwitchDoNothing); EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U); EXPECT_EQ(2U, browser_list->size()); EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath()); // Switch to the first profile without opening a new window. - profiles::SwitchToProfile(path_profile1, desktop_type, false); + profiles::SwitchToProfile(path_profile1, desktop_type, false, + kOnProfileSwitchDoNothing); EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U); EXPECT_EQ(2U, browser_list->size()); @@ -284,13 +289,15 @@ IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, EphemeralProfile) { EXPECT_EQ(1U, browser_list->size()); // Open a browser window for the second profile. - profiles::SwitchToProfile(path_profile2, desktop_type, false); + profiles::SwitchToProfile(path_profile2, desktop_type, false, + kOnProfileSwitchDoNothing); EXPECT_EQ(2U, chrome::GetTotalBrowserCount()); EXPECT_EQ(2U, browser_list->size()); EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath()); // Create a second window for the ephemeral profile. - profiles::SwitchToProfile(path_profile2, desktop_type, true); + profiles::SwitchToProfile(path_profile2, desktop_type, true, + kOnProfileSwitchDoNothing); EXPECT_EQ(3U, chrome::GetTotalBrowserCount()); EXPECT_EQ(3U, browser_list->size()); diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc index 8d4c47f..d65dd17 100644 --- a/chrome/browser/profiles/profile_window.cc +++ b/chrome/browser/profiles/profile_window.cc @@ -16,6 +16,7 @@ #if !defined(OS_IOS) #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_list_observer.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/startup/startup_browser_creator.h" #endif // !defined (OS_IOS) @@ -25,23 +26,66 @@ using content::UserMetricsAction; namespace { -void OpenBrowserWindowForProfile(bool always_create, - bool is_new_profile, - chrome::HostDesktopType desktop_type, - Profile* profile, - Profile::CreateStatus status) { +// Handles running a callback when a new Browser has been completely created. +class BrowserAddedObserver : public chrome::BrowserListObserver { + public: + explicit BrowserAddedObserver( + profiles::ProfileSwitchingDoneCallback callback) : callback_(callback) { + BrowserList::AddObserver(this); + } + virtual ~BrowserAddedObserver() { + BrowserList::RemoveObserver(this); + } + + private: + // Overridden from BrowserListObserver: + virtual void OnBrowserAdded(Browser* browser) OVERRIDE { + DCHECK(!callback_.is_null()); + callback_.Run(); + } + + profiles::ProfileSwitchingDoneCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(BrowserAddedObserver); +}; + +void OpenBrowserWindowForProfile( + profiles::ProfileSwitchingDoneCallback callback, + bool always_create, + bool is_new_profile, + chrome::HostDesktopType desktop_type, + Profile* profile, + Profile::CreateStatus status) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); if (status != Profile::CREATE_STATUS_INITIALIZED) return; + chrome::startup::IsProcessStartup is_process_startup = + chrome::startup::IS_NOT_PROCESS_STARTUP; + chrome::startup::IsFirstRun is_first_run = chrome::startup::IS_NOT_FIRST_RUN; + // If this is a brand new profile, then start a first run window. + if (is_new_profile) { + is_process_startup = chrome::startup::IS_PROCESS_STARTUP; + is_first_run = chrome::startup::IS_FIRST_RUN; + } + + // If we are not showing any browsers windows (we could be showing the + // desktop User Manager, for example), then this is a process startup browser. + if (BrowserList::GetInstance(desktop_type)->size() == 0) + is_process_startup = chrome::startup::IS_PROCESS_STARTUP; + + // If there is a callback, create an observer to make sure it is only + // run when the browser has been completely created. + scoped_ptr<BrowserAddedObserver> browser_added_observer; + if (!callback.is_null()) + browser_added_observer.reset(new BrowserAddedObserver(callback)); + profiles::FindOrCreateNewWindowForProfile( profile, - is_new_profile ? chrome::startup::IS_PROCESS_STARTUP : - chrome::startup::IS_NOT_PROCESS_STARTUP, - is_new_profile ? chrome::startup::IS_FIRST_RUN : - chrome::startup::IS_NOT_FIRST_RUN, + is_process_startup, + is_first_run, desktop_type, always_create); } @@ -81,10 +125,12 @@ void FindOrCreateNewWindowForProfile( void SwitchToProfile( const base::FilePath& path, chrome::HostDesktopType desktop_type, - bool always_create) { + bool always_create, + ProfileSwitchingDoneCallback callback) { g_browser_process->profile_manager()->CreateProfileAsync( path, base::Bind(&OpenBrowserWindowForProfile, + callback, always_create, false, desktop_type), @@ -93,11 +139,27 @@ void SwitchToProfile( std::string()); } -void CreateAndSwitchToNewProfile(chrome::HostDesktopType desktop_type) { +void SwitchToGuestProfile(chrome::HostDesktopType desktop_type, + ProfileSwitchingDoneCallback callback) { + g_browser_process->profile_manager()->CreateProfileAsync( + ProfileManager::GetGuestProfilePath(), + base::Bind(&OpenBrowserWindowForProfile, + callback, + false, + false, + desktop_type), + string16(), + string16(), + std::string()); +} + +void CreateAndSwitchToNewProfile(chrome::HostDesktopType desktop_type, + ProfileSwitchingDoneCallback callback) { ProfileManager::CreateMultiProfileAsync( string16(), string16(), base::Bind(&OpenBrowserWindowForProfile, + callback, true, true, desktop_type), diff --git a/chrome/browser/profiles/profile_window.h b/chrome/browser/profiles/profile_window.h index 77fc4e2..f674144 100644 --- a/chrome/browser/profiles/profile_window.h +++ b/chrome/browser/profiles/profile_window.h @@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_PROFILES_PROFILE_WINDOW_H_ #define CHROME_BROWSER_PROFILES_PROFILE_WINDOW_H_ +#include "base/callback_forward.h" #include "chrome/browser/ui/host_desktop.h" #include "chrome/browser/ui/startup/startup_types.h" @@ -13,6 +14,9 @@ namespace base { class FilePath; } namespace profiles { +// Callback to be used when switching to a new profile is completed. +typedef base::Callback<void()> ProfileSwitchingDoneCallback; + // Activates a window for |profile| on the desktop specified by // |desktop_type|. If no such window yet exists, or if |always_create| is // true, this first creates a new window, then activates @@ -28,15 +32,24 @@ void FindOrCreateNewWindowForProfile( // Opens a Browser with the specified profile given by |path|. // If |always_create| is true then a new window is created -// even if a window for that profile already exists. +// even if a window for that profile already exists. When the browser is +// opened, |callback| will be run if it isn't null. + void SwitchToProfile( const base::FilePath& path, chrome::HostDesktopType desktop_type, - bool always_create); + bool always_create, + ProfileSwitchingDoneCallback callback); + +// Opens a Browser for the guest profile and runs |callback| if it isn't null. +void SwitchToGuestProfile(chrome::HostDesktopType desktop_type, + ProfileSwitchingDoneCallback callback); // Creates a new profile from the next available profile directory, and -// opens a new browser window for the profile once it is ready. -void CreateAndSwitchToNewProfile(chrome::HostDesktopType desktop_type); +// opens a new browser window for the profile once it is ready. When the browser +// is opened, |callback| will be run if it isn't null. +void CreateAndSwitchToNewProfile(chrome::HostDesktopType desktop_type, + ProfileSwitchingDoneCallback callback); // Closes all browser windows that belong to the guest profile. void CloseGuestProfileWindows(); diff --git a/chrome/browser/resources/chromeos/login/screen_account_picker.js b/chrome/browser/resources/chromeos/login/screen_account_picker.js index ab2d4ec..8405ee5 100644 --- a/chrome/browser/resources/chromeos/login/screen_account_picker.js +++ b/chrome/browser/resources/chromeos/login/screen_account_picker.js @@ -146,6 +146,15 @@ login.createScreen('AccountPickerScreen', 'account-picker', function() { loadUsers: function(users, animated, showGuest) { $('pod-row').loadPods(users, animated); $('login-header-bar').showGuestButton = showGuest; + + // The desktop User Manager can send the index of a pod that should be + // initially focused. + var hash = window.location.hash; + if (hash) { + var podIndex = hash.substr(1); + if (podIndex) + $('pod-row').focusPodByIndex(podIndex, false); + } }, /** diff --git a/chrome/browser/resources/chromeos/login/user_pod_row.js b/chrome/browser/resources/chromeos/login/user_pod_row.js index f5d24c8..c0d0d1d 100644 --- a/chrome/browser/resources/chromeos/login/user_pod_row.js +++ b/chrome/browser/resources/chromeos/login/user_pod_row.js @@ -1292,6 +1292,17 @@ cr.define('login', function() { }, /** + * Focuses a given user pod by index or clear focus when given null. + * @param {int=} podToFocus index of User pod to focus. + * @param {boolean=} opt_force If true, forces focus update even when + * podToFocus is already focused. + */ + focusPodByIndex: function(podToFocus, opt_force) { + if (podToFocus < this.pods.length) + this.focusPod(this.pods[podToFocus], opt_force); + }, + + /** * Resets wallpaper to the last active user's wallpaper, if any. */ loadLastWallpaper: function() { diff --git a/chrome/browser/ui/browser_dialogs.h b/chrome/browser/ui/browser_dialogs.h index 72af390..a1f96a6 100644 --- a/chrome/browser/ui/browser_dialogs.h +++ b/chrome/browser/ui/browser_dialogs.h @@ -96,6 +96,13 @@ void ShowProfileSigninConfirmationDialog( const std::string& username, ui::ProfileSigninConfirmationDelegate* delegate); + +// Shows the Desktop User Manager with the |profile_path_to_focus| user focused. +void ShowUserManager(const base::FilePath& profile_path_to_focus); + +// Hides the User Manager. +void HideUserManager(); + } // namespace chrome #endif // CHROME_BROWSER_UI_BROWSER_DIALOGS_H_ diff --git a/chrome/browser/ui/cocoa/user_manager_mac.mm b/chrome/browser/ui/cocoa/user_manager_mac.mm new file mode 100644 index 0000000..07818f3 --- /dev/null +++ b/chrome/browser/ui/cocoa/user_manager_mac.mm @@ -0,0 +1,21 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import <Cocoa/Cocoa.h> + +#include "chrome/browser/ui/browser_dialogs.h" + +namespace chrome { + +// Declared in browser_dialogs.h so others don't have to depend on this header. +// TODO(noms): Add implementation when the User Manager dialog is implemented. +void ShowUserManager(const base::FilePath& profile_path_to_focus) { + NOTIMPLEMENTED(); +} + +void HideUserManager() { + NOTIMPLEMENTED(); +} + +} // namespace chrome diff --git a/chrome/browser/ui/gtk/user_manager_gtk.cc b/chrome/browser/ui/gtk/user_manager_gtk.cc new file mode 100644 index 0000000..d8f09ac --- /dev/null +++ b/chrome/browser/ui/gtk/user_manager_gtk.cc @@ -0,0 +1,21 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <gtk/gtk.h> + +#include "chrome/browser/ui/browser_dialogs.h" + +namespace chrome { + +// Declared in browser_dialogs.h so others don't have to depend on this header. +// TODO(noms): Add implementation when the User Manager dialog is implemented. +void ShowUserManager(const base::FilePath& profile_path_to_focus) { + NOTIMPLEMENTED(); +} + +void HideUserManager() { + NOTIMPLEMENTED(); +} + +} // namespace chrome diff --git a/chrome/browser/ui/views/new_avatar_menu_button_browsertest.cc b/chrome/browser/ui/views/new_avatar_menu_button_browsertest.cc index c4b21df..1f1b4e8 100644 --- a/chrome/browser/ui/views/new_avatar_menu_button_browsertest.cc +++ b/chrome/browser/ui/views/new_avatar_menu_button_browsertest.cc @@ -8,11 +8,13 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profiles_state.h" +#include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/views/avatar_menu_button.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/new_avatar_button.h" #include "chrome/browser/ui/views/profile_chooser_view.h" +#include "chrome/browser/ui/views/user_manager_view.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" @@ -120,4 +122,11 @@ IN_PROC_BROWSER_TEST_F(NewAvatarMenuButtonTest, SignOut) { window_close_observer.Wait(); // Rely on test timeout for failure indication. EXPECT_TRUE(browser_list->empty()); + + // If the User Manager hasn't shown yet, wait for it to show up. + if (!UserManagerView::IsShowing()) + base::MessageLoop::current()->RunUntilIdle(); + + // We need to hide the User Manager or else the process can't die. + chrome::HideUserManager(); } diff --git a/chrome/browser/ui/views/profile_chooser_view.cc b/chrome/browser/ui/views/profile_chooser_view.cc index fd0ea67..b7c827d 100644 --- a/chrome/browser/ui/views/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profile_chooser_view.cc @@ -14,6 +14,7 @@ #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_promo.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/singleton_tabs.h" #include "chrome/browser/ui/views/user_manager_view.h" #include "chrome/common/chrome_switches.h" @@ -365,13 +366,22 @@ void ProfileChooserView::ButtonPressed(views::Button* sender, sender->SetEnabled(false); if (sender == guest_button_) { - avatar_menu_->SwitchToGuestProfileWindow(browser_->host_desktop_type()); + profiles::SwitchToGuestProfile(browser_->host_desktop_type(), + profiles::ProfileSwitchingDoneCallback()); } else if (sender == end_guest_button_) { profiles::CloseGuestProfileWindows(); } else if (sender == users_button_) { - UserManagerView::Show(browser_); + // Only non-guest users appear in the User Manager. + base::FilePath profile_path; + if (!end_guest_button_) { + size_t active_index = avatar_menu_->GetActiveProfileIndex(); + profile_path = avatar_menu_->GetItemAt(active_index).profile_path; + } + chrome::ShowUserManager(profile_path); } else if (sender == add_user_button_) { - profiles::CreateAndSwitchToNewProfile(browser_->host_desktop_type()); + profiles::CreateAndSwitchToNewProfile( + browser_->host_desktop_type(), + profiles::ProfileSwitchingDoneCallback()); } else if (sender == add_account_button_) { ShowView(GAIA_ADD_ACCOUNT_VIEW, avatar_menu_.get()); } else { diff --git a/chrome/browser/ui/views/user_manager_view.cc b/chrome/browser/ui/views/user_manager_view.cc index cf2b892..45fac70 100644 --- a/chrome/browser/ui/views/user_manager_view.cc +++ b/chrome/browser/ui/views/user_manager_view.cc @@ -4,10 +4,12 @@ #include "chrome/browser/ui/views/user_manager_view.h" +#include "base/strings/string_number_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/common/url_constants.h" #include "content/public/browser/web_contents.h" @@ -38,6 +40,19 @@ const int kWindowHeight = 700; } +namespace chrome { + +// Declared in browser_dialogs.h so others don't have to depend on this header. +void ShowUserManager(const base::FilePath& profile_path_to_focus) { + UserManagerView::Show(profile_path_to_focus); +} + +void HideUserManager() { + UserManagerView::Hide(); +} + +} // namespace chrome + // static UserManagerView* UserManagerView::instance_ = NULL; @@ -45,8 +60,6 @@ UserManagerView::UserManagerView(Profile* profile) : web_view_(new views::WebView(profile)) { SetLayoutManager(new views::FillLayout); AddChildView(web_view_); - // Prevent the browser process from shutting down while this window is open. - chrome::StartKeepAlive(); } UserManagerView::~UserManagerView() { @@ -54,8 +67,9 @@ UserManagerView::~UserManagerView() { } // static -void UserManagerView::Show(Browser* browser) { - DCHECK(browser); +void UserManagerView::Show(const base::FilePath& profile_path_to_focus) { + // Prevent the browser process from shutting down while this window is open. + chrome::StartKeepAlive(); if (instance_) { // If there's a user manager window open already, just activate it. @@ -69,40 +83,56 @@ void UserManagerView::Show(Browser* browser) { profile_manager->CreateProfileAsync( ProfileManager::GetGuestProfilePath(), base::Bind(&UserManagerView::OnGuestProfileCreated, - browser), + profile_path_to_focus), string16(), string16(), std::string()); } +// static +void UserManagerView::Hide() { + if (instance_) + instance_->GetWidget()->Close(); +} + +// static +bool UserManagerView::IsShowing() { + return instance_ ? instance_->GetWidget()->IsActive() : false; +} + void UserManagerView::OnGuestProfileCreated( - Browser* browser, + const base::FilePath& profile_path_to_focus, Profile* guest_profile, Profile::CreateStatus status) { if (status != Profile::CREATE_STATUS_INITIALIZED) return; instance_ = new UserManagerView(guest_profile); - gfx::NativeWindow context = browser->window()->GetNativeWindow(); -#if defined(USE_ASH) - if (!context) - context = ash::wm::GetActiveWindow(); -#endif - DialogDelegate::CreateDialogWidget(instance_, context, NULL); + DialogDelegate::CreateDialogWidget(instance_, NULL, NULL); #if defined(OS_WIN) - // Set the app id for the task manager to the app id of its parent browser. If - // no parent is specified, the app id will default to that of the initial - // process. - if (browser) { - ui::win::SetAppIdForWindow( - ShellIntegration::GetChromiumModelIdForProfile( - browser->profile()->GetPath()), - views::HWNDForWidget(instance_->GetWidget())); - } + // Set the app id for the task manager to the app id of its parent + ui::win::SetAppIdForWindow( + ShellIntegration::GetChromiumModelIdForProfile( + guest_profile->GetPath()), + views::HWNDForWidget(instance_->GetWidget())); #endif instance_->GetWidget()->Show(); - instance_->web_view_->LoadInitialURL(GURL(chrome::kChromeUIUserManagerURL)); + + // Tell the webui which user pod should be focused. + std::string page = chrome::kChromeUIUserManagerURL; + + if (!profile_path_to_focus.empty()) { + ProfileInfoCache& cache = + g_browser_process->profile_manager()->GetProfileInfoCache(); + size_t index = cache.GetIndexOfProfileWithPath(profile_path_to_focus); + if (index != std::string::npos) { + page += "#"; + page += base::IntToString(index); + } + } + + instance_->web_view_->LoadInitialURL(GURL(page)); instance_->web_view_->RequestFocus(); } diff --git a/chrome/browser/ui/views/user_manager_view.h b/chrome/browser/ui/views/user_manager_view.h index a7bf712..2629b72 100644 --- a/chrome/browser/ui/views/user_manager_view.h +++ b/chrome/browser/ui/views/user_manager_view.h @@ -8,8 +8,6 @@ #include "chrome/browser/profiles/profile.h" #include "ui/views/window/dialog_delegate.h" -class Browser; - namespace views { class WebView; } @@ -18,13 +16,22 @@ class WebView; class UserManagerView : public views::DialogDelegateView { public: // Shows the User Manager or re-activates an existing one. - static void Show(Browser* browser); + static void Show(const base::FilePath& profile_path_to_focus); + + // Hide the User Manager. + static void Hide(); + + // Returns whether or not the User Manager is showing. + static bool IsShowing(); private: explicit UserManagerView(Profile* profile); virtual ~UserManagerView(); - static void OnGuestProfileCreated(Browser* browser, + // If the |guest_profile| has been initialized succesfully (according to + // |status|), creates a new UserManagerView instance with the user with path + // |profile_path_to_focus| focused. + static void OnGuestProfileCreated(const base::FilePath& profile_path_to_focus, Profile* guest_profile, Profile::CreateStatus status); diff --git a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc index 5fa8b1b..d969164 100644 --- a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc +++ b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc @@ -16,6 +16,7 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_window.h" #include "chrome/browser/profiles/profiles_state.h" +#include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/singleton_tabs.h" #include "content/public/browser/web_contents.h" @@ -55,7 +56,7 @@ const char kJsApiUserManagerLaunchGuest[] = "launchGuest"; const char kJsApiUserManagerLaunchUser[] = "launchUser"; const char kJsApiUserManagerRemoveUser[] = "removeUser"; -const size_t kAvatarIconSize = 160; +const size_t kAvatarIconSize = 180; void HandleAndDoNothing(const base::ListValue* args) { } @@ -165,7 +166,8 @@ void UserManagerScreenHandler::HandleInitialize(const base::ListValue* args) { } void UserManagerScreenHandler::HandleAddUser(const base::ListValue* args) { - profiles::CreateAndSwitchToNewProfile(desktop_type_); + profiles::CreateAndSwitchToNewProfile(desktop_type_, + base::Bind(&chrome::HideUserManager)); } void UserManagerScreenHandler::HandleRemoveUser(const base::ListValue* args) { @@ -192,7 +194,8 @@ void UserManagerScreenHandler::HandleRemoveUser(const base::ListValue* args) { } void UserManagerScreenHandler::HandleLaunchGuest(const base::ListValue* args) { - AvatarMenu::SwitchToGuestProfileWindow(desktop_type_); + profiles::SwitchToGuestProfile(desktop_type_, + base::Bind(&chrome::HideUserManager)); } void UserManagerScreenHandler::HandleLaunchUser(const base::ListValue* args) { @@ -212,7 +215,8 @@ void UserManagerScreenHandler::HandleLaunchUser(const base::ListValue* args) { if (info_cache.GetUserNameOfProfileAtIndex(i) == emailAddress && info_cache.GetNameOfProfileAtIndex(i) == displayName) { base::FilePath path = info_cache.GetPathOfProfileAtIndex(i); - profiles::SwitchToProfile(path, desktop_type_, true); + profiles::SwitchToProfile(path, chrome::GetActiveDesktop(), true, + base::Bind(&chrome::HideUserManager)); break; } } diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 22a0983..607e01e 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -1003,6 +1003,7 @@ 'browser/ui/cocoa/ui_localizer.mm', 'browser/ui/cocoa/url_drop_target.h', 'browser/ui/cocoa/url_drop_target.mm', + 'browser/ui/cocoa/user_manager_mac.mm', 'browser/ui/cocoa/validation_message_bubble_cocoa.mm', 'browser/ui/cocoa/validation_message_bubble_controller.h', 'browser/ui/cocoa/vertical_gradient_view.h', @@ -1338,6 +1339,7 @@ 'browser/ui/gtk/unity_service.h', 'browser/ui/gtk/update_recommended_dialog.cc', 'browser/ui/gtk/update_recommended_dialog.h', + 'browser/ui/gtk/user_manager_gtk.cc', 'browser/ui/gtk/validation_message_bubble_gtk.cc', 'browser/ui/gtk/view_id_util.cc', 'browser/ui/gtk/view_id_util.h', |