Home | History | Annotate | Download | only in user_manager
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "components/user_manager/user_manager_base.h"
      6 
      7 #include <cstddef>
      8 #include <set>
      9 
     10 #include "base/bind.h"
     11 #include "base/bind_helpers.h"
     12 #include "base/command_line.h"
     13 #include "base/compiler_specific.h"
     14 #include "base/format_macros.h"
     15 #include "base/location.h"
     16 #include "base/logging.h"
     17 #include "base/macros.h"
     18 #include "base/metrics/histogram.h"
     19 #include "base/prefs/pref_registry_simple.h"
     20 #include "base/prefs/pref_service.h"
     21 #include "base/prefs/scoped_user_pref_update.h"
     22 #include "base/strings/string_util.h"
     23 #include "base/strings/stringprintf.h"
     24 #include "base/strings/utf_string_conversions.h"
     25 #include "base/task_runner.h"
     26 #include "base/values.h"
     27 #include "chromeos/chromeos_switches.h"
     28 #include "chromeos/cryptohome/async_method_caller.h"
     29 #include "chromeos/login/login_state.h"
     30 #include "chromeos/login/user_names.h"
     31 #include "components/session_manager/core/session_manager.h"
     32 #include "components/user_manager/remove_user_delegate.h"
     33 #include "components/user_manager/user_type.h"
     34 #include "google_apis/gaia/gaia_auth_util.h"
     35 #include "ui/base/l10n/l10n_util.h"
     36 
     37 namespace user_manager {
     38 namespace {
     39 
     40 // A vector pref of the the regular users known on this device, arranged in LRU
     41 // order.
     42 const char kRegularUsers[] = "LoggedInUsers";
     43 
     44 // A dictionary that maps user IDs to the displayed name.
     45 const char kUserDisplayName[] = "UserDisplayName";
     46 
     47 // A dictionary that maps user IDs to the user's given name.
     48 const char kUserGivenName[] = "UserGivenName";
     49 
     50 // A dictionary that maps user IDs to the displayed (non-canonical) emails.
     51 const char kUserDisplayEmail[] = "UserDisplayEmail";
     52 
     53 // A dictionary that maps user IDs to OAuth token presence flag.
     54 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus";
     55 
     56 // A dictionary that maps user IDs to a flag indicating whether online
     57 // authentication against GAIA should be enforced during the next sign-in.
     58 const char kUserForceOnlineSignin[] = "UserForceOnlineSignin";
     59 
     60 // A string pref containing the ID of the last user who logged in if it was
     61 // a regular user or an empty string if it was another type of user (guest,
     62 // kiosk, public account, etc.).
     63 const char kLastLoggedInRegularUser[] = "LastLoggedInRegularUser";
     64 
     65 // A string pref containing the ID of the last active user.
     66 // In case of browser crash, this pref will be used to set active user after
     67 // session restore.
     68 const char kLastActiveUser[] = "LastActiveUser";
     69 
     70 // Upper bound for a histogram metric reporting the amount of time between
     71 // one regular user logging out and a different regular user logging in.
     72 const int kLogoutToLoginDelayMaxSec = 1800;
     73 
     74 // Callback that is called after user removal is complete.
     75 void OnRemoveUserComplete(const std::string& user_email,
     76                           bool success,
     77                           cryptohome::MountError return_code) {
     78   // Log the error, but there's not much we can do.
     79   if (!success) {
     80     LOG(ERROR) << "Removal of cryptohome for " << user_email
     81                << " failed, return code: " << return_code;
     82   }
     83 }
     84 
     85 // Runs on SequencedWorkerPool thread. Passes resolved locale to UI thread.
     86 void ResolveLocale(const std::string& raw_locale,
     87                    std::string* resolved_locale) {
     88   ignore_result(l10n_util::CheckAndResolveLocale(raw_locale, resolved_locale));
     89 }
     90 
     91 }  // namespace
     92 
     93 // static
     94 void UserManagerBase::RegisterPrefs(PrefRegistrySimple* registry) {
     95   registry->RegisterListPref(kRegularUsers);
     96   registry->RegisterStringPref(kLastLoggedInRegularUser, std::string());
     97   registry->RegisterDictionaryPref(kUserDisplayName);
     98   registry->RegisterDictionaryPref(kUserGivenName);
     99   registry->RegisterDictionaryPref(kUserDisplayEmail);
    100   registry->RegisterDictionaryPref(kUserOAuthTokenStatus);
    101   registry->RegisterDictionaryPref(kUserForceOnlineSignin);
    102   registry->RegisterStringPref(kLastActiveUser, std::string());
    103 }
    104 
    105 UserManagerBase::UserManagerBase(
    106     scoped_refptr<base::TaskRunner> task_runner,
    107     scoped_refptr<base::TaskRunner> blocking_task_runner)
    108     : active_user_(NULL),
    109       primary_user_(NULL),
    110       user_loading_stage_(STAGE_NOT_LOADED),
    111       session_started_(false),
    112       is_current_user_owner_(false),
    113       is_current_user_new_(false),
    114       is_current_user_ephemeral_regular_user_(false),
    115       ephemeral_users_enabled_(false),
    116       manager_creation_time_(base::TimeTicks::Now()),
    117       last_session_active_user_initialized_(false),
    118       task_runner_(task_runner),
    119       blocking_task_runner_(blocking_task_runner),
    120       weak_factory_(this) {
    121   UpdateLoginState();
    122 }
    123 
    124 UserManagerBase::~UserManagerBase() {
    125   // Can't use STLDeleteElements because of the private destructor of User.
    126   for (UserList::iterator it = users_.begin(); it != users_.end();
    127        it = users_.erase(it)) {
    128     DeleteUser(*it);
    129   }
    130   // These are pointers to the same User instances that were in users_ list.
    131   logged_in_users_.clear();
    132   lru_logged_in_users_.clear();
    133 
    134   DeleteUser(active_user_);
    135 }
    136 
    137 void UserManagerBase::Shutdown() {
    138   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    139 }
    140 
    141 const UserList& UserManagerBase::GetUsers() const {
    142   const_cast<UserManagerBase*>(this)->EnsureUsersLoaded();
    143   return users_;
    144 }
    145 
    146 const UserList& UserManagerBase::GetLoggedInUsers() const {
    147   return logged_in_users_;
    148 }
    149 
    150 const UserList& UserManagerBase::GetLRULoggedInUsers() const {
    151   return lru_logged_in_users_;
    152 }
    153 
    154 const std::string& UserManagerBase::GetOwnerEmail() const {
    155   return owner_email_;
    156 }
    157 
    158 void UserManagerBase::UserLoggedIn(const std::string& user_id,
    159                                    const std::string& username_hash,
    160                                    bool browser_restart) {
    161   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    162 
    163   if (!last_session_active_user_initialized_) {
    164     last_session_active_user_ = GetLocalState()->GetString(kLastActiveUser);
    165     last_session_active_user_initialized_ = true;
    166   }
    167 
    168   User* user = FindUserInListAndModify(user_id);
    169   if (active_user_ && user) {
    170     user->set_is_logged_in(true);
    171     user->set_username_hash(username_hash);
    172     logged_in_users_.push_back(user);
    173     lru_logged_in_users_.push_back(user);
    174 
    175     // Reset the new user flag if the user already exists.
    176     SetIsCurrentUserNew(false);
    177     NotifyUserAddedToSession(user, true /* user switch pending */);
    178 
    179     return;
    180   }
    181 
    182   if (user_id == chromeos::login::kGuestUserName) {
    183     GuestUserLoggedIn();
    184   } else if (user_id == chromeos::login::kRetailModeUserName) {
    185     RetailModeUserLoggedIn();
    186   } else if (IsKioskApp(user_id)) {
    187     KioskAppLoggedIn(user_id);
    188   } else if (IsDemoApp(user_id)) {
    189     DemoAccountLoggedIn();
    190   } else {
    191     EnsureUsersLoaded();
    192 
    193     if (user && user->GetType() == USER_TYPE_PUBLIC_ACCOUNT) {
    194       PublicAccountUserLoggedIn(user);
    195     } else if ((user && user->GetType() == USER_TYPE_SUPERVISED) ||
    196                (!user &&
    197                 gaia::ExtractDomainName(user_id) ==
    198                     chromeos::login::kSupervisedUserDomain)) {
    199       SupervisedUserLoggedIn(user_id);
    200     } else if (browser_restart && IsPublicAccountMarkedForRemoval(user_id)) {
    201       PublicAccountUserLoggedIn(User::CreatePublicAccountUser(user_id));
    202     } else if (user_id != GetOwnerEmail() && !user &&
    203                (AreEphemeralUsersEnabled() || browser_restart)) {
    204       RegularUserLoggedInAsEphemeral(user_id);
    205     } else {
    206       RegularUserLoggedIn(user_id);
    207     }
    208   }
    209 
    210   DCHECK(active_user_);
    211   active_user_->set_is_logged_in(true);
    212   active_user_->set_is_active(true);
    213   active_user_->set_username_hash(username_hash);
    214 
    215   // Place user who just signed in to the top of the logged in users.
    216   logged_in_users_.insert(logged_in_users_.begin(), active_user_);
    217   SetLRUUser(active_user_);
    218 
    219   if (!primary_user_) {
    220     primary_user_ = active_user_;
    221     if (primary_user_->GetType() == USER_TYPE_REGULAR)
    222       SendRegularUserLoginMetrics(user_id);
    223   }
    224 
    225   UMA_HISTOGRAM_ENUMERATION(
    226       "UserManager.LoginUserType", active_user_->GetType(), NUM_USER_TYPES);
    227 
    228   GetLocalState()->SetString(
    229       kLastLoggedInRegularUser,
    230       (active_user_->GetType() == USER_TYPE_REGULAR) ? user_id : "");
    231 
    232   NotifyOnLogin();
    233   PerformPostUserLoggedInActions(browser_restart);
    234 }
    235 
    236 void UserManagerBase::SwitchActiveUser(const std::string& user_id) {
    237   User* user = FindUserAndModify(user_id);
    238   if (!user) {
    239     NOTREACHED() << "Switching to a non-existing user";
    240     return;
    241   }
    242   if (user == active_user_) {
    243     NOTREACHED() << "Switching to a user who is already active";
    244     return;
    245   }
    246   if (!user->is_logged_in()) {
    247     NOTREACHED() << "Switching to a user that is not logged in";
    248     return;
    249   }
    250   if (user->GetType() != USER_TYPE_REGULAR) {
    251     NOTREACHED() << "Switching to a non-regular user";
    252     return;
    253   }
    254   if (user->username_hash().empty()) {
    255     NOTREACHED() << "Switching to a user that doesn't have username_hash set";
    256     return;
    257   }
    258 
    259   DCHECK(active_user_);
    260   active_user_->set_is_active(false);
    261   user->set_is_active(true);
    262   active_user_ = user;
    263 
    264   // Move the user to the front.
    265   SetLRUUser(active_user_);
    266 
    267   NotifyActiveUserHashChanged(active_user_->username_hash());
    268   NotifyActiveUserChanged(active_user_);
    269 }
    270 
    271 void UserManagerBase::SwitchToLastActiveUser() {
    272   if (last_session_active_user_.empty())
    273     return;
    274 
    275   if (GetActiveUser()->email() != last_session_active_user_)
    276     SwitchActiveUser(last_session_active_user_);
    277 
    278   // Make sure that this function gets run only once.
    279   last_session_active_user_.clear();
    280 }
    281 
    282 void UserManagerBase::SessionStarted() {
    283   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    284   session_started_ = true;
    285 
    286   UpdateLoginState();
    287   session_manager::SessionManager::Get()->SetSessionState(
    288       session_manager::SESSION_STATE_ACTIVE);
    289 
    290   if (IsCurrentUserNew()) {
    291     // Make sure that the new user's data is persisted to Local State.
    292     GetLocalState()->CommitPendingWrite();
    293   }
    294 }
    295 
    296 void UserManagerBase::RemoveUser(const std::string& user_id,
    297                                  RemoveUserDelegate* delegate) {
    298   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    299 
    300   if (!CanUserBeRemoved(FindUser(user_id)))
    301     return;
    302 
    303   RemoveUserInternal(user_id, delegate);
    304 }
    305 
    306 void UserManagerBase::RemoveUserInternal(const std::string& user_email,
    307                                          RemoveUserDelegate* delegate) {
    308   RemoveNonOwnerUserInternal(user_email, delegate);
    309 }
    310 
    311 void UserManagerBase::RemoveNonOwnerUserInternal(const std::string& user_email,
    312                                                  RemoveUserDelegate* delegate) {
    313   if (delegate)
    314     delegate->OnBeforeUserRemoved(user_email);
    315   RemoveUserFromList(user_email);
    316   cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
    317       user_email, base::Bind(&OnRemoveUserComplete, user_email));
    318 
    319   if (delegate)
    320     delegate->OnUserRemoved(user_email);
    321 }
    322 
    323 void UserManagerBase::RemoveUserFromList(const std::string& user_id) {
    324   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    325   RemoveNonCryptohomeData(user_id);
    326   if (user_loading_stage_ == STAGE_LOADED) {
    327     DeleteUser(RemoveRegularOrSupervisedUserFromList(user_id));
    328   } else if (user_loading_stage_ == STAGE_LOADING) {
    329     DCHECK(gaia::ExtractDomainName(user_id) ==
    330            chromeos::login::kSupervisedUserDomain);
    331     // Special case, removing partially-constructed supervised user during user
    332     // list loading.
    333     ListPrefUpdate users_update(GetLocalState(), kRegularUsers);
    334     users_update->Remove(base::StringValue(user_id), NULL);
    335   } else {
    336     NOTREACHED() << "Users are not loaded yet.";
    337     return;
    338   }
    339 
    340   // Make sure that new data is persisted to Local State.
    341   GetLocalState()->CommitPendingWrite();
    342 }
    343 
    344 bool UserManagerBase::IsKnownUser(const std::string& user_id) const {
    345   return FindUser(user_id) != NULL;
    346 }
    347 
    348 const User* UserManagerBase::FindUser(const std::string& user_id) const {
    349   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    350   if (active_user_ && active_user_->email() == user_id)
    351     return active_user_;
    352   return FindUserInList(user_id);
    353 }
    354 
    355 User* UserManagerBase::FindUserAndModify(const std::string& user_id) {
    356   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    357   if (active_user_ && active_user_->email() == user_id)
    358     return active_user_;
    359   return FindUserInListAndModify(user_id);
    360 }
    361 
    362 const User* UserManagerBase::GetLoggedInUser() const {
    363   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    364   return active_user_;
    365 }
    366 
    367 User* UserManagerBase::GetLoggedInUser() {
    368   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    369   return active_user_;
    370 }
    371 
    372 const User* UserManagerBase::GetActiveUser() const {
    373   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    374   return active_user_;
    375 }
    376 
    377 User* UserManagerBase::GetActiveUser() {
    378   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    379   return active_user_;
    380 }
    381 
    382 const User* UserManagerBase::GetPrimaryUser() const {
    383   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    384   return primary_user_;
    385 }
    386 
    387 void UserManagerBase::SaveUserOAuthStatus(
    388     const std::string& user_id,
    389     User::OAuthTokenStatus oauth_token_status) {
    390   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    391 
    392   DVLOG(1) << "Saving user OAuth token status in Local State";
    393   User* user = FindUserAndModify(user_id);
    394   if (user)
    395     user->set_oauth_token_status(oauth_token_status);
    396 
    397   // Do not update local state if data stored or cached outside the user's
    398   // cryptohome is to be treated as ephemeral.
    399   if (IsUserNonCryptohomeDataEphemeral(user_id))
    400     return;
    401 
    402   DictionaryPrefUpdate oauth_status_update(GetLocalState(),
    403                                            kUserOAuthTokenStatus);
    404   oauth_status_update->SetWithoutPathExpansion(
    405       user_id,
    406       new base::FundamentalValue(static_cast<int>(oauth_token_status)));
    407 }
    408 
    409 void UserManagerBase::SaveForceOnlineSignin(const std::string& user_id,
    410                                             bool force_online_signin) {
    411   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    412 
    413   // Do not update local state if data stored or cached outside the user's
    414   // cryptohome is to be treated as ephemeral.
    415   if (IsUserNonCryptohomeDataEphemeral(user_id))
    416     return;
    417 
    418   DictionaryPrefUpdate force_online_update(GetLocalState(),
    419                                            kUserForceOnlineSignin);
    420   force_online_update->SetBooleanWithoutPathExpansion(user_id,
    421                                                       force_online_signin);
    422 }
    423 
    424 void UserManagerBase::SaveUserDisplayName(const std::string& user_id,
    425                                           const base::string16& display_name) {
    426   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    427 
    428   if (User* user = FindUserAndModify(user_id)) {
    429     user->set_display_name(display_name);
    430 
    431     // Do not update local state if data stored or cached outside the user's
    432     // cryptohome is to be treated as ephemeral.
    433     if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
    434       DictionaryPrefUpdate display_name_update(GetLocalState(),
    435                                                kUserDisplayName);
    436       display_name_update->SetWithoutPathExpansion(
    437           user_id, new base::StringValue(display_name));
    438     }
    439   }
    440 }
    441 
    442 base::string16 UserManagerBase::GetUserDisplayName(
    443     const std::string& user_id) const {
    444   const User* user = FindUser(user_id);
    445   return user ? user->display_name() : base::string16();
    446 }
    447 
    448 void UserManagerBase::SaveUserDisplayEmail(const std::string& user_id,
    449                                            const std::string& display_email) {
    450   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    451 
    452   User* user = FindUserAndModify(user_id);
    453   if (!user) {
    454     LOG(ERROR) << "User not found: " << user_id;
    455     return;  // Ignore if there is no such user.
    456   }
    457 
    458   user->set_display_email(display_email);
    459 
    460   // Do not update local state if data stored or cached outside the user's
    461   // cryptohome is to be treated as ephemeral.
    462   if (IsUserNonCryptohomeDataEphemeral(user_id))
    463     return;
    464 
    465   DictionaryPrefUpdate display_email_update(GetLocalState(), kUserDisplayEmail);
    466   display_email_update->SetWithoutPathExpansion(
    467       user_id, new base::StringValue(display_email));
    468 }
    469 
    470 std::string UserManagerBase::GetUserDisplayEmail(
    471     const std::string& user_id) const {
    472   const User* user = FindUser(user_id);
    473   return user ? user->display_email() : user_id;
    474 }
    475 
    476 void UserManagerBase::UpdateUserAccountData(
    477     const std::string& user_id,
    478     const UserAccountData& account_data) {
    479   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    480 
    481   SaveUserDisplayName(user_id, account_data.display_name());
    482 
    483   if (User* user = FindUserAndModify(user_id)) {
    484     base::string16 given_name = account_data.given_name();
    485     user->set_given_name(given_name);
    486     if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
    487       DictionaryPrefUpdate given_name_update(GetLocalState(), kUserGivenName);
    488       given_name_update->SetWithoutPathExpansion(
    489           user_id, new base::StringValue(given_name));
    490     }
    491   }
    492 
    493   UpdateUserAccountLocale(user_id, account_data.locale());
    494 }
    495 
    496 // static
    497 void UserManagerBase::ParseUserList(const base::ListValue& users_list,
    498                                     const std::set<std::string>& existing_users,
    499                                     std::vector<std::string>* users_vector,
    500                                     std::set<std::string>* users_set) {
    501   users_vector->clear();
    502   users_set->clear();
    503   for (size_t i = 0; i < users_list.GetSize(); ++i) {
    504     std::string email;
    505     if (!users_list.GetString(i, &email) || email.empty()) {
    506       LOG(ERROR) << "Corrupt entry in user list at index " << i << ".";
    507       continue;
    508     }
    509     if (existing_users.find(email) != existing_users.end() ||
    510         !users_set->insert(email).second) {
    511       LOG(ERROR) << "Duplicate user: " << email;
    512       continue;
    513     }
    514     users_vector->push_back(email);
    515   }
    516 }
    517 
    518 bool UserManagerBase::IsCurrentUserOwner() const {
    519   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    520   base::AutoLock lk(is_current_user_owner_lock_);
    521   return is_current_user_owner_;
    522 }
    523 
    524 void UserManagerBase::SetCurrentUserIsOwner(bool is_current_user_owner) {
    525   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    526   {
    527     base::AutoLock lk(is_current_user_owner_lock_);
    528     is_current_user_owner_ = is_current_user_owner;
    529   }
    530   UpdateLoginState();
    531 }
    532 
    533 bool UserManagerBase::IsCurrentUserNew() const {
    534   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    535   return is_current_user_new_;
    536 }
    537 
    538 bool UserManagerBase::IsCurrentUserNonCryptohomeDataEphemeral() const {
    539   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    540   return IsUserLoggedIn() &&
    541          IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email());
    542 }
    543 
    544 bool UserManagerBase::CanCurrentUserLock() const {
    545   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    546   return IsUserLoggedIn() && active_user_->can_lock();
    547 }
    548 
    549 bool UserManagerBase::IsUserLoggedIn() const {
    550   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    551   return active_user_;
    552 }
    553 
    554 bool UserManagerBase::IsLoggedInAsRegularUser() const {
    555   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    556   return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_REGULAR;
    557 }
    558 
    559 bool UserManagerBase::IsLoggedInAsDemoUser() const {
    560   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    561   return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_RETAIL_MODE;
    562 }
    563 
    564 bool UserManagerBase::IsLoggedInAsPublicAccount() const {
    565   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    566   return IsUserLoggedIn() &&
    567          active_user_->GetType() == USER_TYPE_PUBLIC_ACCOUNT;
    568 }
    569 
    570 bool UserManagerBase::IsLoggedInAsGuest() const {
    571   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    572   return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_GUEST;
    573 }
    574 
    575 bool UserManagerBase::IsLoggedInAsSupervisedUser() const {
    576   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    577   return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_SUPERVISED;
    578 }
    579 
    580 bool UserManagerBase::IsLoggedInAsKioskApp() const {
    581   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    582   return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_KIOSK_APP;
    583 }
    584 
    585 bool UserManagerBase::IsLoggedInAsStub() const {
    586   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    587   return IsUserLoggedIn() &&
    588          active_user_->email() == chromeos::login::kStubUser;
    589 }
    590 
    591 bool UserManagerBase::IsSessionStarted() const {
    592   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    593   return session_started_;
    594 }
    595 
    596 bool UserManagerBase::IsUserNonCryptohomeDataEphemeral(
    597     const std::string& user_id) const {
    598   // Data belonging to the guest, retail mode and stub users is always
    599   // ephemeral.
    600   if (user_id == chromeos::login::kGuestUserName ||
    601       user_id == chromeos::login::kRetailModeUserName ||
    602       user_id == chromeos::login::kStubUser) {
    603     return true;
    604   }
    605 
    606   // Data belonging to the owner, anyone found on the user list and obsolete
    607   // public accounts whose data has not been removed yet is not ephemeral.
    608   if (user_id == GetOwnerEmail() || UserExistsInList(user_id) ||
    609       IsPublicAccountMarkedForRemoval(user_id)) {
    610     return false;
    611   }
    612 
    613   // Data belonging to the currently logged-in user is ephemeral when:
    614   // a) The user logged into a regular account while the ephemeral users policy
    615   //    was enabled.
    616   //    - or -
    617   // b) The user logged into any other account type.
    618   if (IsUserLoggedIn() && (user_id == GetLoggedInUser()->email()) &&
    619       (is_current_user_ephemeral_regular_user_ || !IsLoggedInAsRegularUser())) {
    620     return true;
    621   }
    622 
    623   // Data belonging to any other user is ephemeral when:
    624   // a) Going through the regular login flow and the ephemeral users policy is
    625   //    enabled.
    626   //    - or -
    627   // b) The browser is restarting after a crash.
    628   return AreEphemeralUsersEnabled() ||
    629          session_manager::SessionManager::HasBrowserRestarted();
    630 }
    631 
    632 void UserManagerBase::AddObserver(UserManager::Observer* obs) {
    633   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    634   observer_list_.AddObserver(obs);
    635 }
    636 
    637 void UserManagerBase::RemoveObserver(UserManager::Observer* obs) {
    638   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    639   observer_list_.RemoveObserver(obs);
    640 }
    641 
    642 void UserManagerBase::AddSessionStateObserver(
    643     UserManager::UserSessionStateObserver* obs) {
    644   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    645   session_state_observer_list_.AddObserver(obs);
    646 }
    647 
    648 void UserManagerBase::RemoveSessionStateObserver(
    649     UserManager::UserSessionStateObserver* obs) {
    650   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    651   session_state_observer_list_.RemoveObserver(obs);
    652 }
    653 
    654 void UserManagerBase::NotifyLocalStateChanged() {
    655   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    656   FOR_EACH_OBSERVER(
    657       UserManager::Observer, observer_list_, LocalStateChanged(this));
    658 }
    659 
    660 void UserManagerBase::ForceUpdateState() {
    661   UpdateLoginState();
    662 }
    663 
    664 bool UserManagerBase::CanUserBeRemoved(const User* user) const {
    665   // Only regular and supervised users are allowed to be manually removed.
    666   if (!user || (user->GetType() != USER_TYPE_REGULAR &&
    667                 user->GetType() != USER_TYPE_SUPERVISED)) {
    668     return false;
    669   }
    670 
    671   // Sanity check: we must not remove single user unless it's an enterprise
    672   // device. This check may seem redundant at a first sight because
    673   // this single user must be an owner and we perform special check later
    674   // in order not to remove an owner. However due to non-instant nature of
    675   // ownership assignment this later check may sometimes fail.
    676   // See http://crosbug.com/12723
    677   if (users_.size() < 2 && !IsEnterpriseManaged())
    678     return false;
    679 
    680   // Sanity check: do not allow any of the the logged in users to be removed.
    681   for (UserList::const_iterator it = logged_in_users_.begin();
    682        it != logged_in_users_.end();
    683        ++it) {
    684     if ((*it)->email() == user->email())
    685       return false;
    686   }
    687 
    688   return true;
    689 }
    690 
    691 bool UserManagerBase::GetEphemeralUsersEnabled() const {
    692   return ephemeral_users_enabled_;
    693 }
    694 
    695 void UserManagerBase::SetEphemeralUsersEnabled(bool enabled) {
    696   ephemeral_users_enabled_ = enabled;
    697 }
    698 
    699 void UserManagerBase::SetIsCurrentUserNew(bool is_new) {
    700   is_current_user_new_ = is_new;
    701 }
    702 
    703 void UserManagerBase::SetOwnerEmail(std::string owner_user_id) {
    704   owner_email_ = owner_user_id;
    705 }
    706 
    707 const std::string& UserManagerBase::GetPendingUserSwitchID() const {
    708   return pending_user_switch_;
    709 }
    710 
    711 void UserManagerBase::SetPendingUserSwitchID(std::string user_id) {
    712   pending_user_switch_ = user_id;
    713 }
    714 
    715 void UserManagerBase::EnsureUsersLoaded() {
    716   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    717   if (!GetLocalState())
    718     return;
    719 
    720   if (user_loading_stage_ != STAGE_NOT_LOADED)
    721     return;
    722   user_loading_stage_ = STAGE_LOADING;
    723 
    724   PerformPreUserListLoadingActions();
    725 
    726   PrefService* local_state = GetLocalState();
    727   const base::ListValue* prefs_regular_users =
    728       local_state->GetList(kRegularUsers);
    729 
    730   const base::DictionaryValue* prefs_display_names =
    731       local_state->GetDictionary(kUserDisplayName);
    732   const base::DictionaryValue* prefs_given_names =
    733       local_state->GetDictionary(kUserGivenName);
    734   const base::DictionaryValue* prefs_display_emails =
    735       local_state->GetDictionary(kUserDisplayEmail);
    736 
    737   // Load public sessions first.
    738   std::set<std::string> public_sessions_set;
    739   LoadPublicAccounts(&public_sessions_set);
    740 
    741   // Load regular users and supervised users.
    742   std::vector<std::string> regular_users;
    743   std::set<std::string> regular_users_set;
    744   ParseUserList(*prefs_regular_users,
    745                 public_sessions_set,
    746                 &regular_users,
    747                 &regular_users_set);
    748   for (std::vector<std::string>::const_iterator it = regular_users.begin();
    749        it != regular_users.end();
    750        ++it) {
    751     User* user = NULL;
    752     const std::string domain = gaia::ExtractDomainName(*it);
    753     if (domain == chromeos::login::kSupervisedUserDomain)
    754       user = User::CreateSupervisedUser(*it);
    755     else
    756       user = User::CreateRegularUser(*it);
    757     user->set_oauth_token_status(LoadUserOAuthStatus(*it));
    758     user->set_force_online_signin(LoadForceOnlineSignin(*it));
    759     users_.push_back(user);
    760 
    761     base::string16 display_name;
    762     if (prefs_display_names->GetStringWithoutPathExpansion(*it,
    763                                                            &display_name)) {
    764       user->set_display_name(display_name);
    765     }
    766 
    767     base::string16 given_name;
    768     if (prefs_given_names->GetStringWithoutPathExpansion(*it, &given_name)) {
    769       user->set_given_name(given_name);
    770     }
    771 
    772     std::string display_email;
    773     if (prefs_display_emails->GetStringWithoutPathExpansion(*it,
    774                                                             &display_email)) {
    775       user->set_display_email(display_email);
    776     }
    777   }
    778 
    779   user_loading_stage_ = STAGE_LOADED;
    780 
    781   PerformPostUserListLoadingActions();
    782 }
    783 
    784 UserList& UserManagerBase::GetUsersAndModify() {
    785   EnsureUsersLoaded();
    786   return users_;
    787 }
    788 
    789 const User* UserManagerBase::FindUserInList(const std::string& user_id) const {
    790   const UserList& users = GetUsers();
    791   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
    792     if ((*it)->email() == user_id)
    793       return *it;
    794   }
    795   return NULL;
    796 }
    797 
    798 const bool UserManagerBase::UserExistsInList(const std::string& user_id) const {
    799   const base::ListValue* user_list = GetLocalState()->GetList(kRegularUsers);
    800   for (size_t i = 0; i < user_list->GetSize(); ++i) {
    801     std::string email;
    802     if (user_list->GetString(i, &email) && (user_id == email))
    803       return true;
    804   }
    805   return false;
    806 }
    807 
    808 User* UserManagerBase::FindUserInListAndModify(const std::string& user_id) {
    809   UserList& users = GetUsersAndModify();
    810   for (UserList::iterator it = users.begin(); it != users.end(); ++it) {
    811     if ((*it)->email() == user_id)
    812       return *it;
    813   }
    814   return NULL;
    815 }
    816 
    817 void UserManagerBase::GuestUserLoggedIn() {
    818   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    819   active_user_ = User::CreateGuestUser();
    820 }
    821 
    822 void UserManagerBase::AddUserRecord(User* user) {
    823   // Add the user to the front of the user list.
    824   ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
    825   prefs_users_update->Insert(0, new base::StringValue(user->email()));
    826   users_.insert(users_.begin(), user);
    827 }
    828 
    829 void UserManagerBase::RegularUserLoggedIn(const std::string& user_id) {
    830   // Remove the user from the user list.
    831   active_user_ = RemoveRegularOrSupervisedUserFromList(user_id);
    832 
    833   // If the user was not found on the user list, create a new user.
    834   SetIsCurrentUserNew(!active_user_);
    835   if (IsCurrentUserNew()) {
    836     active_user_ = User::CreateRegularUser(user_id);
    837     active_user_->set_oauth_token_status(LoadUserOAuthStatus(user_id));
    838     SaveUserDisplayName(active_user_->email(),
    839                         base::UTF8ToUTF16(active_user_->GetAccountName(true)));
    840   }
    841 
    842   AddUserRecord(active_user_);
    843 
    844   // Make sure that new data is persisted to Local State.
    845   GetLocalState()->CommitPendingWrite();
    846 }
    847 
    848 void UserManagerBase::RegularUserLoggedInAsEphemeral(
    849     const std::string& user_id) {
    850   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    851   SetIsCurrentUserNew(true);
    852   is_current_user_ephemeral_regular_user_ = true;
    853   active_user_ = User::CreateRegularUser(user_id);
    854 }
    855 
    856 void UserManagerBase::NotifyOnLogin() {
    857   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    858 
    859   NotifyActiveUserHashChanged(active_user_->username_hash());
    860   NotifyActiveUserChanged(active_user_);
    861   UpdateLoginState();
    862 }
    863 
    864 User::OAuthTokenStatus UserManagerBase::LoadUserOAuthStatus(
    865     const std::string& user_id) const {
    866   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    867 
    868   const base::DictionaryValue* prefs_oauth_status =
    869       GetLocalState()->GetDictionary(kUserOAuthTokenStatus);
    870   int oauth_token_status = User::OAUTH_TOKEN_STATUS_UNKNOWN;
    871   if (prefs_oauth_status &&
    872       prefs_oauth_status->GetIntegerWithoutPathExpansion(user_id,
    873                                                          &oauth_token_status)) {
    874     User::OAuthTokenStatus status =
    875         static_cast<User::OAuthTokenStatus>(oauth_token_status);
    876     HandleUserOAuthTokenStatusChange(user_id, status);
    877 
    878     return status;
    879   }
    880   return User::OAUTH_TOKEN_STATUS_UNKNOWN;
    881 }
    882 
    883 bool UserManagerBase::LoadForceOnlineSignin(const std::string& user_id) const {
    884   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    885 
    886   const base::DictionaryValue* prefs_force_online =
    887       GetLocalState()->GetDictionary(kUserForceOnlineSignin);
    888   bool force_online_signin = false;
    889   if (prefs_force_online) {
    890     prefs_force_online->GetBooleanWithoutPathExpansion(user_id,
    891                                                        &force_online_signin);
    892   }
    893   return force_online_signin;
    894 }
    895 
    896 void UserManagerBase::RemoveNonCryptohomeData(const std::string& user_id) {
    897   PrefService* prefs = GetLocalState();
    898   DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
    899   prefs_display_name_update->RemoveWithoutPathExpansion(user_id, NULL);
    900 
    901   DictionaryPrefUpdate prefs_given_name_update(prefs, kUserGivenName);
    902   prefs_given_name_update->RemoveWithoutPathExpansion(user_id, NULL);
    903 
    904   DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
    905   prefs_display_email_update->RemoveWithoutPathExpansion(user_id, NULL);
    906 
    907   DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
    908   prefs_oauth_update->RemoveWithoutPathExpansion(user_id, NULL);
    909 
    910   DictionaryPrefUpdate prefs_force_online_update(prefs, kUserForceOnlineSignin);
    911   prefs_force_online_update->RemoveWithoutPathExpansion(user_id, NULL);
    912 
    913   std::string last_active_user = GetLocalState()->GetString(kLastActiveUser);
    914   if (user_id == last_active_user)
    915     GetLocalState()->SetString(kLastActiveUser, std::string());
    916 }
    917 
    918 User* UserManagerBase::RemoveRegularOrSupervisedUserFromList(
    919     const std::string& user_id) {
    920   ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
    921   prefs_users_update->Clear();
    922   User* user = NULL;
    923   for (UserList::iterator it = users_.begin(); it != users_.end();) {
    924     const std::string user_email = (*it)->email();
    925     if (user_email == user_id) {
    926       user = *it;
    927       it = users_.erase(it);
    928     } else {
    929       if ((*it)->GetType() == USER_TYPE_REGULAR ||
    930           (*it)->GetType() == USER_TYPE_SUPERVISED) {
    931         prefs_users_update->Append(new base::StringValue(user_email));
    932       }
    933       ++it;
    934     }
    935   }
    936   return user;
    937 }
    938 
    939 void UserManagerBase::NotifyActiveUserChanged(const User* active_user) {
    940   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    941   FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
    942                     session_state_observer_list_,
    943                     ActiveUserChanged(active_user));
    944 }
    945 
    946 void UserManagerBase::NotifyUserAddedToSession(const User* added_user,
    947                                                bool user_switch_pending) {
    948   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    949   FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
    950                     session_state_observer_list_,
    951                     UserAddedToSession(added_user));
    952 }
    953 
    954 void UserManagerBase::NotifyActiveUserHashChanged(const std::string& hash) {
    955   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    956   FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
    957                     session_state_observer_list_,
    958                     ActiveUserHashChanged(hash));
    959 }
    960 
    961 void UserManagerBase::UpdateLoginState() {
    962   if (!chromeos::LoginState::IsInitialized())
    963     return;  // LoginState may not be intialized in tests.
    964 
    965   chromeos::LoginState::LoggedInState logged_in_state;
    966   logged_in_state = active_user_ ? chromeos::LoginState::LOGGED_IN_ACTIVE
    967                                  : chromeos::LoginState::LOGGED_IN_NONE;
    968 
    969   chromeos::LoginState::LoggedInUserType login_user_type;
    970   if (logged_in_state == chromeos::LoginState::LOGGED_IN_NONE)
    971     login_user_type = chromeos::LoginState::LOGGED_IN_USER_NONE;
    972   else if (is_current_user_owner_)
    973     login_user_type = chromeos::LoginState::LOGGED_IN_USER_OWNER;
    974   else if (active_user_->GetType() == USER_TYPE_GUEST)
    975     login_user_type = chromeos::LoginState::LOGGED_IN_USER_GUEST;
    976   else if (active_user_->GetType() == USER_TYPE_RETAIL_MODE)
    977     login_user_type = chromeos::LoginState::LOGGED_IN_USER_RETAIL_MODE;
    978   else if (active_user_->GetType() == USER_TYPE_PUBLIC_ACCOUNT)
    979     login_user_type = chromeos::LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT;
    980   else if (active_user_->GetType() == USER_TYPE_SUPERVISED)
    981     login_user_type = chromeos::LoginState::LOGGED_IN_USER_SUPERVISED;
    982   else if (active_user_->GetType() == USER_TYPE_KIOSK_APP)
    983     login_user_type = chromeos::LoginState::LOGGED_IN_USER_KIOSK_APP;
    984   else
    985     login_user_type = chromeos::LoginState::LOGGED_IN_USER_REGULAR;
    986 
    987   if (primary_user_) {
    988     chromeos::LoginState::Get()->SetLoggedInStateAndPrimaryUser(
    989         logged_in_state, login_user_type, primary_user_->username_hash());
    990   } else {
    991     chromeos::LoginState::Get()->SetLoggedInState(logged_in_state,
    992                                                   login_user_type);
    993   }
    994 }
    995 
    996 void UserManagerBase::SetLRUUser(User* user) {
    997   GetLocalState()->SetString(kLastActiveUser, user->email());
    998   GetLocalState()->CommitPendingWrite();
    999 
   1000   UserList::iterator it =
   1001       std::find(lru_logged_in_users_.begin(), lru_logged_in_users_.end(), user);
   1002   if (it != lru_logged_in_users_.end())
   1003     lru_logged_in_users_.erase(it);
   1004   lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user);
   1005 }
   1006 
   1007 void UserManagerBase::SendRegularUserLoginMetrics(const std::string& user_id) {
   1008   // If this isn't the first time Chrome was run after the system booted,
   1009   // assume that Chrome was restarted because a previous session ended.
   1010   if (!CommandLine::ForCurrentProcess()->HasSwitch(
   1011           chromeos::switches::kFirstExecAfterBoot)) {
   1012     const std::string last_email =
   1013         GetLocalState()->GetString(kLastLoggedInRegularUser);
   1014     const base::TimeDelta time_to_login =
   1015         base::TimeTicks::Now() - manager_creation_time_;
   1016     if (!last_email.empty() && user_id != last_email &&
   1017         time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) {
   1018       UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay",
   1019                                   time_to_login.InSeconds(),
   1020                                   0,
   1021                                   kLogoutToLoginDelayMaxSec,
   1022                                   50);
   1023     }
   1024   }
   1025 }
   1026 
   1027 void UserManagerBase::UpdateUserAccountLocale(const std::string& user_id,
   1028                                               const std::string& locale) {
   1029   scoped_ptr<std::string> resolved_locale(new std::string());
   1030   if (!locale.empty() && locale != GetApplicationLocale()) {
   1031     // base::Pased will NULL out |resolved_locale|, so cache the underlying ptr.
   1032     std::string* raw_resolved_locale = resolved_locale.get();
   1033     blocking_task_runner_->PostTaskAndReply(
   1034         FROM_HERE,
   1035         base::Bind(ResolveLocale,
   1036                    locale,
   1037                    base::Unretained(raw_resolved_locale)),
   1038         base::Bind(&UserManagerBase::DoUpdateAccountLocale,
   1039                    weak_factory_.GetWeakPtr(),
   1040                    user_id,
   1041                    base::Passed(&resolved_locale)));
   1042   } else {
   1043     resolved_locale.reset(new std::string(locale));
   1044     DoUpdateAccountLocale(user_id, resolved_locale.Pass());
   1045   }
   1046 }
   1047 
   1048 void UserManagerBase::DoUpdateAccountLocale(
   1049     const std::string& user_id,
   1050     scoped_ptr<std::string> resolved_locale) {
   1051   User* user = FindUserAndModify(user_id);
   1052   if (user && resolved_locale)
   1053     user->SetAccountLocale(*resolved_locale);
   1054 }
   1055 
   1056 void UserManagerBase::DeleteUser(User* user) {
   1057   const bool is_active_user = (user == active_user_);
   1058   delete user;
   1059   if (is_active_user)
   1060     active_user_ = NULL;
   1061 }
   1062 
   1063 }  // namespace user_manager
   1064