Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(666)

Unified Diff: chrome/browser/chromeos/login/user_manager_impl.cc

Issue 14139003: Chrome OS multi-profiles backend and UI. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: move IsMultiProfilesEnabled() out of cros Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/login/user_manager_impl.cc
diff --git a/chrome/browser/chromeos/login/user_manager_impl.cc b/chrome/browser/chromeos/login/user_manager_impl.cc
index afa66d86249f97bf394b0483a761d5f2c71481de..1bbacee466dc9e13b6f05ce476bf67e886edf147 100644
--- a/chrome/browser/chromeos/login/user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/user_manager_impl.cc
@@ -190,7 +190,7 @@ UserManagerImpl::UserManagerImpl()
: cros_settings_(CrosSettings::Get()),
device_local_account_policy_service_(NULL),
users_loaded_(false),
- logged_in_user_(NULL),
+ active_user_(NULL),
session_started_(false),
is_current_user_owner_(false),
is_current_user_new_(false),
@@ -212,11 +212,13 @@ UserManagerImpl::~UserManagerImpl() {
// Can't use STLDeleteElements because of the private destructor of User.
for (UserList::iterator it = users_.begin(); it != users_.end();
it = users_.erase(it)) {
- if (logged_in_user_ == *it)
- logged_in_user_ = NULL;
+ if (active_user_ == *it)
+ active_user_ = NULL;
delete *it;
}
- delete logged_in_user_;
+ // These are pointers to the same User instances that were in users_ list.
+ logged_in_users_.clear();
+ delete active_user_;
}
void UserManagerImpl::Shutdown() {
@@ -239,6 +241,10 @@ const UserList& UserManagerImpl::GetUsers() const {
return users_;
}
+const UserList& UserManagerImpl::GetLoggedInUsers() const {
+ return logged_in_users_;
+}
+
void UserManagerImpl::UserLoggedIn(const std::string& email,
const std::string& username_hash,
bool browser_restart) {
@@ -247,6 +253,9 @@ void UserManagerImpl::UserLoggedIn(const std::string& email,
if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles))
DCHECK(!IsUserLoggedIn());
+ if (active_user_)
+ active_user_->set_is_active(false);
+
if (email == kGuestUserEMail) {
GuestUserLoggedIn();
} else if (email == kRetailModeUserEMail) {
@@ -256,7 +265,7 @@ void UserManagerImpl::UserLoggedIn(const std::string& email,
} else {
EnsureUsersLoaded();
- User* user = const_cast<User*>(FindUserInList(email));
+ User* user = FindUserInListAndModify(email);
if (user && user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
PublicAccountUserLoggedIn(user);
} else if ((user &&
@@ -280,16 +289,60 @@ void UserManagerImpl::UserLoggedIn(const std::string& email,
session_length_limiter_.reset(new SessionLengthLimiter(NULL,
browser_restart));
}
- DCHECK(logged_in_user_);
- logged_in_user_->set_username_hash(username_hash);
+ DCHECK(active_user_);
+ active_user_->set_is_logged_in(true);
+ active_user_->set_is_active(true);
+ active_user_->set_username_hash(username_hash);
+
+ // Place user who just signed in to the top of the logged in users.
+ logged_in_users_.insert(logged_in_users_.begin(), active_user_);
NotifyOnLogin();
}
+void UserManagerImpl::SwitchActiveUser(const std::string& email) {
+ if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles))
+ return;
+
+ User* user = FindUserAndModify(email);
+ if (!user) {
+ NOTREACHED() << "Switching to a non-existing user";
+ return;
+ }
+ if (user == active_user_) {
+ NOTREACHED() << "Switching to a user who is already active";
+ return;
+ }
+ if (!user->is_logged_in()) {
+ NOTREACHED() << "Switching to a user that is not logged in";
+ return;
+ }
+ if (user->GetType() != User::USER_TYPE_REGULAR) {
+ NOTREACHED() << "Switching to a non-regular user";
+ return;
+ }
+ if (user->username_hash().empty()) {
+ NOTREACHED() << "Switching to a user that doesn't have username_hash set";
+ return;
+ }
+
+ DCHECK(active_user_);
+ active_user_->set_is_active(false);
+ user->set_is_active(true);
+ active_user_ = user;
+
+ // TODO(nkostylev): Notify session_manager on active user change.
+ // http://crbug.com/230857
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_ACTIVE_USER_CHANGED,
+ content::Source<UserManager>(this),
+ content::Details<const User>(active_user_));
+}
+
void UserManagerImpl::RetailModeUserLoggedIn() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
is_current_user_new_ = true;
- logged_in_user_ = User::CreateRetailModeUser();
+ active_user_ = User::CreateRetailModeUser();
user_image_manager_->UserLoggedIn(kRetailModeUserEMail,
is_current_user_new_,
true);
@@ -299,10 +352,11 @@ void UserManagerImpl::RetailModeUserLoggedIn() {
void UserManagerImpl::GuestUserLoggedIn() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
WallpaperManager::Get()->SetInitialUserWallpaper(kGuestUserEMail, false);
- logged_in_user_ = User::CreateGuestUser();
+ active_user_ = User::CreateGuestUser();
// TODO(nkostylev): Add support for passing guest session cryptohome
// mount point. Legacy (--login-profile) value will be used for now.
- logged_in_user_->SetStubImage(User::kInvalidImageIndex, false);
+ // http://crosbug.com/230859
+ active_user_->SetStubImage(User::kInvalidImageIndex, false);
}
void UserManagerImpl::KioskAppLoggedIn(const std::string& username) {
@@ -310,13 +364,13 @@ void UserManagerImpl::KioskAppLoggedIn(const std::string& username) {
DCHECK_EQ(gaia::ExtractDomainName(username), kKioskAppUserDomain);
WallpaperManager::Get()->SetInitialUserWallpaper(username, false);
- logged_in_user_ = User::CreateKioskAppUser(username);
- logged_in_user_->SetStubImage(User::kInvalidImageIndex, false);
+ active_user_ = User::CreateKioskAppUser(username);
+ active_user_->SetStubImage(User::kInvalidImageIndex, false);
CommandLine* command_line = CommandLine::ForCurrentProcess();
command_line->AppendSwitch(::switches::kForceAppMode);
command_line->AppendSwitchASCII(::switches::kAppId,
- logged_in_user_->GetAccountName(false));
+ active_user_->GetAccountName(false));
}
void UserManagerImpl::LocallyManagedUserLoggedIn(
@@ -324,11 +378,11 @@ void UserManagerImpl::LocallyManagedUserLoggedIn(
// TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
// Remove the user from the user list.
- logged_in_user_ = RemoveRegularOrLocallyManagedUserFromList(username);
+ active_user_ = RemoveRegularOrLocallyManagedUserFromList(username);
// If the user was not found on the user list, create a new user.
- if (!logged_in_user_) {
+ if (!active_user_) {
is_current_user_new_ = true;
- logged_in_user_ = User::CreateLocallyManagedUser(username);
+ active_user_ = User::CreateLocallyManagedUser(username);
// Leaving OAuth token status at the default state = unknown.
WallpaperManager::Get()->SetInitialUserWallpaper(username, true);
} else {
@@ -344,12 +398,12 @@ void UserManagerImpl::LocallyManagedUserLoggedIn(
ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
kRegularUsers);
prefs_users_update->Insert(0, new base::StringValue(username));
- users_.insert(users_.begin(), logged_in_user_);
+ users_.insert(users_.begin(), active_user_);
// Now that user is in the list, save display name.
if (is_current_user_new_) {
- SaveUserDisplayName(logged_in_user_->email(),
- logged_in_user_->GetDisplayName());
+ SaveUserDisplayName(active_user_->email(),
+ active_user_->GetDisplayName());
}
user_image_manager_->UserLoggedIn(username, is_current_user_new_, true);
@@ -361,7 +415,7 @@ void UserManagerImpl::LocallyManagedUserLoggedIn(
void UserManagerImpl::PublicAccountUserLoggedIn(User* user) {
is_current_user_new_ = true;
- logged_in_user_ = user;
+ active_user_ = user;
// The UserImageManager chooses a random avatar picture when a user logs in
// for the first time. Tell the UserImageManager that this user is not new to
// prevent the avatar from getting changed.
@@ -372,15 +426,15 @@ void UserManagerImpl::PublicAccountUserLoggedIn(User* user) {
void UserManagerImpl::RegularUserLoggedIn(const std::string& email,
bool browser_restart) {
// Remove the user from the user list.
- logged_in_user_ = RemoveRegularOrLocallyManagedUserFromList(email);
+ active_user_ = RemoveRegularOrLocallyManagedUserFromList(email);
// If the user was not found on the user list, create a new user.
- if (!logged_in_user_) {
+ if (!active_user_) {
is_current_user_new_ = true;
- logged_in_user_ = User::CreateRegularUser(email);
- logged_in_user_->set_oauth_token_status(LoadUserOAuthStatus(email));
- SaveUserDisplayName(logged_in_user_->email(),
- UTF8ToUTF16(logged_in_user_->GetAccountName(true)));
+ active_user_ = User::CreateRegularUser(email);
+ active_user_->set_oauth_token_status(LoadUserOAuthStatus(email));
+ SaveUserDisplayName(active_user_->email(),
+ UTF8ToUTF16(active_user_->GetAccountName(true)));
WallpaperManager::Get()->SetInitialUserWallpaper(email, true);
}
@@ -388,7 +442,7 @@ void UserManagerImpl::RegularUserLoggedIn(const std::string& email,
ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
kRegularUsers);
prefs_users_update->Insert(0, new base::StringValue(email));
- users_.insert(users_.begin(), logged_in_user_);
+ users_.insert(users_.begin(), active_user_);
user_image_manager_->UserLoggedIn(email, is_current_user_new_, false);
@@ -405,7 +459,7 @@ void UserManagerImpl::RegularUserLoggedInAsEphemeral(const std::string& email) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
is_current_user_new_ = true;
is_current_user_ephemeral_regular_user_ = true;
- logged_in_user_ = User::CreateRegularUser(email);
+ active_user_ = User::CreateRegularUser(email);
user_image_manager_->UserLoggedIn(email, is_current_user_new_, false);
WallpaperManager::Get()->SetInitialUserWallpaper(email, false);
}
@@ -415,8 +469,8 @@ void UserManagerImpl::SessionStarted() {
session_started_ = true;
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_SESSION_STARTED,
- content::NotificationService::AllSources(),
- content::NotificationService::NoDetails());
+ content::Source<UserManager>(this),
+ content::Details<const User>(active_user_));
if (is_current_user_new_) {
// Make sure that the new user's data is persisted to Local State.
g_browser_process->local_state()->CommitPendingWrite();
@@ -484,9 +538,12 @@ void UserManagerImpl::RemoveUser(const std::string& email,
if (users_.size() < 2)
return;
- // Sanity check: do not allow the logged-in user to remove himself.
- if (logged_in_user_ && logged_in_user_->email() == email)
- return;
+ // Sanity check: do not allow any of the the logged in users to be removed.
+ for (UserList::const_iterator it = logged_in_users_.begin();
+ it != logged_in_users_.end(); ++it) {
+ if ((*it)->email() == email)
+ return;
+ }
RemoveUserInternal(email, delegate);
}
@@ -506,8 +563,8 @@ bool UserManagerImpl::IsKnownUser(const std::string& email) const {
const User* UserManagerImpl::FindUser(const std::string& email) const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (logged_in_user_ && logged_in_user_->email() == email)
- return logged_in_user_;
+ if (active_user_ && active_user_->email() == email)
+ return active_user_;
return FindUserInList(email);
}
@@ -526,12 +583,22 @@ const User* UserManagerImpl::FindLocallyManagedUser(
const User* UserManagerImpl::GetLoggedInUser() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- return logged_in_user_;
+ return active_user_;
}
User* UserManagerImpl::GetLoggedInUser() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- return logged_in_user_;
+ return active_user_;
+}
+
+const User* UserManagerImpl::GetActiveUser() const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ return active_user_;
+}
+
+User* UserManagerImpl::GetActiveUser() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ return active_user_;
}
void UserManagerImpl::SaveUserOAuthStatus(
@@ -540,7 +607,7 @@ void UserManagerImpl::SaveUserOAuthStatus(
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DVLOG(1) << "Saving user OAuth token status in Local State";
- User* user = const_cast<User*>(FindUser(username));
+ User* user = FindUserAndModify(username);
if (user)
user->set_oauth_token_status(oauth_token_status);
@@ -582,7 +649,7 @@ void UserManagerImpl::SaveUserDisplayName(const std::string& username,
const string16& display_name) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- User* user = const_cast<User*>(FindUser(username));
+ User* user = FindUserAndModify(username);
if (!user)
return; // Ignore if there is no such user.
@@ -611,7 +678,7 @@ void UserManagerImpl::SaveUserDisplayEmail(const std::string& username,
const std::string& display_email) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- User* user = const_cast<User*>(FindUser(username));
+ User* user = FindUserAndModify(username);
if (!user)
return; // Ignore if there is no such user.
@@ -688,8 +755,12 @@ void UserManagerImpl::OnStateChanged() {
// TODO(altimofeev): this code isn't needed after crosbug.com/25978 is
// implemented.
DVLOG(1) << "Invalidate OAuth token because of a sync error.";
+ // http://crbug.com/230860
+ // TODO(nkostylev): Figure out whether we want to have observers
+ // for each logged in user.
+ // TODO(nkostyelv): Change observer after active user has changed.
SaveUserOAuthStatus(
- logged_in_user_->email(),
+ active_user_->email(),
User::OAUTH2_TOKEN_STATUS_INVALID);
}
}
@@ -729,53 +800,53 @@ bool UserManagerImpl::IsCurrentUserNonCryptohomeDataEphemeral() const {
bool UserManagerImpl::CanCurrentUserLock() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- return IsUserLoggedIn() && logged_in_user_->can_lock();
+ return IsUserLoggedIn() && active_user_->can_lock();
}
bool UserManagerImpl::IsUserLoggedIn() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- return logged_in_user_;
+ return active_user_;
}
bool UserManagerImpl::IsLoggedInAsRegularUser() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return IsUserLoggedIn() &&
- logged_in_user_->GetType() == User::USER_TYPE_REGULAR;
+ active_user_->GetType() == User::USER_TYPE_REGULAR;
}
bool UserManagerImpl::IsLoggedInAsDemoUser() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return IsUserLoggedIn() &&
- logged_in_user_->GetType() == User::USER_TYPE_RETAIL_MODE;
+ active_user_->GetType() == User::USER_TYPE_RETAIL_MODE;
}
bool UserManagerImpl::IsLoggedInAsPublicAccount() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return IsUserLoggedIn() &&
- logged_in_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
+ active_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
}
bool UserManagerImpl::IsLoggedInAsGuest() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return IsUserLoggedIn() &&
- logged_in_user_->GetType() == User::USER_TYPE_GUEST;
+ active_user_->GetType() == User::USER_TYPE_GUEST;
}
bool UserManagerImpl::IsLoggedInAsLocallyManagedUser() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return IsUserLoggedIn() &&
- logged_in_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED;
+ active_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED;
}
bool UserManagerImpl::IsLoggedInAsKioskApp() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return IsUserLoggedIn() &&
- logged_in_user_->GetType() == User::USER_TYPE_KIOSK_APP;
+ active_user_->GetType() == User::USER_TYPE_KIOSK_APP;
}
bool UserManagerImpl::IsLoggedInAsStub() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- return IsUserLoggedIn() && logged_in_user_->email() == kStubUser;
+ return IsUserLoggedIn() && active_user_->email() == kStubUser;
}
bool UserManagerImpl::IsSessionStarted() const {
@@ -976,6 +1047,18 @@ bool UserManagerImpl::AreEphemeralUsersEnabled() const {
!owner_email_.empty());
}
+UserList& UserManagerImpl::GetUsersAndModify() {
+ EnsureUsersLoaded();
+ return users_;
+}
+
+User* UserManagerImpl::FindUserAndModify(const std::string& email) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (active_user_ && active_user_->email() == email)
+ return active_user_;
+ return FindUserInListAndModify(email);
+}
+
const User* UserManagerImpl::FindUserInList(const std::string& email) const {
const UserList& users = GetUsers();
for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
@@ -985,18 +1068,27 @@ const User* UserManagerImpl::FindUserInList(const std::string& email) const {
return NULL;
}
+User* UserManagerImpl::FindUserInListAndModify(const std::string& email) {
+ UserList& users = GetUsersAndModify();
+ for (UserList::iterator it = users.begin(); it != users.end(); ++it) {
+ if ((*it)->email() == email)
+ return *it;
+ }
+ return NULL;
+}
+
void UserManagerImpl::NotifyOnLogin() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_LOGIN_USER_CHANGED,
content::Source<UserManager>(this),
- content::Details<const User>(logged_in_user_));
+ content::Details<const User>(active_user_));
CrosLibrary::Get()->GetCertLibrary()->LoadKeyStore();
// Indicate to DeviceSettingsService that the owner key may have become
// available.
- DeviceSettingsService::Get()->SetUsername(logged_in_user_->email());
+ DeviceSettingsService::Get()->SetUsername(active_user_->email());
}
void UserManagerImpl::UpdateOwnership(
@@ -1060,9 +1152,9 @@ bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
PrefService* local_state = g_browser_process->local_state();
// Determine the currently logged-in user's email.
- std::string logged_in_user_email;
+ std::string active_user_email;
if (IsUserLoggedIn())
- logged_in_user_email = GetLoggedInUser()->email();
+ active_user_email = GetLoggedInUser()->email();
// If there is a public account whose data is pending removal and the user is
// not currently logged in with that account, take this opportunity to remove
@@ -1070,7 +1162,7 @@ bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
std::string public_account_pending_data_removal =
local_state->GetString(kPublicAccountPendingDataRemoval);
if (!public_account_pending_data_removal.empty() &&
- public_account_pending_data_removal != logged_in_user_email) {
+ public_account_pending_data_removal != active_user_email) {
RemoveNonCryptohomeData(public_account_pending_data_removal);
local_state->ClearPref(kPublicAccountPendingDataRemoval);
}
@@ -1088,14 +1180,14 @@ bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
// Get the new list of public accounts from policy.
std::vector<std::string> new_public_accounts;
std::set<std::string> new_public_accounts_set;
- if (!ParseUserList(public_accounts, regular_users, logged_in_user_email,
+ if (!ParseUserList(public_accounts, regular_users, active_user_email,
&new_public_accounts, &new_public_accounts_set) &&
IsLoggedInAsPublicAccount()) {
// If the user is currently logged into a public account that has been
// removed from the list, mark the account's data as pending removal after
// logout.
local_state->SetString(kPublicAccountPendingDataRemoval,
- logged_in_user_email);
+ active_user_email);
}
// Persist the new list of public accounts in a pref.
@@ -1131,7 +1223,7 @@ bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
for (std::vector<std::string>::const_reverse_iterator
it = new_public_accounts.rbegin();
it != new_public_accounts.rend(); ++it) {
- if (IsLoggedInAsPublicAccount() && *it == logged_in_user_email)
+ if (IsLoggedInAsPublicAccount() && *it == active_user_email)
users_.insert(users_.begin(), GetLoggedInUser());
else
users_.insert(users_.begin(), User::CreatePublicAccountUser(*it));
« no previous file with comments | « chrome/browser/chromeos/login/user_manager_impl.h ('k') | chrome/browser/chromeos/system/ash_system_tray_delegate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698