15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager_base.h"
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <cstddef>
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <set>
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/bind.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/bind_helpers.h"
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/command_line.h"
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/compiler_specific.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/format_macros.h"
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/location.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/logging.h"
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/macros.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/metrics/histogram.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/prefs/pref_service.h"
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h"
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/strings/string_util.h"
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/strings/stringprintf.h"
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/task_runner.h"
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/values.h"
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chromeos/chromeos_switches.h"
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chromeos/cryptohome/async_method_caller.h"
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chromeos/login/login_state.h"
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chromeos/login/user_names.h"
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/session_manager/core/session_manager.h"
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/remove_user_delegate.h"
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/user_manager/user_type.h"
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h"
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace user_manager {
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A vector pref of the the regular users known on this device, arranged in LRU
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// order.
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kRegularUsers[] = "LoggedInUsers";
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A dictionary that maps user IDs to the displayed name.
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kUserDisplayName[] = "UserDisplayName";
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A dictionary that maps user IDs to the user's given name.
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kUserGivenName[] = "UserGivenName";
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A dictionary that maps user IDs to the displayed (non-canonical) emails.
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kUserDisplayEmail[] = "UserDisplayEmail";
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A dictionary that maps user IDs to OAuth token presence flag.
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kUserOAuthTokenStatus[] = "OAuthTokenStatus";
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A dictionary that maps user IDs to a flag indicating whether online
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// authentication against GAIA should be enforced during the next sign-in.
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kUserForceOnlineSignin[] = "UserForceOnlineSignin";
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A string pref containing the ID of the last user who logged in if it was
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// a regular user or an empty string if it was another type of user (guest,
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// kiosk, public account, etc.).
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kLastLoggedInRegularUser[] = "LastLoggedInRegularUser";
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// A string pref containing the ID of the last active user.
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// In case of browser crash, this pref will be used to set active user after
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// session restore.
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kLastActiveUser[] = "LastActiveUser";
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Upper bound for a histogram metric reporting the amount of time between
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// one regular user logging out and a different regular user logging in.
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kLogoutToLoginDelayMaxSec = 1800;
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Callback that is called after user removal is complete.
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void OnRemoveUserComplete(const std::string& user_email,
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          bool success,
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          cryptohome::MountError return_code) {
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Log the error, but there's not much we can do.
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!success) {
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LOG(ERROR) << "Removal of cryptohome for " << user_email
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               << " failed, return code: " << return_code;
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Runs on SequencedWorkerPool thread. Passes resolved locale to UI thread.
8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ResolveLocale(const std::string& raw_locale,
8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   std::string* resolved_locale) {
8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ignore_result(l10n_util::CheckAndResolveLocale(raw_locale, resolved_locale));
8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::RegisterPrefs(PrefRegistrySimple* registry) {
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registry->RegisterListPref(kRegularUsers);
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registry->RegisterStringPref(kLastLoggedInRegularUser, std::string());
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registry->RegisterDictionaryPref(kUserDisplayName);
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registry->RegisterDictionaryPref(kUserGivenName);
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registry->RegisterDictionaryPref(kUserDisplayEmail);
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registry->RegisterDictionaryPref(kUserOAuthTokenStatus);
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registry->RegisterDictionaryPref(kUserForceOnlineSignin);
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  registry->RegisterStringPref(kLastActiveUser, std::string());
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)UserManagerBase::UserManagerBase(
1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_refptr<base::TaskRunner> task_runner,
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_refptr<base::TaskRunner> blocking_task_runner)
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : active_user_(NULL),
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      primary_user_(NULL),
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      user_loading_stage_(STAGE_NOT_LOADED),
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      session_started_(false),
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      is_current_user_owner_(false),
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      is_current_user_new_(false),
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      is_current_user_ephemeral_regular_user_(false),
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ephemeral_users_enabled_(false),
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      manager_creation_time_(base::TimeTicks::Now()),
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      last_session_active_user_initialized_(false),
1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      task_runner_(task_runner),
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      blocking_task_runner_(blocking_task_runner),
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      weak_factory_(this) {
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UpdateLoginState();
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)UserManagerBase::~UserManagerBase() {
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Can't use STLDeleteElements because of the private destructor of User.
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (UserList::iterator it = users_.begin(); it != users_.end();
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       it = users_.erase(it)) {
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DeleteUser(*it);
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // These are pointers to the same User instances that were in users_ list.
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  logged_in_users_.clear();
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  lru_logged_in_users_.clear();
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DeleteUser(active_user_);
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::Shutdown() {
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const UserList& UserManagerBase::GetUsers() const {
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const_cast<UserManagerBase*>(this)->EnsureUsersLoaded();
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return users_;
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const UserList& UserManagerBase::GetLoggedInUsers() const {
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return logged_in_users_;
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const UserList& UserManagerBase::GetLRULoggedInUsers() const {
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return lru_logged_in_users_;
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const std::string& UserManagerBase::GetOwnerEmail() const {
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return owner_email_;
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::UserLoggedIn(const std::string& user_id,
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   const std::string& username_hash,
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   bool browser_restart) {
1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!last_session_active_user_initialized_) {
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    last_session_active_user_ = GetLocalState()->GetString(kLastActiveUser);
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    last_session_active_user_initialized_ = true;
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  User* user = FindUserInListAndModify(user_id);
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (active_user_ && user) {
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    user->set_is_logged_in(true);
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    user->set_username_hash(username_hash);
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    logged_in_users_.push_back(user);
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    lru_logged_in_users_.push_back(user);
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Reset the new user flag if the user already exists.
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    SetIsCurrentUserNew(false);
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NotifyUserAddedToSession(user, true /* user switch pending */);
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (user_id == chromeos::login::kGuestUserName) {
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    GuestUserLoggedIn();
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else if (user_id == chromeos::login::kRetailModeUserName) {
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RetailModeUserLoggedIn();
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else if (IsKioskApp(user_id)) {
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    KioskAppLoggedIn(user_id);
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else if (IsDemoApp(user_id)) {
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DemoAccountLoggedIn();
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EnsureUsersLoaded();
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (user && user->GetType() == USER_TYPE_PUBLIC_ACCOUNT) {
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      PublicAccountUserLoggedIn(user);
1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    } else if ((user && user->GetType() == USER_TYPE_SUPERVISED) ||
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               (!user &&
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                gaia::ExtractDomainName(user_id) ==
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    chromeos::login::kSupervisedUserDomain)) {
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      SupervisedUserLoggedIn(user_id);
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else if (browser_restart && IsPublicAccountMarkedForRemoval(user_id)) {
2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      PublicAccountUserLoggedIn(User::CreatePublicAccountUser(user_id));
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else if (user_id != GetOwnerEmail() && !user &&
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               (AreEphemeralUsersEnabled() || browser_restart)) {
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      RegularUserLoggedInAsEphemeral(user_id);
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else {
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      RegularUserLoggedIn(user_id);
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(active_user_);
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  active_user_->set_is_logged_in(true);
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  active_user_->set_is_active(true);
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  active_user_->set_username_hash(username_hash);
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Place user who just signed in to the top of the logged in users.
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  logged_in_users_.insert(logged_in_users_.begin(), active_user_);
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SetLRUUser(active_user_);
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!primary_user_) {
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    primary_user_ = active_user_;
2216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (primary_user_->GetType() == USER_TYPE_REGULAR)
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      SendRegularUserLoginMetrics(user_id);
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION(
2266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "UserManager.LoginUserType", active_user_->GetType(), NUM_USER_TYPES);
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GetLocalState()->SetString(
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      kLastLoggedInRegularUser,
2306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      (active_user_->GetType() == USER_TYPE_REGULAR) ? user_id : "");
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NotifyOnLogin();
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  PerformPostUserLoggedInActions(browser_restart);
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::SwitchActiveUser(const std::string& user_id) {
2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  User* user = FindUserAndModify(user_id);
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!user) {
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NOTREACHED() << "Switching to a non-existing user";
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (user == active_user_) {
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NOTREACHED() << "Switching to a user who is already active";
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!user->is_logged_in()) {
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NOTREACHED() << "Switching to a user that is not logged in";
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (user->GetType() != USER_TYPE_REGULAR) {
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NOTREACHED() << "Switching to a non-regular user";
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (user->username_hash().empty()) {
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NOTREACHED() << "Switching to a user that doesn't have username_hash set";
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(active_user_);
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  active_user_->set_is_active(false);
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  user->set_is_active(true);
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  active_user_ = user;
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Move the user to the front.
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SetLRUUser(active_user_);
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NotifyActiveUserHashChanged(active_user_->username_hash());
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NotifyActiveUserChanged(active_user_);
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid UserManagerBase::SwitchToLastActiveUser() {
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (last_session_active_user_.empty())
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (GetActiveUser()->email() != last_session_active_user_)
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SwitchActiveUser(last_session_active_user_);
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Make sure that this function gets run only once.
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  last_session_active_user_.clear();
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::SessionStarted() {
2836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  session_started_ = true;
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UpdateLoginState();
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  session_manager::SessionManager::Get()->SetSessionState(
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      session_manager::SESSION_STATE_ACTIVE);
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (IsCurrentUserNew()) {
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Make sure that the new user's data is persisted to Local State.
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    GetLocalState()->CommitPendingWrite();
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::RemoveUser(const std::string& user_id,
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 RemoveUserDelegate* delegate) {
2986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!CanUserBeRemoved(FindUser(user_id)))
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RemoveUserInternal(user_id, delegate);
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::RemoveUserInternal(const std::string& user_email,
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                         RemoveUserDelegate* delegate) {
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RemoveNonOwnerUserInternal(user_email, delegate);
3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::RemoveNonOwnerUserInternal(const std::string& user_email,
3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                 RemoveUserDelegate* delegate) {
3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (delegate)
3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    delegate->OnBeforeUserRemoved(user_email);
3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RemoveUserFromList(user_email);
3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      user_email, base::Bind(&OnRemoveUserComplete, user_email));
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (delegate)
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    delegate->OnUserRemoved(user_email);
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::RemoveUserFromList(const std::string& user_id) {
3246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RemoveNonCryptohomeData(user_id);
3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (user_loading_stage_ == STAGE_LOADED) {
3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DeleteUser(RemoveRegularOrSupervisedUserFromList(user_id));
3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else if (user_loading_stage_ == STAGE_LOADING) {
3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DCHECK(gaia::ExtractDomainName(user_id) ==
3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           chromeos::login::kSupervisedUserDomain);
3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Special case, removing partially-constructed supervised user during user
3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // list loading.
3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ListPrefUpdate users_update(GetLocalState(), kRegularUsers);
3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    users_update->Remove(base::StringValue(user_id), NULL);
3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NOTREACHED() << "Users are not loaded yet.";
3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Make sure that new data is persisted to Local State.
3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GetLocalState()->CommitPendingWrite();
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::IsKnownUser(const std::string& user_id) const {
3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return FindUser(user_id) != NULL;
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const User* UserManagerBase::FindUser(const std::string& user_id) const {
3496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (active_user_ && active_user_->email() == user_id)
3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return active_user_;
3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return FindUserInList(user_id);
3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)User* UserManagerBase::FindUserAndModify(const std::string& user_id) {
3566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (active_user_ && active_user_->email() == user_id)
3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return active_user_;
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return FindUserInListAndModify(user_id);
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const User* UserManagerBase::GetLoggedInUser() const {
3636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return active_user_;
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)User* UserManagerBase::GetLoggedInUser() {
3686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return active_user_;
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const User* UserManagerBase::GetActiveUser() const {
3736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return active_user_;
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)User* UserManagerBase::GetActiveUser() {
3786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return active_user_;
3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const User* UserManagerBase::GetPrimaryUser() const {
3836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return primary_user_;
3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::SaveUserOAuthStatus(
3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& user_id,
3896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    User::OAuthTokenStatus oauth_token_status) {
3906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DVLOG(1) << "Saving user OAuth token status in Local State";
3936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  User* user = FindUserAndModify(user_id);
3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (user)
3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    user->set_oauth_token_status(oauth_token_status);
3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Do not update local state if data stored or cached outside the user's
3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // cryptohome is to be treated as ephemeral.
3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (IsUserNonCryptohomeDataEphemeral(user_id))
4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DictionaryPrefUpdate oauth_status_update(GetLocalState(),
4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                           kUserOAuthTokenStatus);
4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  oauth_status_update->SetWithoutPathExpansion(
4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      user_id,
4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new base::FundamentalValue(static_cast<int>(oauth_token_status)));
4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::SaveForceOnlineSignin(const std::string& user_id,
4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                            bool force_online_signin) {
4116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Do not update local state if data stored or cached outside the user's
4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // cryptohome is to be treated as ephemeral.
4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (IsUserNonCryptohomeDataEphemeral(user_id))
4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DictionaryPrefUpdate force_online_update(GetLocalState(),
4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                           kUserForceOnlineSignin);
4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  force_online_update->SetBooleanWithoutPathExpansion(user_id,
4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                      force_online_signin);
4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::SaveUserDisplayName(const std::string& user_id,
4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                          const base::string16& display_name) {
4266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (User* user = FindUserAndModify(user_id)) {
4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    user->set_display_name(display_name);
4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Do not update local state if data stored or cached outside the user's
4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // cryptohome is to be treated as ephemeral.
4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      DictionaryPrefUpdate display_name_update(GetLocalState(),
4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               kUserDisplayName);
4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      display_name_update->SetWithoutPathExpansion(
4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          user_id, new base::StringValue(display_name));
4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::string16 UserManagerBase::GetUserDisplayName(
4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& user_id) const {
4446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const User* user = FindUser(user_id);
4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return user ? user->display_name() : base::string16();
4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::SaveUserDisplayEmail(const std::string& user_id,
4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                           const std::string& display_email) {
4506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  User* user = FindUserAndModify(user_id);
4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!user) {
4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(ERROR) << "User not found: " << user_id;
4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;  // Ignore if there is no such user.
4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  user->set_display_email(display_email);
4595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Do not update local state if data stored or cached outside the user's
4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // cryptohome is to be treated as ephemeral.
4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (IsUserNonCryptohomeDataEphemeral(user_id))
4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DictionaryPrefUpdate display_email_update(GetLocalState(), kUserDisplayEmail);
4665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  display_email_update->SetWithoutPathExpansion(
4675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      user_id, new base::StringValue(display_email));
4685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)std::string UserManagerBase::GetUserDisplayEmail(
4715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& user_id) const {
4726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const User* user = FindUser(user_id);
4735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return user ? user->display_email() : user_id;
4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::UpdateUserAccountData(
4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& user_id,
4785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const UserAccountData& account_data) {
4796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
4805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SaveUserDisplayName(user_id, account_data.display_name());
4825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (User* user = FindUserAndModify(user_id)) {
4845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::string16 given_name = account_data.given_name();
4855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    user->set_given_name(given_name);
4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
4875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      DictionaryPrefUpdate given_name_update(GetLocalState(), kUserGivenName);
4885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      given_name_update->SetWithoutPathExpansion(
4895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          user_id, new base::StringValue(given_name));
4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
4915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UpdateUserAccountLocale(user_id, account_data.locale());
4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::ParseUserList(const base::ListValue& users_list,
4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    const std::set<std::string>& existing_users,
4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    std::vector<std::string>* users_vector,
5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    std::set<std::string>* users_set) {
5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  users_vector->clear();
5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  users_set->clear();
5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = 0; i < users_list.GetSize(); ++i) {
5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    std::string email;
5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!users_list.GetString(i, &email) || email.empty()) {
5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      LOG(ERROR) << "Corrupt entry in user list at index " << i << ".";
5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      continue;
5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (existing_users.find(email) != existing_users.end() ||
5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        !users_set->insert(email).second) {
5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      LOG(ERROR) << "Duplicate user: " << email;
5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      continue;
5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    users_vector->push_back(email);
5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::IsCurrentUserOwner() const {
5196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::AutoLock lk(is_current_user_owner_lock_);
5215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return is_current_user_owner_;
5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::SetCurrentUserIsOwner(bool is_current_user_owner) {
5256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  {
5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lk(is_current_user_owner_lock_);
5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    is_current_user_owner_ = is_current_user_owner;
5295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UpdateLoginState();
5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::IsCurrentUserNew() const {
5346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
5355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return is_current_user_new_;
5365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::IsCurrentUserNonCryptohomeDataEphemeral() const {
5396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
5405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return IsUserLoggedIn() &&
5415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email());
5425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::CanCurrentUserLock() const {
5456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
5465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return IsUserLoggedIn() && active_user_->can_lock();
5475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::IsUserLoggedIn() const {
5506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
5515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return active_user_;
5525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::IsLoggedInAsRegularUser() const {
5556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
5566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_REGULAR;
5575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::IsLoggedInAsDemoUser() const {
5606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
5616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_RETAIL_MODE;
5625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::IsLoggedInAsPublicAccount() const {
5656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
5665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return IsUserLoggedIn() &&
5676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         active_user_->GetType() == USER_TYPE_PUBLIC_ACCOUNT;
5685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::IsLoggedInAsGuest() const {
5716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
5726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_GUEST;
5735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::IsLoggedInAsSupervisedUser() const {
5766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
5776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_SUPERVISED;
5785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::IsLoggedInAsKioskApp() const {
5816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
5826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_KIOSK_APP;
5835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::IsLoggedInAsStub() const {
5866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
5876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return IsUserLoggedIn() &&
5886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         active_user_->email() == chromeos::login::kStubUser;
5895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::IsSessionStarted() const {
5926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
5935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return session_started_;
5945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::IsUserNonCryptohomeDataEphemeral(
5975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& user_id) const {
5985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Data belonging to the guest, retail mode and stub users is always
5995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // ephemeral.
6006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (user_id == chromeos::login::kGuestUserName ||
6016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_id == chromeos::login::kRetailModeUserName ||
6026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_id == chromeos::login::kStubUser) {
6035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return true;
6045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
6055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Data belonging to the owner, anyone found on the user list and obsolete
6075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // public accounts whose data has not been removed yet is not ephemeral.
6085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (user_id == GetOwnerEmail() || UserExistsInList(user_id) ||
6095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      IsPublicAccountMarkedForRemoval(user_id)) {
6105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
6115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
6125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Data belonging to the currently logged-in user is ephemeral when:
6145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // a) The user logged into a regular account while the ephemeral users policy
6155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  //    was enabled.
6165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  //    - or -
6175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // b) The user logged into any other account type.
6185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (IsUserLoggedIn() && (user_id == GetLoggedInUser()->email()) &&
6195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      (is_current_user_ephemeral_regular_user_ || !IsLoggedInAsRegularUser())) {
6205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return true;
6215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
6225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Data belonging to any other user is ephemeral when:
6245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // a) Going through the regular login flow and the ephemeral users policy is
6255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  //    enabled.
6265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  //    - or -
6275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // b) The browser is restarting after a crash.
6285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return AreEphemeralUsersEnabled() ||
6295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         session_manager::SessionManager::HasBrowserRestarted();
6305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
6315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::AddObserver(UserManager::Observer* obs) {
6336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
6345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  observer_list_.AddObserver(obs);
6355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
6365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::RemoveObserver(UserManager::Observer* obs) {
6386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
6395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  observer_list_.RemoveObserver(obs);
6405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
6415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::AddSessionStateObserver(
6435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UserManager::UserSessionStateObserver* obs) {
6446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
6455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  session_state_observer_list_.AddObserver(obs);
6465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
6475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::RemoveSessionStateObserver(
6495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UserManager::UserSessionStateObserver* obs) {
6506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
6515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  session_state_observer_list_.RemoveObserver(obs);
6525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::NotifyLocalStateChanged() {
6556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
6565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FOR_EACH_OBSERVER(
6575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      UserManager::Observer, observer_list_, LocalStateChanged(this));
6585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
6595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid UserManagerBase::ForceUpdateState() {
6611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UpdateLoginState();
6621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
6631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool UserManagerBase::CanUserBeRemoved(const User* user) const {
6655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Only regular and supervised users are allowed to be manually removed.
6666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!user || (user->GetType() != USER_TYPE_REGULAR &&
6676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                user->GetType() != USER_TYPE_SUPERVISED)) {
6685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
6695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
6705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Sanity check: we must not remove single user unless it's an enterprise
6725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // device. This check may seem redundant at a first sight because
6735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // this single user must be an owner and we perform special check later
6745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // in order not to remove an owner. However due to non-instant nature of
6755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // ownership assignment this later check may sometimes fail.
6765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // See http://crosbug.com/12723
6775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (users_.size() < 2 && !IsEnterpriseManaged())
6785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
6795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Sanity check: do not allow any of the the logged in users to be removed.
6816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (UserList::const_iterator it = logged_in_users_.begin();
6825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       it != logged_in_users_.end();
6835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       ++it) {
6845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if ((*it)->email() == user->email())
6855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
6865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
6875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
6895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
6905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::GetEphemeralUsersEnabled() const {
6925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return ephemeral_users_enabled_;
6935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
6945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::SetEphemeralUsersEnabled(bool enabled) {
6965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ephemeral_users_enabled_ = enabled;
6975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
6985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::SetIsCurrentUserNew(bool is_new) {
7005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  is_current_user_new_ = is_new;
7015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
7025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::SetOwnerEmail(std::string owner_user_id) {
7045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  owner_email_ = owner_user_id;
7055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
7065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const std::string& UserManagerBase::GetPendingUserSwitchID() const {
7085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return pending_user_switch_;
7095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
7105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::SetPendingUserSwitchID(std::string user_id) {
7125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  pending_user_switch_ = user_id;
7135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
7145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::EnsureUsersLoaded() {
7166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
7175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!GetLocalState())
7185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
7195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (user_loading_stage_ != STAGE_NOT_LOADED)
7215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
7225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  user_loading_stage_ = STAGE_LOADING;
7235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  PerformPreUserListLoadingActions();
7255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  PrefService* local_state = GetLocalState();
7275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const base::ListValue* prefs_regular_users =
7285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      local_state->GetList(kRegularUsers);
7295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const base::DictionaryValue* prefs_display_names =
7315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      local_state->GetDictionary(kUserDisplayName);
7325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const base::DictionaryValue* prefs_given_names =
7335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      local_state->GetDictionary(kUserGivenName);
7345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const base::DictionaryValue* prefs_display_emails =
7355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      local_state->GetDictionary(kUserDisplayEmail);
7365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Load public sessions first.
7385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::set<std::string> public_sessions_set;
7395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  LoadPublicAccounts(&public_sessions_set);
7405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Load regular users and supervised users.
7425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::vector<std::string> regular_users;
7435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::set<std::string> regular_users_set;
7445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ParseUserList(*prefs_regular_users,
7455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                public_sessions_set,
7465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                &regular_users,
7475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                &regular_users_set);
7485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (std::vector<std::string>::const_iterator it = regular_users.begin();
7495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       it != regular_users.end();
7505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       ++it) {
7516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    User* user = NULL;
7525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string domain = gaia::ExtractDomainName(*it);
7535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (domain == chromeos::login::kSupervisedUserDomain)
7546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user = User::CreateSupervisedUser(*it);
7555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else
7566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user = User::CreateRegularUser(*it);
7575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    user->set_oauth_token_status(LoadUserOAuthStatus(*it));
7585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    user->set_force_online_signin(LoadForceOnlineSignin(*it));
7595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    users_.push_back(user);
7605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::string16 display_name;
7625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (prefs_display_names->GetStringWithoutPathExpansion(*it,
7635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                           &display_name)) {
7645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      user->set_display_name(display_name);
7655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
7665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::string16 given_name;
7685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (prefs_given_names->GetStringWithoutPathExpansion(*it, &given_name)) {
7695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      user->set_given_name(given_name);
7705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
7715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    std::string display_email;
7735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (prefs_display_emails->GetStringWithoutPathExpansion(*it,
7745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                            &display_email)) {
7755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      user->set_display_email(display_email);
7765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
7775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
7785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  user_loading_stage_ = STAGE_LOADED;
7805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  PerformPostUserListLoadingActions();
7825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
7835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)UserList& UserManagerBase::GetUsersAndModify() {
7855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EnsureUsersLoaded();
7865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return users_;
7875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
7885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const User* UserManagerBase::FindUserInList(const std::string& user_id) const {
7906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const UserList& users = GetUsers();
7916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
7925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if ((*it)->email() == user_id)
7935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return *it;
7945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
7955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return NULL;
7965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
7975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const bool UserManagerBase::UserExistsInList(const std::string& user_id) const {
7995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const base::ListValue* user_list = GetLocalState()->GetList(kRegularUsers);
8005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = 0; i < user_list->GetSize(); ++i) {
8015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    std::string email;
8025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (user_list->GetString(i, &email) && (user_id == email))
8035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return true;
8045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
8055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return false;
8065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
8075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)User* UserManagerBase::FindUserInListAndModify(const std::string& user_id) {
8096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  UserList& users = GetUsersAndModify();
8106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (UserList::iterator it = users.begin(); it != users.end(); ++it) {
8115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if ((*it)->email() == user_id)
8125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return *it;
8135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
8145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return NULL;
8155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
8165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::GuestUserLoggedIn() {
8186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
8196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  active_user_ = User::CreateGuestUser();
8205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
8215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void UserManagerBase::AddUserRecord(User* user) {
8235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Add the user to the front of the user list.
8245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
8255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs_users_update->Insert(0, new base::StringValue(user->email()));
8265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  users_.insert(users_.begin(), user);
8275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
8285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::RegularUserLoggedIn(const std::string& user_id) {
8305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Remove the user from the user list.
8315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  active_user_ = RemoveRegularOrSupervisedUserFromList(user_id);
8325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If the user was not found on the user list, create a new user.
8345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SetIsCurrentUserNew(!active_user_);
8355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (IsCurrentUserNew()) {
8366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    active_user_ = User::CreateRegularUser(user_id);
8375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    active_user_->set_oauth_token_status(LoadUserOAuthStatus(user_id));
8385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    SaveUserDisplayName(active_user_->email(),
8395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        base::UTF8ToUTF16(active_user_->GetAccountName(true)));
8405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
8415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AddUserRecord(active_user_);
8435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Make sure that new data is persisted to Local State.
8455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GetLocalState()->CommitPendingWrite();
8465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
8475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::RegularUserLoggedInAsEphemeral(
8495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& user_id) {
8506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
8515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SetIsCurrentUserNew(true);
8525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  is_current_user_ephemeral_regular_user_ = true;
8536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  active_user_ = User::CreateRegularUser(user_id);
8545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
8555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::NotifyOnLogin() {
8576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
8585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NotifyActiveUserHashChanged(active_user_->username_hash());
8605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NotifyActiveUserChanged(active_user_);
8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UpdateLoginState();
8625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
8635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)User::OAuthTokenStatus UserManagerBase::LoadUserOAuthStatus(
8655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& user_id) const {
8666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
8675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const base::DictionaryValue* prefs_oauth_status =
8695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      GetLocalState()->GetDictionary(kUserOAuthTokenStatus);
8706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  int oauth_token_status = User::OAUTH_TOKEN_STATUS_UNKNOWN;
8715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (prefs_oauth_status &&
8725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      prefs_oauth_status->GetIntegerWithoutPathExpansion(user_id,
8735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                         &oauth_token_status)) {
8746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    User::OAuthTokenStatus status =
8756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        static_cast<User::OAuthTokenStatus>(oauth_token_status);
8766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    HandleUserOAuthTokenStatusChange(user_id, status);
8776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
8786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return status;
8795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
8806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return User::OAUTH_TOKEN_STATUS_UNKNOWN;
8815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
8825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserManagerBase::LoadForceOnlineSignin(const std::string& user_id) const {
8846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
8855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const base::DictionaryValue* prefs_force_online =
8875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      GetLocalState()->GetDictionary(kUserForceOnlineSignin);
8885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool force_online_signin = false;
8895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (prefs_force_online) {
8905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    prefs_force_online->GetBooleanWithoutPathExpansion(user_id,
8915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                       &force_online_signin);
8925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
8935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return force_online_signin;
8945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
8955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::RemoveNonCryptohomeData(const std::string& user_id) {
8975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  PrefService* prefs = GetLocalState();
8985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
8995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs_display_name_update->RemoveWithoutPathExpansion(user_id, NULL);
9005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DictionaryPrefUpdate prefs_given_name_update(prefs, kUserGivenName);
9025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs_given_name_update->RemoveWithoutPathExpansion(user_id, NULL);
9035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
9055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs_display_email_update->RemoveWithoutPathExpansion(user_id, NULL);
9065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
9085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs_oauth_update->RemoveWithoutPathExpansion(user_id, NULL);
9095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DictionaryPrefUpdate prefs_force_online_update(prefs, kUserForceOnlineSignin);
9115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs_force_online_update->RemoveWithoutPathExpansion(user_id, NULL);
9121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string last_active_user = GetLocalState()->GetString(kLastActiveUser);
9141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (user_id == last_active_user)
9151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GetLocalState()->SetString(kLastActiveUser, std::string());
9165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
9175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)User* UserManagerBase::RemoveRegularOrSupervisedUserFromList(
9195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& user_id) {
9205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
9215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs_users_update->Clear();
9226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  User* user = NULL;
9236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (UserList::iterator it = users_.begin(); it != users_.end();) {
9245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string user_email = (*it)->email();
9255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (user_email == user_id) {
9265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      user = *it;
9275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      it = users_.erase(it);
9285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else {
9296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if ((*it)->GetType() == USER_TYPE_REGULAR ||
9306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          (*it)->GetType() == USER_TYPE_SUPERVISED) {
9315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        prefs_users_update->Append(new base::StringValue(user_email));
9325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      }
9335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ++it;
9345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
9355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
9365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return user;
9375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
9385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void UserManagerBase::NotifyActiveUserChanged(const User* active_user) {
9406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
9415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
9425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    session_state_observer_list_,
9435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    ActiveUserChanged(active_user));
9445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
9455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void UserManagerBase::NotifyUserAddedToSession(const User* added_user,
9476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                               bool user_switch_pending) {
9486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
9495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
9505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    session_state_observer_list_,
9515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    UserAddedToSession(added_user));
9525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
9535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::NotifyActiveUserHashChanged(const std::string& hash) {
9556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
9565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
9575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    session_state_observer_list_,
9585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    ActiveUserHashChanged(hash));
9595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
9605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::UpdateLoginState() {
9626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!chromeos::LoginState::IsInitialized())
9635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;  // LoginState may not be intialized in tests.
9645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  chromeos::LoginState::LoggedInState logged_in_state;
9666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  logged_in_state = active_user_ ? chromeos::LoginState::LOGGED_IN_ACTIVE
9676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 : chromeos::LoginState::LOGGED_IN_NONE;
9685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  chromeos::LoginState::LoggedInUserType login_user_type;
9706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (logged_in_state == chromeos::LoginState::LOGGED_IN_NONE)
9716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    login_user_type = chromeos::LoginState::LOGGED_IN_USER_NONE;
9725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  else if (is_current_user_owner_)
9736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    login_user_type = chromeos::LoginState::LOGGED_IN_USER_OWNER;
9746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  else if (active_user_->GetType() == USER_TYPE_GUEST)
9756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    login_user_type = chromeos::LoginState::LOGGED_IN_USER_GUEST;
9766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  else if (active_user_->GetType() == USER_TYPE_RETAIL_MODE)
9776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    login_user_type = chromeos::LoginState::LOGGED_IN_USER_RETAIL_MODE;
9786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  else if (active_user_->GetType() == USER_TYPE_PUBLIC_ACCOUNT)
9796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    login_user_type = chromeos::LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT;
9806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  else if (active_user_->GetType() == USER_TYPE_SUPERVISED)
9816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    login_user_type = chromeos::LoginState::LOGGED_IN_USER_SUPERVISED;
9826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  else if (active_user_->GetType() == USER_TYPE_KIOSK_APP)
9836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    login_user_type = chromeos::LoginState::LOGGED_IN_USER_KIOSK_APP;
9845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  else
9856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    login_user_type = chromeos::LoginState::LOGGED_IN_USER_REGULAR;
9865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (primary_user_) {
9886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    chromeos::LoginState::Get()->SetLoggedInStateAndPrimaryUser(
9895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        logged_in_state, login_user_type, primary_user_->username_hash());
9905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
9916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    chromeos::LoginState::Get()->SetLoggedInState(logged_in_state,
9926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                                  login_user_type);
9935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
9945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
9955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void UserManagerBase::SetLRUUser(User* user) {
9971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GetLocalState()->SetString(kLastActiveUser, user->email());
9981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GetLocalState()->CommitPendingWrite();
9991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  UserList::iterator it =
10015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      std::find(lru_logged_in_users_.begin(), lru_logged_in_users_.end(), user);
10025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (it != lru_logged_in_users_.end())
10035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    lru_logged_in_users_.erase(it);
10045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user);
10055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
10065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::SendRegularUserLoginMetrics(const std::string& user_id) {
10085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If this isn't the first time Chrome was run after the system booted,
10095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // assume that Chrome was restarted because a previous session ended.
10105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
10116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          chromeos::switches::kFirstExecAfterBoot)) {
10125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string last_email =
10135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        GetLocalState()->GetString(kLastLoggedInRegularUser);
10145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::TimeDelta time_to_login =
10155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::TimeTicks::Now() - manager_creation_time_;
10165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!last_email.empty() && user_id != last_email &&
10175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) {
10185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay",
10195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  time_to_login.InSeconds(),
10205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  0,
10215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  kLogoutToLoginDelayMaxSec,
10225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  50);
10235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
10245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
10255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
10265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::UpdateUserAccountLocale(const std::string& user_id,
10285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                              const std::string& locale) {
102903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<std::string> resolved_locale(new std::string());
10305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!locale.empty() && locale != GetApplicationLocale()) {
103103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // base::Pased will NULL out |resolved_locale|, so cache the underlying ptr.
103203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::string* raw_resolved_locale = resolved_locale.get();
103303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    blocking_task_runner_->PostTaskAndReply(
103403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        FROM_HERE,
103503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(ResolveLocale,
103603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   locale,
103703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   base::Unretained(raw_resolved_locale)),
10385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(&UserManagerBase::DoUpdateAccountLocale,
10395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   weak_factory_.GetWeakPtr(),
104003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   user_id,
104103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   base::Passed(&resolved_locale)));
10425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
104303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    resolved_locale.reset(new std::string(locale));
104403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    DoUpdateAccountLocale(user_id, resolved_locale.Pass());
10455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
10465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
10475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void UserManagerBase::DoUpdateAccountLocale(
10495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& user_id,
105003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<std::string> resolved_locale) {
105103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  User* user = FindUserAndModify(user_id);
105203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (user && resolved_locale)
105303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    user->SetAccountLocale(*resolved_locale);
10545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
10555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void UserManagerBase::DeleteUser(User* user) {
10575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const bool is_active_user = (user == active_user_);
10585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  delete user;
10595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (is_active_user)
10605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    active_user_ = NULL;
10615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
10625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // namespace user_manager
1064