summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornoms@chromium.org <noms@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-04 18:07:50 +0000
committernoms@chromium.org <noms@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-04 18:07:50 +0000
commitff41e625781f4511a45df7c307e2c79f358836ac (patch)
treeddc5ff99b4332198dfd8aaef0d555854a5850678
parent2e2bfd1c0d0aa4a815433db49ba205b56a609402 (diff)
downloadchromium_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
-rw-r--r--chrome/browser/chromeos/profiles/profile_list_chromeos.cc1
-rw-r--r--chrome/browser/profiles/avatar_menu.cc42
-rw-r--r--chrome/browser/profiles/avatar_menu.h6
-rw-r--r--chrome/browser/profiles/avatar_menu_actions_desktop.cc26
-rw-r--r--chrome/browser/profiles/profile_list_desktop.cc1
-rw-r--r--chrome/browser/profiles/profile_manager_browsertest.cc17
-rw-r--r--chrome/browser/profiles/profile_window.cc84
-rw-r--r--chrome/browser/profiles/profile_window.h21
-rw-r--r--chrome/browser/resources/chromeos/login/screen_account_picker.js9
-rw-r--r--chrome/browser/resources/chromeos/login/user_pod_row.js11
-rw-r--r--chrome/browser/ui/browser_dialogs.h7
-rw-r--r--chrome/browser/ui/cocoa/user_manager_mac.mm21
-rw-r--r--chrome/browser/ui/gtk/user_manager_gtk.cc21
-rw-r--r--chrome/browser/ui/views/new_avatar_menu_button_browsertest.cc9
-rw-r--r--chrome/browser/ui/views/profile_chooser_view.cc16
-rw-r--r--chrome/browser/ui/views/user_manager_view.cc74
-rw-r--r--chrome/browser/ui/views/user_manager_view.h15
-rw-r--r--chrome/browser/ui/webui/signin/user_manager_screen_handler.cc12
-rw-r--r--chrome/chrome_browser_ui.gypi2
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',