Home | History | Annotate | Download | only in users
      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 "chrome/browser/chromeos/login/users/chrome_user_manager_impl.h"
      6 
      7 #include <cstddef>
      8 #include <set>
      9 
     10 #include "ash/multi_profile_uma.h"
     11 #include "base/bind.h"
     12 #include "base/bind_helpers.h"
     13 #include "base/command_line.h"
     14 #include "base/compiler_specific.h"
     15 #include "base/format_macros.h"
     16 #include "base/logging.h"
     17 #include "base/metrics/histogram.h"
     18 #include "base/prefs/pref_registry_simple.h"
     19 #include "base/prefs/pref_service.h"
     20 #include "base/prefs/scoped_user_pref_update.h"
     21 #include "base/strings/string_util.h"
     22 #include "base/strings/stringprintf.h"
     23 #include "base/strings/utf_string_conversions.h"
     24 #include "base/thread_task_runner_handle.h"
     25 #include "base/values.h"
     26 #include "chrome/browser/browser_process.h"
     27 #include "chrome/browser/chrome_notification_types.h"
     28 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
     29 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
     30 #include "chrome/browser/chromeos/login/signin/auth_sync_observer.h"
     31 #include "chrome/browser/chromeos/login/signin/auth_sync_observer_factory.h"
     32 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h"
     33 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
     34 #include "chrome/browser/chromeos/login/users/supervised_user_manager_impl.h"
     35 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
     36 #include "chrome/browser/chromeos/policy/device_local_account.h"
     37 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog.h"
     38 #include "chrome/browser/chromeos/profiles/profile_helper.h"
     39 #include "chrome/browser/chromeos/session_length_limiter.h"
     40 #include "chrome/browser/profiles/profile.h"
     41 #include "chrome/browser/signin/easy_unlock_service.h"
     42 #include "chrome/browser/supervised_user/chromeos/manager_password_service_factory.h"
     43 #include "chrome/browser/supervised_user/chromeos/supervised_user_password_service_factory.h"
     44 #include "chrome/common/chrome_constants.h"
     45 #include "chrome/common/chrome_switches.h"
     46 #include "chrome/common/crash_keys.h"
     47 #include "chrome/common/pref_names.h"
     48 #include "chrome/grit/theme_resources.h"
     49 #include "chromeos/chromeos_switches.h"
     50 #include "chromeos/login/user_names.h"
     51 #include "chromeos/settings/cros_settings_names.h"
     52 #include "components/session_manager/core/session_manager.h"
     53 #include "components/user_manager/remove_user_delegate.h"
     54 #include "components/user_manager/user_image/user_image.h"
     55 #include "components/user_manager/user_type.h"
     56 #include "content/public/browser/browser_thread.h"
     57 #include "content/public/browser/notification_service.h"
     58 #include "policy/policy_constants.h"
     59 #include "ui/base/resource/resource_bundle.h"
     60 #include "ui/wm/core/wm_core_switches.h"
     61 
     62 using content::BrowserThread;
     63 
     64 namespace chromeos {
     65 namespace {
     66 
     67 // A vector pref of the the regular users known on this device, arranged in LRU
     68 // order.
     69 const char kRegularUsers[] = "LoggedInUsers";
     70 
     71 // A vector pref of the public accounts defined on this device.
     72 const char kPublicAccounts[] = "PublicAccounts";
     73 
     74 // A string pref that gets set when a public account is removed but a user is
     75 // currently logged into that account, requiring the account's data to be
     76 // removed after logout.
     77 const char kPublicAccountPendingDataRemoval[] =
     78     "PublicAccountPendingDataRemoval";
     79 
     80 }  // namespace
     81 
     82 // static
     83 void ChromeUserManagerImpl::RegisterPrefs(PrefRegistrySimple* registry) {
     84   ChromeUserManager::RegisterPrefs(registry);
     85 
     86   registry->RegisterListPref(kPublicAccounts);
     87   registry->RegisterStringPref(kPublicAccountPendingDataRemoval, std::string());
     88   SupervisedUserManager::RegisterPrefs(registry);
     89   SessionLengthLimiter::RegisterPrefs(registry);
     90 }
     91 
     92 // static
     93 scoped_ptr<ChromeUserManager> ChromeUserManagerImpl::CreateChromeUserManager() {
     94   return scoped_ptr<ChromeUserManager>(new ChromeUserManagerImpl());
     95 }
     96 
     97 ChromeUserManagerImpl::ChromeUserManagerImpl()
     98     : ChromeUserManager(base::ThreadTaskRunnerHandle::Get(),
     99                         BrowserThread::GetBlockingPool()),
    100       cros_settings_(CrosSettings::Get()),
    101       device_local_account_policy_service_(NULL),
    102       supervised_user_manager_(new SupervisedUserManagerImpl(this)),
    103       weak_factory_(this) {
    104   UpdateNumberOfUsers();
    105 
    106   // UserManager instance should be used only on UI thread.
    107   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    108   registrar_.Add(this,
    109                  chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
    110                  content::NotificationService::AllSources());
    111   registrar_.Add(this,
    112                  chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
    113                  content::NotificationService::AllSources());
    114   registrar_.Add(this,
    115                  chrome::NOTIFICATION_PROFILE_CREATED,
    116                  content::NotificationService::AllSources());
    117 
    118   // Since we're in ctor postpone any actions till this is fully created.
    119   if (base::MessageLoop::current()) {
    120     base::MessageLoop::current()->PostTask(
    121         FROM_HERE,
    122         base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies,
    123                    weak_factory_.GetWeakPtr()));
    124   }
    125 
    126   local_accounts_subscription_ = cros_settings_->AddSettingsObserver(
    127       kAccountsPrefDeviceLocalAccounts,
    128       base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies,
    129                  weak_factory_.GetWeakPtr()));
    130   multi_profile_user_controller_.reset(
    131       new MultiProfileUserController(this, GetLocalState()));
    132 
    133   policy::BrowserPolicyConnectorChromeOS* connector =
    134       g_browser_process->platform_part()->browser_policy_connector_chromeos();
    135   avatar_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
    136       cros_settings_,
    137       connector->GetDeviceLocalAccountPolicyService(),
    138       policy::key::kUserAvatarImage,
    139       this));
    140   avatar_policy_observer_->Init();
    141 
    142   wallpaper_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
    143       cros_settings_,
    144       connector->GetDeviceLocalAccountPolicyService(),
    145       policy::key::kWallpaperImage,
    146       this));
    147   wallpaper_policy_observer_->Init();
    148 }
    149 
    150 ChromeUserManagerImpl::~ChromeUserManagerImpl() {
    151 }
    152 
    153 void ChromeUserManagerImpl::Shutdown() {
    154   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    155   ChromeUserManager::Shutdown();
    156 
    157   local_accounts_subscription_.reset();
    158 
    159   // Stop the session length limiter.
    160   session_length_limiter_.reset();
    161 
    162   if (device_local_account_policy_service_)
    163     device_local_account_policy_service_->RemoveObserver(this);
    164 
    165   for (UserImageManagerMap::iterator it = user_image_managers_.begin(),
    166                                      ie = user_image_managers_.end();
    167        it != ie;
    168        ++it) {
    169     it->second->Shutdown();
    170   }
    171   multi_profile_user_controller_.reset();
    172   avatar_policy_observer_.reset();
    173   wallpaper_policy_observer_.reset();
    174   registrar_.RemoveAll();
    175 }
    176 
    177 MultiProfileUserController*
    178 ChromeUserManagerImpl::GetMultiProfileUserController() {
    179   return multi_profile_user_controller_.get();
    180 }
    181 
    182 UserImageManager* ChromeUserManagerImpl::GetUserImageManager(
    183     const std::string& user_id) {
    184   UserImageManagerMap::iterator ui = user_image_managers_.find(user_id);
    185   if (ui != user_image_managers_.end())
    186     return ui->second.get();
    187   linked_ptr<UserImageManagerImpl> mgr(new UserImageManagerImpl(user_id, this));
    188   user_image_managers_[user_id] = mgr;
    189   return mgr.get();
    190 }
    191 
    192 SupervisedUserManager* ChromeUserManagerImpl::GetSupervisedUserManager() {
    193   return supervised_user_manager_.get();
    194 }
    195 
    196 user_manager::UserList ChromeUserManagerImpl::GetUsersAdmittedForMultiProfile()
    197     const {
    198   // Supervised users are not allowed to use multi-profiles.
    199   if (GetLoggedInUsers().size() == 1 &&
    200       GetPrimaryUser()->GetType() != user_manager::USER_TYPE_REGULAR) {
    201     return user_manager::UserList();
    202   }
    203 
    204   user_manager::UserList result;
    205   const user_manager::UserList& users = GetUsers();
    206   for (user_manager::UserList::const_iterator it = users.begin();
    207        it != users.end();
    208        ++it) {
    209     if ((*it)->GetType() == user_manager::USER_TYPE_REGULAR &&
    210         !(*it)->is_logged_in()) {
    211       MultiProfileUserController::UserAllowedInSessionReason check;
    212       multi_profile_user_controller_->IsUserAllowedInSession((*it)->email(),
    213                                                              &check);
    214       if (check ==
    215           MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS) {
    216         return user_manager::UserList();
    217       }
    218 
    219       // Users with a policy that prevents them being added to a session will be
    220       // shown in login UI but will be grayed out.
    221       // Same applies to owner account (see http://crbug.com/385034).
    222       result.push_back(*it);
    223     }
    224   }
    225 
    226   return result;
    227 }
    228 
    229 user_manager::UserList ChromeUserManagerImpl::GetUnlockUsers() const {
    230   const user_manager::UserList& logged_in_users = GetLoggedInUsers();
    231   if (logged_in_users.empty())
    232     return user_manager::UserList();
    233 
    234   user_manager::UserList unlock_users;
    235   Profile* profile =
    236       ProfileHelper::Get()->GetProfileByUserUnsafe(GetPrimaryUser());
    237   std::string primary_behavior =
    238       profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
    239 
    240   // Specific case: only one logged in user or
    241   // primary user has primary-only multi-profile policy.
    242   if (logged_in_users.size() == 1 ||
    243       primary_behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
    244     if (GetPrimaryUser()->can_lock())
    245       unlock_users.push_back(primary_user_);
    246   } else {
    247     // Fill list of potential unlock users based on multi-profile policy state.
    248     for (user_manager::UserList::const_iterator it = logged_in_users.begin();
    249          it != logged_in_users.end();
    250          ++it) {
    251       user_manager::User* user = (*it);
    252       Profile* profile = ProfileHelper::Get()->GetProfileByUserUnsafe(user);
    253       const std::string behavior =
    254           profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
    255       if (behavior == MultiProfileUserController::kBehaviorUnrestricted &&
    256           user->can_lock()) {
    257         unlock_users.push_back(user);
    258       } else if (behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
    259         NOTREACHED()
    260             << "Spotted primary-only multi-profile policy for non-primary user";
    261       }
    262     }
    263   }
    264 
    265   return unlock_users;
    266 }
    267 
    268 void ChromeUserManagerImpl::SessionStarted() {
    269   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    270   ChromeUserManager::SessionStarted();
    271 
    272   content::NotificationService::current()->Notify(
    273       chrome::NOTIFICATION_SESSION_STARTED,
    274       content::Source<UserManager>(this),
    275       content::Details<const user_manager::User>(GetActiveUser()));
    276 }
    277 
    278 void ChromeUserManagerImpl::RemoveUserInternal(
    279     const std::string& user_email,
    280     user_manager::RemoveUserDelegate* delegate) {
    281   CrosSettings* cros_settings = CrosSettings::Get();
    282 
    283   const base::Closure& callback =
    284       base::Bind(&ChromeUserManagerImpl::RemoveUserInternal,
    285                  weak_factory_.GetWeakPtr(),
    286                  user_email,
    287                  delegate);
    288 
    289   // Ensure the value of owner email has been fetched.
    290   if (CrosSettingsProvider::TRUSTED !=
    291       cros_settings->PrepareTrustedValues(callback)) {
    292     // Value of owner email is not fetched yet.  RemoveUserInternal will be
    293     // called again after fetch completion.
    294     return;
    295   }
    296   std::string owner;
    297   cros_settings->GetString(kDeviceOwner, &owner);
    298   if (user_email == owner) {
    299     // Owner is not allowed to be removed from the device.
    300     return;
    301   }
    302   RemoveNonOwnerUserInternal(user_email, delegate);
    303 }
    304 
    305 void ChromeUserManagerImpl::SaveUserOAuthStatus(
    306     const std::string& user_id,
    307     user_manager::User::OAuthTokenStatus oauth_token_status) {
    308   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    309   ChromeUserManager::SaveUserOAuthStatus(user_id, oauth_token_status);
    310 
    311   GetUserFlow(user_id)->HandleOAuthTokenStatusChange(oauth_token_status);
    312 }
    313 
    314 void ChromeUserManagerImpl::SaveUserDisplayName(
    315     const std::string& user_id,
    316     const base::string16& display_name) {
    317   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    318   ChromeUserManager::SaveUserDisplayName(user_id, display_name);
    319 
    320   // Do not update local state if data stored or cached outside the user's
    321   // cryptohome is to be treated as ephemeral.
    322   if (!IsUserNonCryptohomeDataEphemeral(user_id))
    323     supervised_user_manager_->UpdateManagerName(user_id, display_name);
    324 }
    325 
    326 void ChromeUserManagerImpl::StopPolicyObserverForTesting() {
    327   avatar_policy_observer_.reset();
    328   wallpaper_policy_observer_.reset();
    329 }
    330 
    331 void ChromeUserManagerImpl::Observe(
    332     int type,
    333     const content::NotificationSource& source,
    334     const content::NotificationDetails& details) {
    335   switch (type) {
    336     case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED:
    337       if (!device_local_account_policy_service_) {
    338         policy::BrowserPolicyConnectorChromeOS* connector =
    339             g_browser_process->platform_part()
    340                 ->browser_policy_connector_chromeos();
    341         device_local_account_policy_service_ =
    342             connector->GetDeviceLocalAccountPolicyService();
    343         if (device_local_account_policy_service_)
    344           device_local_account_policy_service_->AddObserver(this);
    345       }
    346       RetrieveTrustedDevicePolicies();
    347       UpdateOwnership();
    348       break;
    349     case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: {
    350       Profile* profile = content::Details<Profile>(details).ptr();
    351       if (IsUserLoggedIn() && !IsLoggedInAsGuest() && !IsLoggedInAsKioskApp()) {
    352         if (IsLoggedInAsSupervisedUser())
    353           SupervisedUserPasswordServiceFactory::GetForProfile(profile);
    354         if (IsLoggedInAsRegularUser())
    355           ManagerPasswordServiceFactory::GetForProfile(profile);
    356 
    357         if (!profile->IsOffTheRecord()) {
    358           AuthSyncObserver* sync_observer =
    359               AuthSyncObserverFactory::GetInstance()->GetForProfile(profile);
    360           sync_observer->StartObserving();
    361           multi_profile_user_controller_->StartObserving(profile);
    362         }
    363       }
    364       break;
    365     }
    366     case chrome::NOTIFICATION_PROFILE_CREATED: {
    367       Profile* profile = content::Source<Profile>(source).ptr();
    368       user_manager::User* user =
    369           ProfileHelper::Get()->GetUserByProfile(profile);
    370       if (user != NULL)
    371         user->set_profile_is_created();
    372 
    373       // If there is pending user switch, do it now.
    374       if (!GetPendingUserSwitchID().empty()) {
    375         // Call SwitchActiveUser async because otherwise it may cause
    376         // ProfileManager::GetProfile before the profile gets registered
    377         // in ProfileManager. It happens in case of sync profile load when
    378         // NOTIFICATION_PROFILE_CREATED is called synchronously.
    379         base::MessageLoop::current()->PostTask(
    380             FROM_HERE,
    381             base::Bind(&ChromeUserManagerImpl::SwitchActiveUser,
    382                        weak_factory_.GetWeakPtr(),
    383                        GetPendingUserSwitchID()));
    384         SetPendingUserSwitchID(std::string());
    385       }
    386       break;
    387     }
    388     default:
    389       NOTREACHED();
    390   }
    391 }
    392 
    393 void ChromeUserManagerImpl::OnExternalDataSet(const std::string& policy,
    394                                               const std::string& user_id) {
    395   if (policy == policy::key::kUserAvatarImage)
    396     GetUserImageManager(user_id)->OnExternalDataSet(policy);
    397   else if (policy == policy::key::kWallpaperImage)
    398     WallpaperManager::Get()->OnPolicySet(policy, user_id);
    399   else
    400     NOTREACHED();
    401 }
    402 
    403 void ChromeUserManagerImpl::OnExternalDataCleared(const std::string& policy,
    404                                                   const std::string& user_id) {
    405   if (policy == policy::key::kUserAvatarImage)
    406     GetUserImageManager(user_id)->OnExternalDataCleared(policy);
    407   else if (policy == policy::key::kWallpaperImage)
    408     WallpaperManager::Get()->OnPolicyCleared(policy, user_id);
    409   else
    410     NOTREACHED();
    411 }
    412 
    413 void ChromeUserManagerImpl::OnExternalDataFetched(
    414     const std::string& policy,
    415     const std::string& user_id,
    416     scoped_ptr<std::string> data) {
    417   if (policy == policy::key::kUserAvatarImage)
    418     GetUserImageManager(user_id)->OnExternalDataFetched(policy, data.Pass());
    419   else if (policy == policy::key::kWallpaperImage)
    420     WallpaperManager::Get()->OnPolicyFetched(policy, user_id, data.Pass());
    421   else
    422     NOTREACHED();
    423 }
    424 
    425 void ChromeUserManagerImpl::OnPolicyUpdated(const std::string& user_id) {
    426   const user_manager::User* user = FindUser(user_id);
    427   if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
    428     return;
    429   UpdatePublicAccountDisplayName(user_id);
    430 }
    431 
    432 void ChromeUserManagerImpl::OnDeviceLocalAccountsChanged() {
    433   // No action needed here, changes to the list of device-local accounts get
    434   // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
    435 }
    436 
    437 bool ChromeUserManagerImpl::CanCurrentUserLock() const {
    438   return ChromeUserManager::CanCurrentUserLock() &&
    439          GetCurrentUserFlow()->CanLockScreen();
    440 }
    441 
    442 bool ChromeUserManagerImpl::IsUserNonCryptohomeDataEphemeral(
    443     const std::string& user_id) const {
    444   // Data belonging to the obsolete public accounts whose data has not been
    445   // removed yet is not ephemeral.
    446   bool is_obsolete_public_account = IsPublicAccountMarkedForRemoval(user_id);
    447 
    448   return !is_obsolete_public_account &&
    449          ChromeUserManager::IsUserNonCryptohomeDataEphemeral(user_id);
    450 }
    451 
    452 bool ChromeUserManagerImpl::AreEphemeralUsersEnabled() const {
    453   policy::BrowserPolicyConnectorChromeOS* connector =
    454       g_browser_process->platform_part()->browser_policy_connector_chromeos();
    455   return GetEphemeralUsersEnabled() &&
    456          (connector->IsEnterpriseManaged() || !GetOwnerEmail().empty());
    457 }
    458 
    459 const std::string& ChromeUserManagerImpl::GetApplicationLocale() const {
    460   return g_browser_process->GetApplicationLocale();
    461 }
    462 
    463 PrefService* ChromeUserManagerImpl::GetLocalState() const {
    464   return g_browser_process ? g_browser_process->local_state() : NULL;
    465 }
    466 
    467 void ChromeUserManagerImpl::HandleUserOAuthTokenStatusChange(
    468     const std::string& user_id,
    469     user_manager::User::OAuthTokenStatus status) const {
    470   GetUserFlow(user_id)->HandleOAuthTokenStatusChange(status);
    471 }
    472 
    473 bool ChromeUserManagerImpl::IsEnterpriseManaged() const {
    474   policy::BrowserPolicyConnectorChromeOS* connector =
    475       g_browser_process->platform_part()->browser_policy_connector_chromeos();
    476   return connector->IsEnterpriseManaged();
    477 }
    478 
    479 void ChromeUserManagerImpl::LoadPublicAccounts(
    480     std::set<std::string>* public_sessions_set) {
    481   const base::ListValue* prefs_public_sessions =
    482       GetLocalState()->GetList(kPublicAccounts);
    483   std::vector<std::string> public_sessions;
    484   ParseUserList(*prefs_public_sessions,
    485                 std::set<std::string>(),
    486                 &public_sessions,
    487                 public_sessions_set);
    488   for (std::vector<std::string>::const_iterator it = public_sessions.begin();
    489        it != public_sessions.end();
    490        ++it) {
    491     users_.push_back(user_manager::User::CreatePublicAccountUser(*it));
    492     UpdatePublicAccountDisplayName(*it);
    493   }
    494 }
    495 
    496 void ChromeUserManagerImpl::PerformPreUserListLoadingActions() {
    497   // Clean up user list first. All code down the path should be synchronous,
    498   // so that local state after transaction rollback is in consistent state.
    499   // This process also should not trigger EnsureUsersLoaded again.
    500   if (supervised_user_manager_->HasFailedUserCreationTransaction())
    501     supervised_user_manager_->RollbackUserCreationTransaction();
    502 }
    503 
    504 void ChromeUserManagerImpl::PerformPostUserListLoadingActions() {
    505   for (user_manager::UserList::iterator ui = users_.begin(), ue = users_.end();
    506        ui != ue;
    507        ++ui) {
    508     GetUserImageManager((*ui)->email())->LoadUserImage();
    509   }
    510 }
    511 
    512 void ChromeUserManagerImpl::PerformPostUserLoggedInActions(
    513     bool browser_restart) {
    514   // Initialize the session length limiter and start it only if
    515   // session limit is defined by the policy.
    516   session_length_limiter_.reset(
    517       new SessionLengthLimiter(NULL, browser_restart));
    518 }
    519 
    520 bool ChromeUserManagerImpl::IsDemoApp(const std::string& user_id) const {
    521   return DemoAppLauncher::IsDemoAppSession(user_id);
    522 }
    523 
    524 bool ChromeUserManagerImpl::IsKioskApp(const std::string& user_id) const {
    525   policy::DeviceLocalAccount::Type device_local_account_type;
    526   return policy::IsDeviceLocalAccountUser(user_id,
    527                                           &device_local_account_type) &&
    528          device_local_account_type ==
    529              policy::DeviceLocalAccount::TYPE_KIOSK_APP;
    530 }
    531 
    532 bool ChromeUserManagerImpl::IsPublicAccountMarkedForRemoval(
    533     const std::string& user_id) const {
    534   return user_id ==
    535          GetLocalState()->GetString(kPublicAccountPendingDataRemoval);
    536 }
    537 
    538 void ChromeUserManagerImpl::RetrieveTrustedDevicePolicies() {
    539   // Local state may not be initialized in unit_tests.
    540   if (!GetLocalState())
    541     return;
    542 
    543   SetEphemeralUsersEnabled(false);
    544   SetOwnerEmail(std::string());
    545 
    546   // Schedule a callback if device policy has not yet been verified.
    547   if (CrosSettingsProvider::TRUSTED !=
    548       cros_settings_->PrepareTrustedValues(
    549           base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies,
    550                      weak_factory_.GetWeakPtr()))) {
    551     return;
    552   }
    553 
    554   bool ephemeral_users_enabled = false;
    555   cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
    556                              &ephemeral_users_enabled);
    557   SetEphemeralUsersEnabled(ephemeral_users_enabled);
    558 
    559   std::string owner_email;
    560   cros_settings_->GetString(kDeviceOwner, &owner_email);
    561   SetOwnerEmail(owner_email);
    562 
    563   EnsureUsersLoaded();
    564 
    565   bool changed = UpdateAndCleanUpPublicAccounts(
    566       policy::GetDeviceLocalAccounts(cros_settings_));
    567 
    568   // If ephemeral users are enabled and we are on the login screen, take this
    569   // opportunity to clean up by removing all regular users except the owner.
    570   if (GetEphemeralUsersEnabled() && !IsUserLoggedIn()) {
    571     ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
    572     prefs_users_update->Clear();
    573     for (user_manager::UserList::iterator it = users_.begin();
    574          it != users_.end();) {
    575       const std::string user_email = (*it)->email();
    576       if ((*it)->GetType() == user_manager::USER_TYPE_REGULAR &&
    577           user_email != GetOwnerEmail()) {
    578         RemoveNonCryptohomeData(user_email);
    579         DeleteUser(*it);
    580         it = users_.erase(it);
    581         changed = true;
    582       } else {
    583         if ((*it)->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
    584           prefs_users_update->Append(new base::StringValue(user_email));
    585         ++it;
    586       }
    587     }
    588   }
    589 
    590   if (changed)
    591     NotifyUserListChanged();
    592 }
    593 
    594 void ChromeUserManagerImpl::GuestUserLoggedIn() {
    595   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    596   ChromeUserManager::GuestUserLoggedIn();
    597 
    598   // TODO(nkostylev): Add support for passing guest session cryptohome
    599   // mount point. Legacy (--login-profile) value will be used for now.
    600   // http://crosbug.com/230859
    601   active_user_->SetStubImage(
    602       user_manager::UserImage(
    603           *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
    604               IDR_PROFILE_PICTURE_LOADING)),
    605       user_manager::User::USER_IMAGE_INVALID,
    606       false);
    607 
    608   // Initializes wallpaper after active_user_ is set.
    609   WallpaperManager::Get()->SetUserWallpaperNow(chromeos::login::kGuestUserName);
    610 }
    611 
    612 void ChromeUserManagerImpl::RegularUserLoggedIn(const std::string& user_id) {
    613   ChromeUserManager::RegularUserLoggedIn(user_id);
    614 
    615   if (IsCurrentUserNew())
    616     WallpaperManager::Get()->SetUserWallpaperNow(user_id);
    617 
    618   GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), false);
    619 
    620   WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
    621 
    622   // Make sure that new data is persisted to Local State.
    623   GetLocalState()->CommitPendingWrite();
    624 }
    625 
    626 void ChromeUserManagerImpl::RegularUserLoggedInAsEphemeral(
    627     const std::string& user_id) {
    628   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    629   ChromeUserManager::RegularUserLoggedInAsEphemeral(user_id);
    630 
    631   GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), false);
    632   WallpaperManager::Get()->SetUserWallpaperNow(user_id);
    633 }
    634 
    635 void ChromeUserManagerImpl::SupervisedUserLoggedIn(const std::string& user_id) {
    636   // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
    637 
    638   // Remove the user from the user list.
    639   active_user_ = RemoveRegularOrSupervisedUserFromList(user_id);
    640 
    641   // If the user was not found on the user list, create a new user.
    642   if (!GetActiveUser()) {
    643     SetIsCurrentUserNew(true);
    644     active_user_ = user_manager::User::CreateSupervisedUser(user_id);
    645     // Leaving OAuth token status at the default state = unknown.
    646     WallpaperManager::Get()->SetUserWallpaperNow(user_id);
    647   } else {
    648     if (supervised_user_manager_->CheckForFirstRun(user_id)) {
    649       SetIsCurrentUserNew(true);
    650       WallpaperManager::Get()->SetUserWallpaperNow(user_id);
    651     } else {
    652       SetIsCurrentUserNew(false);
    653     }
    654   }
    655 
    656   // Add the user to the front of the user list.
    657   ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
    658   prefs_users_update->Insert(0, new base::StringValue(user_id));
    659   users_.insert(users_.begin(), active_user_);
    660 
    661   // Now that user is in the list, save display name.
    662   if (IsCurrentUserNew()) {
    663     SaveUserDisplayName(GetActiveUser()->email(),
    664                         GetActiveUser()->GetDisplayName());
    665   }
    666 
    667   GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), true);
    668   WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
    669 
    670   // Make sure that new data is persisted to Local State.
    671   GetLocalState()->CommitPendingWrite();
    672 }
    673 
    674 void ChromeUserManagerImpl::PublicAccountUserLoggedIn(
    675     user_manager::User* user) {
    676   SetIsCurrentUserNew(true);
    677   active_user_ = user;
    678 
    679   // The UserImageManager chooses a random avatar picture when a user logs in
    680   // for the first time. Tell the UserImageManager that this user is not new to
    681   // prevent the avatar from getting changed.
    682   GetUserImageManager(user->email())->UserLoggedIn(false, true);
    683   WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
    684 }
    685 
    686 void ChromeUserManagerImpl::KioskAppLoggedIn(const std::string& app_id) {
    687   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    688   policy::DeviceLocalAccount::Type device_local_account_type;
    689   DCHECK(policy::IsDeviceLocalAccountUser(app_id, &device_local_account_type));
    690   DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
    691             device_local_account_type);
    692 
    693   active_user_ = user_manager::User::CreateKioskAppUser(app_id);
    694   active_user_->SetStubImage(
    695       user_manager::UserImage(
    696           *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
    697               IDR_PROFILE_PICTURE_LOADING)),
    698       user_manager::User::USER_IMAGE_INVALID,
    699       false);
    700 
    701   WallpaperManager::Get()->SetUserWallpaperNow(app_id);
    702 
    703   // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
    704   // the kiosk_app_id in these objects, removing the need to re-parse the
    705   // device-local account list here to extract the kiosk_app_id.
    706   const std::vector<policy::DeviceLocalAccount> device_local_accounts =
    707       policy::GetDeviceLocalAccounts(cros_settings_);
    708   const policy::DeviceLocalAccount* account = NULL;
    709   for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
    710            device_local_accounts.begin();
    711        it != device_local_accounts.end();
    712        ++it) {
    713     if (it->user_id == app_id) {
    714       account = &*it;
    715       break;
    716     }
    717   }
    718   std::string kiosk_app_id;
    719   if (account) {
    720     kiosk_app_id = account->kiosk_app_id;
    721   } else {
    722     LOG(ERROR) << "Logged into nonexistent kiosk-app account: " << app_id;
    723     NOTREACHED();
    724   }
    725 
    726   CommandLine* command_line = CommandLine::ForCurrentProcess();
    727   command_line->AppendSwitch(::switches::kForceAppMode);
    728   command_line->AppendSwitchASCII(::switches::kAppId, kiosk_app_id);
    729 
    730   // Disable window animation since kiosk app runs in a single full screen
    731   // window and window animation causes start-up janks.
    732   command_line->AppendSwitch(wm::switches::kWindowAnimationsDisabled);
    733 }
    734 
    735 void ChromeUserManagerImpl::DemoAccountLoggedIn() {
    736   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    737   active_user_ =
    738       user_manager::User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName);
    739   active_user_->SetStubImage(
    740       user_manager::UserImage(
    741           *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
    742               IDR_PROFILE_PICTURE_LOADING)),
    743       user_manager::User::USER_IMAGE_INVALID,
    744       false);
    745   WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName);
    746 
    747   CommandLine* command_line = CommandLine::ForCurrentProcess();
    748   command_line->AppendSwitch(::switches::kForceAppMode);
    749   command_line->AppendSwitchASCII(::switches::kAppId,
    750                                   DemoAppLauncher::kDemoAppId);
    751 
    752   // Disable window animation since the demo app runs in a single full screen
    753   // window and window animation causes start-up janks.
    754   CommandLine::ForCurrentProcess()->AppendSwitch(
    755       wm::switches::kWindowAnimationsDisabled);
    756 }
    757 
    758 void ChromeUserManagerImpl::RetailModeUserLoggedIn() {
    759   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    760   SetIsCurrentUserNew(true);
    761   active_user_ = user_manager::User::CreateRetailModeUser();
    762   GetUserImageManager(chromeos::login::kRetailModeUserName)
    763       ->UserLoggedIn(IsCurrentUserNew(), true);
    764   WallpaperManager::Get()->SetUserWallpaperNow(
    765       chromeos::login::kRetailModeUserName);
    766 }
    767 
    768 void ChromeUserManagerImpl::NotifyOnLogin() {
    769   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    770 
    771   UserSessionManager::OverrideHomedir();
    772   UpdateNumberOfUsers();
    773 
    774   ChromeUserManager::NotifyOnLogin();
    775 
    776   // TODO(nkostylev): Deprecate this notification in favor of
    777   // ActiveUserChanged() observer call.
    778   content::NotificationService::current()->Notify(
    779       chrome::NOTIFICATION_LOGIN_USER_CHANGED,
    780       content::Source<UserManager>(this),
    781       content::Details<const user_manager::User>(GetActiveUser()));
    782 
    783   UserSessionManager::GetInstance()->PerformPostUserLoggedInActions();
    784 }
    785 
    786 void ChromeUserManagerImpl::UpdateOwnership() {
    787   bool is_owner = DeviceSettingsService::Get()->HasPrivateOwnerKey();
    788   VLOG(1) << "Current user " << (is_owner ? "is owner" : "is not owner");
    789 
    790   SetCurrentUserIsOwner(is_owner);
    791 }
    792 
    793 void ChromeUserManagerImpl::RemoveNonCryptohomeData(
    794     const std::string& user_id) {
    795   ChromeUserManager::RemoveNonCryptohomeData(user_id);
    796 
    797   WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id);
    798   GetUserImageManager(user_id)->DeleteUserImage();
    799 
    800   supervised_user_manager_->RemoveNonCryptohomeData(user_id);
    801 
    802   multi_profile_user_controller_->RemoveCachedValues(user_id);
    803 
    804   EasyUnlockService::ResetLocalStateForUser(user_id);
    805 }
    806 
    807 void
    808 ChromeUserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
    809   PrefService* local_state = GetLocalState();
    810   const std::string public_account_pending_data_removal =
    811       local_state->GetString(kPublicAccountPendingDataRemoval);
    812   if (public_account_pending_data_removal.empty() ||
    813       (IsUserLoggedIn() &&
    814        public_account_pending_data_removal == GetActiveUser()->email())) {
    815     return;
    816   }
    817 
    818   RemoveNonCryptohomeData(public_account_pending_data_removal);
    819   local_state->ClearPref(kPublicAccountPendingDataRemoval);
    820 }
    821 
    822 void ChromeUserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
    823     const std::vector<std::string>& old_public_accounts) {
    824   std::set<std::string> users;
    825   for (user_manager::UserList::const_iterator it = users_.begin();
    826        it != users_.end();
    827        ++it)
    828     users.insert((*it)->email());
    829 
    830   // If the user is logged into a public account that has been removed from the
    831   // user list, mark the account's data as pending removal after logout.
    832   if (IsLoggedInAsPublicAccount()) {
    833     const std::string active_user_id = GetActiveUser()->email();
    834     if (users.find(active_user_id) == users.end()) {
    835       GetLocalState()->SetString(kPublicAccountPendingDataRemoval,
    836                                  active_user_id);
    837       users.insert(active_user_id);
    838     }
    839   }
    840 
    841   // Remove the data belonging to any other public accounts that are no longer
    842   // found on the user list.
    843   for (std::vector<std::string>::const_iterator it =
    844            old_public_accounts.begin();
    845        it != old_public_accounts.end();
    846        ++it) {
    847     if (users.find(*it) == users.end())
    848       RemoveNonCryptohomeData(*it);
    849   }
    850 }
    851 
    852 bool ChromeUserManagerImpl::UpdateAndCleanUpPublicAccounts(
    853     const std::vector<policy::DeviceLocalAccount>& device_local_accounts) {
    854   // Try to remove any public account data marked as pending removal.
    855   CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
    856 
    857   // Get the current list of public accounts.
    858   std::vector<std::string> old_public_accounts;
    859   for (user_manager::UserList::const_iterator it = users_.begin();
    860        it != users_.end();
    861        ++it) {
    862     if ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT)
    863       old_public_accounts.push_back((*it)->email());
    864   }
    865 
    866   // Get the new list of public accounts from policy.
    867   std::vector<std::string> new_public_accounts;
    868   for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
    869            device_local_accounts.begin();
    870        it != device_local_accounts.end();
    871        ++it) {
    872     // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
    873     // standard login framework: http://crbug.com/234694
    874     if (it->type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
    875       new_public_accounts.push_back(it->user_id);
    876   }
    877 
    878   // If the list of public accounts has not changed, return.
    879   if (new_public_accounts.size() == old_public_accounts.size()) {
    880     bool changed = false;
    881     for (size_t i = 0; i < new_public_accounts.size(); ++i) {
    882       if (new_public_accounts[i] != old_public_accounts[i]) {
    883         changed = true;
    884         break;
    885       }
    886     }
    887     if (!changed)
    888       return false;
    889   }
    890 
    891   // Persist the new list of public accounts in a pref.
    892   ListPrefUpdate prefs_public_accounts_update(GetLocalState(), kPublicAccounts);
    893   prefs_public_accounts_update->Clear();
    894   for (std::vector<std::string>::const_iterator it =
    895            new_public_accounts.begin();
    896        it != new_public_accounts.end();
    897        ++it) {
    898     prefs_public_accounts_update->AppendString(*it);
    899   }
    900 
    901   // Remove the old public accounts from the user list.
    902   for (user_manager::UserList::iterator it = users_.begin();
    903        it != users_.end();) {
    904     if ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
    905       if (*it != GetLoggedInUser())
    906         DeleteUser(*it);
    907       it = users_.erase(it);
    908     } else {
    909       ++it;
    910     }
    911   }
    912 
    913   // Add the new public accounts to the front of the user list.
    914   for (std::vector<std::string>::const_reverse_iterator it =
    915            new_public_accounts.rbegin();
    916        it != new_public_accounts.rend();
    917        ++it) {
    918     if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email())
    919       users_.insert(users_.begin(), GetLoggedInUser());
    920     else
    921       users_.insert(users_.begin(),
    922                     user_manager::User::CreatePublicAccountUser(*it));
    923     UpdatePublicAccountDisplayName(*it);
    924   }
    925 
    926   for (user_manager::UserList::iterator
    927            ui = users_.begin(),
    928            ue = users_.begin() + new_public_accounts.size();
    929        ui != ue;
    930        ++ui) {
    931     GetUserImageManager((*ui)->email())->LoadUserImage();
    932   }
    933 
    934   // Remove data belonging to public accounts that are no longer found on the
    935   // user list.
    936   CleanUpPublicAccountNonCryptohomeData(old_public_accounts);
    937 
    938   return true;
    939 }
    940 
    941 void ChromeUserManagerImpl::UpdatePublicAccountDisplayName(
    942     const std::string& user_id) {
    943   std::string display_name;
    944 
    945   if (device_local_account_policy_service_) {
    946     policy::DeviceLocalAccountPolicyBroker* broker =
    947         device_local_account_policy_service_->GetBrokerForUser(user_id);
    948     if (broker)
    949       display_name = broker->GetDisplayName();
    950   }
    951 
    952   // Set or clear the display name.
    953   SaveUserDisplayName(user_id, base::UTF8ToUTF16(display_name));
    954 }
    955 
    956 UserFlow* ChromeUserManagerImpl::GetCurrentUserFlow() const {
    957   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    958   if (!IsUserLoggedIn())
    959     return GetDefaultUserFlow();
    960   return GetUserFlow(GetLoggedInUser()->email());
    961 }
    962 
    963 UserFlow* ChromeUserManagerImpl::GetUserFlow(const std::string& user_id) const {
    964   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    965   FlowMap::const_iterator it = specific_flows_.find(user_id);
    966   if (it != specific_flows_.end())
    967     return it->second;
    968   return GetDefaultUserFlow();
    969 }
    970 
    971 void ChromeUserManagerImpl::SetUserFlow(const std::string& user_id,
    972                                         UserFlow* flow) {
    973   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    974   ResetUserFlow(user_id);
    975   specific_flows_[user_id] = flow;
    976 }
    977 
    978 void ChromeUserManagerImpl::ResetUserFlow(const std::string& user_id) {
    979   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    980   FlowMap::iterator it = specific_flows_.find(user_id);
    981   if (it != specific_flows_.end()) {
    982     delete it->second;
    983     specific_flows_.erase(it);
    984   }
    985 }
    986 
    987 bool ChromeUserManagerImpl::AreSupervisedUsersAllowed() const {
    988   bool supervised_users_allowed = false;
    989   cros_settings_->GetBoolean(kAccountsPrefSupervisedUsersEnabled,
    990                              &supervised_users_allowed);
    991   return supervised_users_allowed;
    992 }
    993 
    994 UserFlow* ChromeUserManagerImpl::GetDefaultUserFlow() const {
    995   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    996   if (!default_flow_.get())
    997     default_flow_.reset(new DefaultUserFlow());
    998   return default_flow_.get();
    999 }
   1000 
   1001 void ChromeUserManagerImpl::NotifyUserListChanged() {
   1002   content::NotificationService::current()->Notify(
   1003       chrome::NOTIFICATION_USER_LIST_CHANGED,
   1004       content::Source<UserManager>(this),
   1005       content::NotificationService::NoDetails());
   1006 }
   1007 
   1008 void ChromeUserManagerImpl::NotifyUserAddedToSession(
   1009     const user_manager::User* added_user,
   1010     bool user_switch_pending) {
   1011   // Special case for user session restoration after browser crash.
   1012   // We don't switch to each user session that has been restored as once all
   1013   // session will be restored we'll switch to the session that has been used
   1014   // before the crash.
   1015   if (user_switch_pending &&
   1016       !UserSessionManager::GetInstance()->UserSessionsRestoreInProgress()) {
   1017     SetPendingUserSwitchID(added_user->email());
   1018   }
   1019 
   1020   UpdateNumberOfUsers();
   1021   ChromeUserManager::NotifyUserAddedToSession(added_user, user_switch_pending);
   1022 }
   1023 
   1024 void ChromeUserManagerImpl::OnUserNotAllowed(const std::string& user_email) {
   1025   LOG(ERROR) << "Shutdown session because a user is not allowed to be in the "
   1026                 "current session";
   1027   chromeos::ShowMultiprofilesSessionAbortedDialog(user_email);
   1028 }
   1029 
   1030 void ChromeUserManagerImpl::UpdateNumberOfUsers() {
   1031   size_t users = GetLoggedInUsers().size();
   1032   if (users) {
   1033     // Write the user number as UMA stat when a multi user session is possible.
   1034     if ((users + GetUsersAdmittedForMultiProfile().size()) > 1)
   1035       ash::MultiProfileUMA::RecordUserCount(users);
   1036   }
   1037 
   1038   base::debug::SetCrashKeyValue(
   1039       crash_keys::kNumberOfUsers,
   1040       base::StringPrintf("%" PRIuS, GetLoggedInUsers().size()));
   1041 }
   1042 
   1043 }  // namespace chromeos
   1044