| 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 3f772404ab0224eee4419e921441830a6dfa391c..dce81c7ac9b53974ae4c6523eeac159ddaa6b66d 100644
|
| --- a/chrome/browser/chromeos/login/user_manager_impl.cc
|
| +++ b/chrome/browser/chromeos/login/user_manager_impl.cc
|
| @@ -126,36 +126,6 @@ void OnRemoveUserComplete(const std::string& user_email,
|
| }
|
| }
|
|
|
| -// This method is used to implement UserManager::RemoveUser.
|
| -void RemoveUserInternal(const std::string& user_email,
|
| - chromeos::RemoveUserDelegate* delegate) {
|
| - CrosSettings* cros_settings = CrosSettings::Get();
|
| -
|
| - // Ensure the value of owner email has been fetched.
|
| - if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues(
|
| - base::Bind(&RemoveUserInternal, user_email, delegate))) {
|
| - // Value of owner email is not fetched yet. RemoveUserInternal will be
|
| - // called again after fetch completion.
|
| - return;
|
| - }
|
| - std::string owner;
|
| - cros_settings->GetString(kDeviceOwner, &owner);
|
| - if (user_email == owner) {
|
| - // Owner is not allowed to be removed from the device.
|
| - return;
|
| - }
|
| -
|
| - if (delegate)
|
| - delegate->OnBeforeUserRemoved(user_email);
|
| -
|
| - chromeos::UserManager::Get()->RemoveUserFromList(user_email);
|
| - cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
|
| - user_email, base::Bind(&OnRemoveUserComplete, user_email));
|
| -
|
| - if (delegate)
|
| - delegate->OnUserRemoved(user_email);
|
| -}
|
| -
|
| // Helper function that copies users from |users_list| to |users_vector| and
|
| // |users_set|. Duplicates and users already present in |existing_users| are
|
| // skipped.
|
| @@ -511,12 +481,55 @@ void UserManagerImpl::RemoveUser(const std::string& user_id,
|
| RemoveUserInternal(user_id, delegate);
|
| }
|
|
|
| +void UserManagerImpl::RemoveUserInternal(const std::string& user_email,
|
| + RemoveUserDelegate* delegate) {
|
| + CrosSettings* cros_settings = CrosSettings::Get();
|
| +
|
| + // Ensure the value of owner email has been fetched.
|
| + if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues(
|
| + base::Bind(&UserManagerImpl::RemoveUserInternal,
|
| + base::Unretained(this),
|
| + user_email, delegate))) {
|
| + // Value of owner email is not fetched yet. RemoveUserInternal will be
|
| + // called again after fetch completion.
|
| + return;
|
| + }
|
| + std::string owner;
|
| + cros_settings->GetString(kDeviceOwner, &owner);
|
| + if (user_email == owner) {
|
| + // Owner is not allowed to be removed from the device.
|
| + return;
|
| + }
|
| + RemoveNonOwnerUserInternal(user_email, delegate);
|
| +}
|
| +
|
| +void UserManagerImpl::RemoveNonOwnerUserInternal(const std::string& user_email,
|
| + RemoveUserDelegate* delegate) {
|
| + if (delegate)
|
| + delegate->OnBeforeUserRemoved(user_email);
|
| + RemoveUserFromList(user_email);
|
| + cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
|
| + user_email, base::Bind(&OnRemoveUserComplete, user_email));
|
| +
|
| + if (delegate)
|
| + delegate->OnUserRemoved(user_email);
|
| +}
|
| +
|
| void UserManagerImpl::RemoveUserFromList(const std::string& user_id) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - EnsureUsersLoaded();
|
| RemoveNonCryptohomeData(user_id);
|
| - User* user = RemoveRegularOrLocallyManagedUserFromList(user_id);
|
| - delete user;
|
| + if (users_loaded_) {
|
| + User* user = RemoveRegularOrLocallyManagedUserFromList(user_id);
|
| + delete user;
|
| + } else {
|
| + DCHECK(gaia::ExtractDomainName(user_id) ==
|
| + UserManager::kLocallyManagedUserDomain);
|
| + // Special case, removing partially-constructed supervised user during user
|
| + // list loading.
|
| + ListPrefUpdate users_update(g_browser_process->local_state(),
|
| + kRegularUsers);
|
| + users_update->Remove(base::StringValue(user_id), NULL);
|
| + }
|
| // Make sure that new data is persisted to Local State.
|
| g_browser_process->local_state()->CommitPendingWrite();
|
| }
|
| @@ -957,7 +970,7 @@ bool UserManagerImpl::IsUserNonCryptohomeDataEphemeral(
|
|
|
| // Data belonging to the owner, anyone found on the user list and obsolete
|
| // public accounts whose data has not been removed yet is not ephemeral.
|
| - if (user_id == owner_email_ || FindUserInList(user_id) ||
|
| + if (user_id == owner_email_ || UserExistsInList(user_id) ||
|
| user_id == g_browser_process->local_state()->
|
| GetString(kPublicAccountPendingDataRemoval)) {
|
| return false;
|
| @@ -1033,9 +1046,9 @@ void UserManagerImpl::EnsureUsersLoaded() {
|
|
|
| if (users_loaded_)
|
| return;
|
| - users_loaded_ = true;
|
| -
|
| - // Clean up user list first.
|
| + // Clean up user list first. All code down the path should be synchronous,
|
| + // so that local state after transaction rollback is in consistent state.
|
| + // This process also should not trigger EnsureUsersLoaded again.
|
| if (supervised_user_manager_->HasFailedUserCreationTransaction())
|
| supervised_user_manager_->RollbackUserCreationTransaction();
|
|
|
| @@ -1087,6 +1100,7 @@ void UserManagerImpl::EnsureUsersLoaded() {
|
| users_.push_back(User::CreatePublicAccountUser(*it));
|
| UpdatePublicAccountDisplayName(*it);
|
| }
|
| + users_loaded_ = true;
|
|
|
| user_image_manager_->LoadUserImages(users_);
|
| }
|
| @@ -1164,6 +1178,17 @@ const User* UserManagerImpl::FindUserInList(const std::string& user_id) const {
|
| return NULL;
|
| }
|
|
|
| +const bool UserManagerImpl::UserExistsInList(const std::string& user_id) const {
|
| + PrefService* local_state = g_browser_process->local_state();
|
| + const ListValue* user_list = local_state->GetList(kRegularUsers);
|
| + for (size_t i = 0; i < user_list->GetSize(); ++i) {
|
| + std::string email;
|
| + if (user_list->GetString(i, &email) && (user_id == email))
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| User* UserManagerImpl::FindUserInListAndModify(const std::string& user_id) {
|
| UserList& users = GetUsersAndModify();
|
| for (UserList::iterator it = users.begin(); it != users.end(); ++it) {
|
|
|