• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/chromeos/login/users/user_manager_impl.h"
6 
7 #include <cstddef>
8 #include <set>
9 
10 #include "ash/multi_profile_uma.h"
11 #include "base/base_paths.h"
12 #include "base/bind.h"
13 #include "base/bind_helpers.h"
14 #include "base/command_line.h"
15 #include "base/compiler_specific.h"
16 #include "base/files/file_path.h"
17 #include "base/format_macros.h"
18 #include "base/logging.h"
19 #include "base/metrics/histogram.h"
20 #include "base/path_service.h"
21 #include "base/prefs/pref_registry_simple.h"
22 #include "base/prefs/pref_service.h"
23 #include "base/prefs/scoped_user_pref_update.h"
24 #include "base/rand_util.h"
25 #include "base/strings/string_util.h"
26 #include "base/strings/stringprintf.h"
27 #include "base/strings/utf_string_conversions.h"
28 #include "base/sys_info.h"
29 #include "base/threading/worker_pool.h"
30 #include "base/values.h"
31 #include "chrome/browser/app_mode/app_mode_utils.h"
32 #include "chrome/browser/browser_process.h"
33 #include "chrome/browser/chrome_notification_types.h"
34 #include "chrome/browser/chromeos/base/locale_util.h"
35 #include "chrome/browser/chromeos/login/auth/user_context.h"
36 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
37 #include "chrome/browser/chromeos/login/login_utils.h"
38 #include "chrome/browser/chromeos/login/session/session_manager.h"
39 #include "chrome/browser/chromeos/login/signin/auth_sync_observer.h"
40 #include "chrome/browser/chromeos/login/signin/auth_sync_observer_factory.h"
41 #include "chrome/browser/chromeos/login/ui/login_display.h"
42 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h"
43 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
44 #include "chrome/browser/chromeos/login/users/remove_user_delegate.h"
45 #include "chrome/browser/chromeos/login/users/supervised_user_manager_impl.h"
46 #include "chrome/browser/chromeos/login/wizard_controller.h"
47 #include "chrome/browser/chromeos/net/network_portal_detector.h"
48 #include "chrome/browser/chromeos/net/network_portal_detector_strategy.h"
49 #include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h"
50 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
51 #include "chrome/browser/chromeos/policy/device_local_account.h"
52 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog.h"
53 #include "chrome/browser/chromeos/profiles/profile_helper.h"
54 #include "chrome/browser/chromeos/session_length_limiter.h"
55 #include "chrome/browser/net/nss_context.h"
56 #include "chrome/browser/profiles/profile.h"
57 #include "chrome/browser/profiles/profile_manager.h"
58 #include "chrome/browser/profiles/profiles_state.h"
59 #include "chrome/browser/supervised_user/chromeos/manager_password_service_factory.h"
60 #include "chrome/browser/supervised_user/chromeos/supervised_user_password_service_factory.h"
61 #include "chrome/browser/sync/profile_sync_service.h"
62 #include "chrome/browser/sync/profile_sync_service_factory.h"
63 #include "chrome/common/chrome_constants.h"
64 #include "chrome/common/chrome_paths.h"
65 #include "chrome/common/chrome_switches.h"
66 #include "chrome/common/crash_keys.h"
67 #include "chrome/common/pref_names.h"
68 #include "chromeos/cert_loader.h"
69 #include "chromeos/chromeos_switches.h"
70 #include "chromeos/cryptohome/async_method_caller.h"
71 #include "chromeos/dbus/dbus_thread_manager.h"
72 #include "chromeos/login/login_state.h"
73 #include "chromeos/settings/cros_settings_names.h"
74 #include "content/public/browser/browser_thread.h"
75 #include "content/public/browser/notification_service.h"
76 #include "google_apis/gaia/gaia_auth_util.h"
77 #include "google_apis/gaia/google_service_auth_error.h"
78 #include "policy/policy_constants.h"
79 #include "ui/base/l10n/l10n_util.h"
80 #include "ui/wm/core/wm_core_switches.h"
81 
82 using content::BrowserThread;
83 
84 namespace chromeos {
85 namespace {
86 
87 // A vector pref of the the regular users known on this device, arranged in LRU
88 // order.
89 const char kRegularUsers[] = "LoggedInUsers";
90 
91 // A vector pref of the public accounts defined on this device.
92 const char kPublicAccounts[] = "PublicAccounts";
93 
94 // A string pref that gets set when a public account is removed but a user is
95 // currently logged into that account, requiring the account's data to be
96 // removed after logout.
97 const char kPublicAccountPendingDataRemoval[] =
98     "PublicAccountPendingDataRemoval";
99 
100 // A dictionary that maps user IDs to the displayed name.
101 const char kUserDisplayName[] = "UserDisplayName";
102 
103 // A dictionary that maps user IDs to the user's given name.
104 const char kUserGivenName[] = "UserGivenName";
105 
106 // A dictionary that maps user IDs to the displayed (non-canonical) emails.
107 const char kUserDisplayEmail[] = "UserDisplayEmail";
108 
109 // A dictionary that maps user IDs to OAuth token presence flag.
110 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus";
111 
112 // A dictionary that maps user IDs to a flag indicating whether online
113 // authentication against GAIA should be enforced during the next sign-in.
114 const char kUserForceOnlineSignin[] = "UserForceOnlineSignin";
115 
116 // A string pref containing the ID of the last user who logged in if it was
117 // a regular user or an empty string if it was another type of user (guest,
118 // kiosk, public account, etc.).
119 const char kLastLoggedInRegularUser[] = "LastLoggedInRegularUser";
120 
121 // Upper bound for a histogram metric reporting the amount of time between
122 // one regular user logging out and a different regular user logging in.
123 const int kLogoutToLoginDelayMaxSec = 1800;
124 
125 // Callback that is called after user removal is complete.
OnRemoveUserComplete(const std::string & user_email,bool success,cryptohome::MountError return_code)126 void OnRemoveUserComplete(const std::string& user_email,
127                           bool success,
128                           cryptohome::MountError return_code) {
129   // Log the error, but there's not much we can do.
130   if (!success) {
131     LOG(ERROR) << "Removal of cryptohome for " << user_email
132                << " failed, return code: " << return_code;
133   }
134 }
135 
136 // Helper function that copies users from |users_list| to |users_vector| and
137 // |users_set|. Duplicates and users already present in |existing_users| are
138 // skipped.
ParseUserList(const base::ListValue & users_list,const std::set<std::string> & existing_users,std::vector<std::string> * users_vector,std::set<std::string> * users_set)139 void ParseUserList(const base::ListValue& users_list,
140                    const std::set<std::string>& existing_users,
141                    std::vector<std::string>* users_vector,
142                    std::set<std::string>* users_set) {
143   users_vector->clear();
144   users_set->clear();
145   for (size_t i = 0; i < users_list.GetSize(); ++i) {
146     std::string email;
147     if (!users_list.GetString(i, &email) || email.empty()) {
148       LOG(ERROR) << "Corrupt entry in user list at index " << i << ".";
149       continue;
150     }
151     if (existing_users.find(email) != existing_users.end() ||
152         !users_set->insert(email).second) {
153       LOG(ERROR) << "Duplicate user: " << email;
154       continue;
155     }
156     users_vector->push_back(email);
157   }
158 }
159 
160 class UserHashMatcher {
161  public:
UserHashMatcher(const std::string & h)162   explicit UserHashMatcher(const std::string& h) : username_hash(h) {}
operator ()(const User * user) const163   bool operator()(const User* user) const {
164     return user->username_hash() == username_hash;
165   }
166 
167  private:
168   const std::string& username_hash;
169 };
170 
171 // Runs on SequencedWorkerPool thread. Passes resolved locale to
172 // |on_resolve_callback| on UI thread.
ResolveLocale(const std::string & raw_locale,base::Callback<void (const std::string &)> on_resolve_callback)173 void ResolveLocale(
174     const std::string& raw_locale,
175     base::Callback<void(const std::string&)> on_resolve_callback) {
176   DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
177   std::string resolved_locale;
178   // Ignore result
179   l10n_util::CheckAndResolveLocale(raw_locale, &resolved_locale);
180   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
181       base::Bind(on_resolve_callback, resolved_locale));
182 }
183 
184 // Callback to GetNSSCertDatabaseForProfile. It starts CertLoader using the
185 // provided NSS database. It must be called for primary user only.
OnGetNSSCertDatabaseForUser(net::NSSCertDatabase * database)186 void OnGetNSSCertDatabaseForUser(net::NSSCertDatabase* database) {
187   if (!CertLoader::IsInitialized())
188     return;
189 
190   CertLoader::Get()->StartWithNSSDB(database);
191 }
192 
193 }  // namespace
194 
195 // static
RegisterPrefs(PrefRegistrySimple * registry)196 void UserManager::RegisterPrefs(PrefRegistrySimple* registry) {
197   registry->RegisterListPref(kRegularUsers);
198   registry->RegisterListPref(kPublicAccounts);
199   registry->RegisterStringPref(kPublicAccountPendingDataRemoval, "");
200   registry->RegisterStringPref(kLastLoggedInRegularUser, "");
201   registry->RegisterDictionaryPref(kUserDisplayName);
202   registry->RegisterDictionaryPref(kUserGivenName);
203   registry->RegisterDictionaryPref(kUserDisplayEmail);
204   registry->RegisterDictionaryPref(kUserOAuthTokenStatus);
205   registry->RegisterDictionaryPref(kUserForceOnlineSignin);
206   SupervisedUserManager::RegisterPrefs(registry);
207   SessionLengthLimiter::RegisterPrefs(registry);
208 }
209 
UserManagerImpl()210 UserManagerImpl::UserManagerImpl()
211     : cros_settings_(CrosSettings::Get()),
212       device_local_account_policy_service_(NULL),
213       user_loading_stage_(STAGE_NOT_LOADED),
214       active_user_(NULL),
215       primary_user_(NULL),
216       session_started_(false),
217       user_sessions_restored_(false),
218       is_current_user_owner_(false),
219       is_current_user_new_(false),
220       is_current_user_ephemeral_regular_user_(false),
221       ephemeral_users_enabled_(false),
222       supervised_user_manager_(new SupervisedUserManagerImpl(this)),
223       manager_creation_time_(base::TimeTicks::Now()) {
224   UpdateNumberOfUsers();
225   // UserManager instance should be used only on UI thread.
226   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
227   registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
228       content::NotificationService::AllSources());
229   registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
230       content::NotificationService::AllSources());
231   registrar_.Add(this,
232                  chrome::NOTIFICATION_PROFILE_CREATED,
233                  content::NotificationService::AllSources());
234   RetrieveTrustedDevicePolicies();
235   local_accounts_subscription_ = cros_settings_->AddSettingsObserver(
236       kAccountsPrefDeviceLocalAccounts,
237       base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
238                  base::Unretained(this)));
239   multi_profile_user_controller_.reset(new MultiProfileUserController(
240       this, g_browser_process->local_state()));
241 
242   policy::BrowserPolicyConnectorChromeOS* connector =
243       g_browser_process->platform_part()->browser_policy_connector_chromeos();
244   avatar_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
245       cros_settings_,
246       this,
247       connector->GetDeviceLocalAccountPolicyService(),
248       policy::key::kUserAvatarImage,
249       this));
250   avatar_policy_observer_->Init();
251 
252   wallpaper_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
253       cros_settings_,
254       this,
255       connector->GetDeviceLocalAccountPolicyService(),
256       policy::key::kWallpaperImage,
257       this));
258   wallpaper_policy_observer_->Init();
259 
260   UpdateLoginState();
261 }
262 
~UserManagerImpl()263 UserManagerImpl::~UserManagerImpl() {
264   // Can't use STLDeleteElements because of the private destructor of User.
265   for (UserList::iterator it = users_.begin(); it != users_.end();
266        it = users_.erase(it)) {
267     DeleteUser(*it);
268   }
269   // These are pointers to the same User instances that were in users_ list.
270   logged_in_users_.clear();
271   lru_logged_in_users_.clear();
272 
273   DeleteUser(active_user_);
274 }
275 
Shutdown()276 void UserManagerImpl::Shutdown() {
277   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
278   local_accounts_subscription_.reset();
279   // Stop the session length limiter.
280   session_length_limiter_.reset();
281 
282   if (device_local_account_policy_service_)
283     device_local_account_policy_service_->RemoveObserver(this);
284 
285   for (UserImageManagerMap::iterator it = user_image_managers_.begin(),
286                                      ie = user_image_managers_.end();
287        it != ie; ++it) {
288     it->second->Shutdown();
289   }
290   multi_profile_user_controller_.reset();
291   avatar_policy_observer_.reset();
292   wallpaper_policy_observer_.reset();
293   registrar_.RemoveAll();
294 }
295 
GetMultiProfileUserController()296 MultiProfileUserController* UserManagerImpl::GetMultiProfileUserController() {
297   return multi_profile_user_controller_.get();
298 }
299 
GetUserImageManager(const std::string & user_id)300 UserImageManager* UserManagerImpl::GetUserImageManager(
301     const std::string& user_id) {
302   UserImageManagerMap::iterator ui = user_image_managers_.find(user_id);
303   if (ui != user_image_managers_.end())
304     return ui->second.get();
305   linked_ptr<UserImageManagerImpl> mgr(new UserImageManagerImpl(user_id, this));
306   user_image_managers_[user_id] = mgr;
307   return mgr.get();
308 }
309 
GetSupervisedUserManager()310 SupervisedUserManager* UserManagerImpl::GetSupervisedUserManager() {
311   return supervised_user_manager_.get();
312 }
313 
GetUsers() const314 const UserList& UserManagerImpl::GetUsers() const {
315   const_cast<UserManagerImpl*>(this)->EnsureUsersLoaded();
316   return users_;
317 }
318 
GetUsersAdmittedForMultiProfile() const319 UserList UserManagerImpl::GetUsersAdmittedForMultiProfile() const {
320   // Supervised users are not allowed to use multi-profiles.
321   if (logged_in_users_.size() == 1 &&
322       GetPrimaryUser()->GetType() != User::USER_TYPE_REGULAR) {
323     return UserList();
324   }
325 
326   UserList result;
327   const UserList& users = GetUsers();
328   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
329     if ((*it)->GetType() == User::USER_TYPE_REGULAR && !(*it)->is_logged_in()) {
330       MultiProfileUserController::UserAllowedInSessionResult check =
331           multi_profile_user_controller_->
332               IsUserAllowedInSession((*it)->email());
333       if (check == MultiProfileUserController::
334               NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS) {
335         return UserList();
336       }
337 
338       // Users with a policy that prevents them being added to a session will be
339       // shown in login UI but will be grayed out.
340       // Same applies to owner account (see http://crbug.com/385034).
341       if (check == MultiProfileUserController::ALLOWED ||
342           check == MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS ||
343           check == MultiProfileUserController::NOT_ALLOWED_OWNER_AS_SECONDARY) {
344         result.push_back(*it);
345       }
346     }
347   }
348 
349   return result;
350 }
351 
GetLoggedInUsers() const352 const UserList& UserManagerImpl::GetLoggedInUsers() const {
353   return logged_in_users_;
354 }
355 
GetLRULoggedInUsers()356 const UserList& UserManagerImpl::GetLRULoggedInUsers() {
357   // If there is no user logged in, we return the active user as the only one.
358   if (lru_logged_in_users_.empty() && active_user_) {
359     temp_single_logged_in_users_.clear();
360     temp_single_logged_in_users_.insert(temp_single_logged_in_users_.begin(),
361                                         active_user_);
362     return temp_single_logged_in_users_;
363   }
364   return lru_logged_in_users_;
365 }
366 
GetUnlockUsers() const367 UserList UserManagerImpl::GetUnlockUsers() const {
368   const UserList& logged_in_users = GetLoggedInUsers();
369   if (logged_in_users.empty())
370     return UserList();
371 
372   UserList unlock_users;
373   Profile* profile = GetProfileByUser(primary_user_);
374   std::string primary_behavior =
375       profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
376 
377   // Specific case: only one logged in user or
378   // primary user has primary-only multi-profile policy.
379   if (logged_in_users.size() == 1 ||
380       primary_behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
381     if (primary_user_->can_lock())
382       unlock_users.push_back(primary_user_);
383   } else {
384     // Fill list of potential unlock users based on multi-profile policy state.
385     for (UserList::const_iterator it = logged_in_users.begin();
386          it != logged_in_users.end(); ++it) {
387       User* user = (*it);
388       Profile* profile = GetProfileByUser(user);
389       const std::string behavior =
390           profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
391       if (behavior == MultiProfileUserController::kBehaviorUnrestricted &&
392           user->can_lock()) {
393         unlock_users.push_back(user);
394       } else if (behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
395         NOTREACHED()
396             << "Spotted primary-only multi-profile policy for non-primary user";
397       }
398     }
399   }
400 
401   return unlock_users;
402 }
403 
GetOwnerEmail()404 const std::string& UserManagerImpl::GetOwnerEmail() {
405   return owner_email_;
406 }
407 
UserLoggedIn(const std::string & user_id,const std::string & username_hash,bool browser_restart)408 void UserManagerImpl::UserLoggedIn(const std::string& user_id,
409                                    const std::string& username_hash,
410                                    bool browser_restart) {
411   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
412 
413   User* user = FindUserInListAndModify(user_id);
414   if (active_user_ && user) {
415     user->set_is_logged_in(true);
416     user->set_username_hash(username_hash);
417     logged_in_users_.push_back(user);
418     lru_logged_in_users_.push_back(user);
419     // Reset the new user flag if the user already exists.
420     is_current_user_new_ = false;
421     NotifyUserAddedToSession(user);
422     // Remember that we need to switch to this user as soon as profile ready.
423     pending_user_switch_ = user_id;
424     return;
425   }
426 
427   policy::DeviceLocalAccount::Type device_local_account_type;
428   if (user_id == UserManager::kGuestUserName) {
429     GuestUserLoggedIn();
430   } else if (user_id == UserManager::kRetailModeUserName) {
431     RetailModeUserLoggedIn();
432   } else if (policy::IsDeviceLocalAccountUser(user_id,
433                                               &device_local_account_type) &&
434              device_local_account_type ==
435                  policy::DeviceLocalAccount::TYPE_KIOSK_APP) {
436     KioskAppLoggedIn(user_id);
437   } else if (DemoAppLauncher::IsDemoAppSession(user_id)) {
438     DemoAccountLoggedIn();
439   } else {
440     EnsureUsersLoaded();
441 
442     if (user && user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
443       PublicAccountUserLoggedIn(user);
444     } else if ((user && user->GetType() == User::USER_TYPE_LOCALLY_MANAGED) ||
445                (!user && gaia::ExtractDomainName(user_id) ==
446                     UserManager::kLocallyManagedUserDomain)) {
447       LocallyManagedUserLoggedIn(user_id);
448     } else if (browser_restart && user_id == g_browser_process->local_state()->
449                    GetString(kPublicAccountPendingDataRemoval)) {
450       PublicAccountUserLoggedIn(User::CreatePublicAccountUser(user_id));
451     } else if (user_id != owner_email_ && !user &&
452                (AreEphemeralUsersEnabled() || browser_restart)) {
453       RegularUserLoggedInAsEphemeral(user_id);
454     } else {
455       RegularUserLoggedIn(user_id);
456     }
457 
458     // Initialize the session length limiter and start it only if
459     // session limit is defined by the policy.
460     session_length_limiter_.reset(new SessionLengthLimiter(NULL,
461                                                            browser_restart));
462   }
463   DCHECK(active_user_);
464   active_user_->set_is_logged_in(true);
465   active_user_->set_is_active(true);
466   active_user_->set_username_hash(username_hash);
467 
468   // Place user who just signed in to the top of the logged in users.
469   logged_in_users_.insert(logged_in_users_.begin(), active_user_);
470   SetLRUUser(active_user_);
471 
472   if (!primary_user_) {
473     primary_user_ = active_user_;
474     if (primary_user_->GetType() == User::USER_TYPE_REGULAR)
475       SendRegularUserLoginMetrics(user_id);
476   }
477 
478   UMA_HISTOGRAM_ENUMERATION("UserManager.LoginUserType",
479                             active_user_->GetType(), User::NUM_USER_TYPES);
480 
481   g_browser_process->local_state()->SetString(kLastLoggedInRegularUser,
482     (active_user_->GetType() == User::USER_TYPE_REGULAR) ? user_id : "");
483 
484   NotifyOnLogin();
485 }
486 
SwitchActiveUser(const std::string & user_id)487 void UserManagerImpl::SwitchActiveUser(const std::string& user_id) {
488   User* user = FindUserAndModify(user_id);
489   if (!user) {
490     NOTREACHED() << "Switching to a non-existing user";
491     return;
492   }
493   if (user == active_user_) {
494     NOTREACHED() << "Switching to a user who is already active";
495     return;
496   }
497   if (!user->is_logged_in()) {
498     NOTREACHED() << "Switching to a user that is not logged in";
499     return;
500   }
501   if (user->GetType() != User::USER_TYPE_REGULAR) {
502     NOTREACHED() << "Switching to a non-regular user";
503     return;
504   }
505   if (user->username_hash().empty()) {
506     NOTREACHED() << "Switching to a user that doesn't have username_hash set";
507     return;
508   }
509 
510   DCHECK(active_user_);
511   active_user_->set_is_active(false);
512   user->set_is_active(true);
513   active_user_ = user;
514 
515   // Move the user to the front.
516   SetLRUUser(active_user_);
517 
518   NotifyActiveUserHashChanged(active_user_->username_hash());
519   NotifyActiveUserChanged(active_user_);
520 }
521 
RestoreActiveSessions()522 void UserManagerImpl::RestoreActiveSessions() {
523   DBusThreadManager::Get()->GetSessionManagerClient()->RetrieveActiveSessions(
524       base::Bind(&UserManagerImpl::OnRestoreActiveSessions,
525                  base::Unretained(this)));
526 }
527 
SessionStarted()528 void UserManagerImpl::SessionStarted() {
529   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
530   session_started_ = true;
531   UpdateLoginState();
532   content::NotificationService::current()->Notify(
533       chrome::NOTIFICATION_SESSION_STARTED,
534       content::Source<UserManager>(this),
535       content::Details<const User>(active_user_));
536   if (is_current_user_new_) {
537     // Make sure that the new user's data is persisted to Local State.
538     g_browser_process->local_state()->CommitPendingWrite();
539   }
540 }
541 
RemoveUser(const std::string & user_id,RemoveUserDelegate * delegate)542 void UserManagerImpl::RemoveUser(const std::string& user_id,
543                                  RemoveUserDelegate* delegate) {
544   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
545 
546   const User* user = FindUser(user_id);
547   if (!user || (user->GetType() != User::USER_TYPE_REGULAR &&
548                 user->GetType() != User::USER_TYPE_LOCALLY_MANAGED))
549     return;
550 
551   // Sanity check: we must not remove single user unless it's an enterprise
552   // device. This check may seem redundant at a first sight because
553   // this single user must be an owner and we perform special check later
554   // in order not to remove an owner. However due to non-instant nature of
555   // ownership assignment this later check may sometimes fail.
556   // See http://crosbug.com/12723
557   policy::BrowserPolicyConnectorChromeOS* connector =
558       g_browser_process->platform_part()
559           ->browser_policy_connector_chromeos();
560   if (users_.size() < 2 && !connector->IsEnterpriseManaged())
561     return;
562 
563   // Sanity check: do not allow any of the the logged in users to be removed.
564   for (UserList::const_iterator it = logged_in_users_.begin();
565        it != logged_in_users_.end(); ++it) {
566     if ((*it)->email() == user_id)
567       return;
568   }
569 
570   RemoveUserInternal(user_id, delegate);
571 }
572 
RemoveUserInternal(const std::string & user_email,RemoveUserDelegate * delegate)573 void UserManagerImpl::RemoveUserInternal(const std::string& user_email,
574                                          RemoveUserDelegate* delegate) {
575   CrosSettings* cros_settings = CrosSettings::Get();
576 
577   // Ensure the value of owner email has been fetched.
578   if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues(
579           base::Bind(&UserManagerImpl::RemoveUserInternal,
580                      base::Unretained(this),
581                      user_email, delegate))) {
582     // Value of owner email is not fetched yet.  RemoveUserInternal will be
583     // called again after fetch completion.
584     return;
585   }
586   std::string owner;
587   cros_settings->GetString(kDeviceOwner, &owner);
588   if (user_email == owner) {
589     // Owner is not allowed to be removed from the device.
590     return;
591   }
592   RemoveNonOwnerUserInternal(user_email, delegate);
593 }
594 
RemoveNonOwnerUserInternal(const std::string & user_email,RemoveUserDelegate * delegate)595 void UserManagerImpl::RemoveNonOwnerUserInternal(const std::string& user_email,
596                                                  RemoveUserDelegate* delegate) {
597   if (delegate)
598     delegate->OnBeforeUserRemoved(user_email);
599   RemoveUserFromList(user_email);
600   cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
601       user_email, base::Bind(&OnRemoveUserComplete, user_email));
602 
603   if (delegate)
604     delegate->OnUserRemoved(user_email);
605 }
606 
RemoveUserFromList(const std::string & user_id)607 void UserManagerImpl::RemoveUserFromList(const std::string& user_id) {
608   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
609   RemoveNonCryptohomeData(user_id);
610   if (user_loading_stage_ == STAGE_LOADED) {
611     DeleteUser(RemoveRegularOrLocallyManagedUserFromList(user_id));
612   } else if (user_loading_stage_ == STAGE_LOADING) {
613     DCHECK(gaia::ExtractDomainName(user_id) ==
614         UserManager::kLocallyManagedUserDomain);
615     // Special case, removing partially-constructed supervised user during user
616     // list loading.
617     ListPrefUpdate users_update(g_browser_process->local_state(),
618                                 kRegularUsers);
619     users_update->Remove(base::StringValue(user_id), NULL);
620   } else {
621     NOTREACHED() << "Users are not loaded yet.";
622     return;
623   }
624   // Make sure that new data is persisted to Local State.
625   g_browser_process->local_state()->CommitPendingWrite();
626 }
627 
IsKnownUser(const std::string & user_id) const628 bool UserManagerImpl::IsKnownUser(const std::string& user_id) const {
629   return FindUser(user_id) != NULL;
630 }
631 
FindUser(const std::string & user_id) const632 const User* UserManagerImpl::FindUser(const std::string& user_id) const {
633   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
634   if (active_user_ && active_user_->email() == user_id)
635     return active_user_;
636   return FindUserInList(user_id);
637 }
638 
FindUserAndModify(const std::string & user_id)639 User* UserManagerImpl::FindUserAndModify(const std::string& user_id) {
640   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
641   if (active_user_ && active_user_->email() == user_id)
642     return active_user_;
643   return FindUserInListAndModify(user_id);
644 }
645 
GetLoggedInUser() const646 const User* UserManagerImpl::GetLoggedInUser() const {
647   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
648   return active_user_;
649 }
650 
GetLoggedInUser()651 User* UserManagerImpl::GetLoggedInUser() {
652   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
653   return active_user_;
654 }
655 
GetActiveUser() const656 const User* UserManagerImpl::GetActiveUser() const {
657   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
658   return active_user_;
659 }
660 
GetActiveUser()661 User* UserManagerImpl::GetActiveUser() {
662   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
663   return active_user_;
664 }
665 
GetPrimaryUser() const666 const User* UserManagerImpl::GetPrimaryUser() const {
667   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
668   return primary_user_;
669 }
670 
GetUserByProfile(Profile * profile) const671 User* UserManagerImpl::GetUserByProfile(Profile* profile) const {
672   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
673   if (ProfileHelper::IsSigninProfile(profile))
674     return NULL;
675 
676   // Special case for non-CrOS tests that do create several profiles
677   // and don't really care about mapping to the real user.
678   // Without multi-profiles on Chrome OS such tests always got active_user_.
679   // Now these tests will specify special flag to continue working.
680   // In future those tests can get a proper CrOS configuration i.e. register
681   // and login several users if they want to work with an additional profile.
682   if (CommandLine::ForCurrentProcess()->HasSwitch(
683           switches::kIgnoreUserProfileMappingForTests)) {
684     return active_user_;
685   }
686 
687   const std::string username_hash =
688       ProfileHelper::GetUserIdHashFromProfile(profile);
689   const UserList& users = GetUsers();
690   const UserList::const_iterator pos = std::find_if(
691       users.begin(), users.end(), UserHashMatcher(username_hash));
692   if (pos != users.end())
693     return *pos;
694 
695   // Many tests do not have their users registered with UserManager and
696   // runs here. If |active_user_| matches |profile|, returns it.
697   return active_user_ &&
698                  ProfileHelper::GetProfilePathByUserIdHash(
699                      active_user_->username_hash()) == profile->GetPath()
700              ? active_user_
701              : NULL;
702 }
703 
GetProfileByUser(const User * user) const704 Profile* UserManagerImpl::GetProfileByUser(const User* user) const {
705   Profile* profile = NULL;
706   if (user->is_profile_created())
707     profile = ProfileHelper::GetProfileByUserIdHash(user->username_hash());
708   else
709     profile = ProfileManager::GetActiveUserProfile();
710 
711   // GetActiveUserProfile() or GetProfileByUserIdHash() returns a new instance
712   // of ProfileImpl(), but actually its OffTheRecordProfile() should be used.
713   if (profile && IsLoggedInAsGuest())
714     profile = profile->GetOffTheRecordProfile();
715   return profile;
716 }
717 
SaveUserOAuthStatus(const std::string & user_id,User::OAuthTokenStatus oauth_token_status)718 void UserManagerImpl::SaveUserOAuthStatus(
719     const std::string& user_id,
720     User::OAuthTokenStatus oauth_token_status) {
721   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
722 
723   DVLOG(1) << "Saving user OAuth token status in Local State";
724   User* user = FindUserAndModify(user_id);
725   if (user)
726     user->set_oauth_token_status(oauth_token_status);
727 
728   GetUserFlow(user_id)->HandleOAuthTokenStatusChange(oauth_token_status);
729 
730   // Do not update local state if data stored or cached outside the user's
731   // cryptohome is to be treated as ephemeral.
732   if (IsUserNonCryptohomeDataEphemeral(user_id))
733     return;
734 
735   PrefService* local_state = g_browser_process->local_state();
736 
737   DictionaryPrefUpdate oauth_status_update(local_state, kUserOAuthTokenStatus);
738   oauth_status_update->SetWithoutPathExpansion(user_id,
739       new base::FundamentalValue(static_cast<int>(oauth_token_status)));
740 }
741 
SaveForceOnlineSignin(const std::string & user_id,bool force_online_signin)742 void UserManagerImpl::SaveForceOnlineSignin(const std::string& user_id,
743                                             bool force_online_signin) {
744   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
745 
746   // Do not update local state if data stored or cached outside the user's
747   // cryptohome is to be treated as ephemeral.
748   if (IsUserNonCryptohomeDataEphemeral(user_id))
749     return;
750 
751   DictionaryPrefUpdate force_online_update(g_browser_process->local_state(),
752                                            kUserForceOnlineSignin);
753   force_online_update->SetBooleanWithoutPathExpansion(user_id,
754                                                       force_online_signin);
755 }
756 
SaveUserDisplayName(const std::string & user_id,const base::string16 & display_name)757 void UserManagerImpl::SaveUserDisplayName(const std::string& user_id,
758                                           const base::string16& display_name) {
759   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
760 
761   if (User* user = FindUserAndModify(user_id)) {
762     user->set_display_name(display_name);
763 
764     // Do not update local state if data stored or cached outside the user's
765     // cryptohome is to be treated as ephemeral.
766     if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
767       PrefService* local_state = g_browser_process->local_state();
768 
769       DictionaryPrefUpdate display_name_update(local_state, kUserDisplayName);
770       display_name_update->SetWithoutPathExpansion(
771           user_id,
772           new base::StringValue(display_name));
773 
774       supervised_user_manager_->UpdateManagerName(user_id, display_name);
775     }
776   }
777 }
778 
GetUserDisplayName(const std::string & user_id) const779 base::string16 UserManagerImpl::GetUserDisplayName(
780     const std::string& user_id) const {
781   const User* user = FindUser(user_id);
782   return user ? user->display_name() : base::string16();
783 }
784 
SaveUserDisplayEmail(const std::string & user_id,const std::string & display_email)785 void UserManagerImpl::SaveUserDisplayEmail(const std::string& user_id,
786                                            const std::string& display_email) {
787   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
788 
789   User* user = FindUserAndModify(user_id);
790   if (!user)
791     return;  // Ignore if there is no such user.
792 
793   user->set_display_email(display_email);
794 
795   // Do not update local state if data stored or cached outside the user's
796   // cryptohome is to be treated as ephemeral.
797   if (IsUserNonCryptohomeDataEphemeral(user_id))
798     return;
799 
800   PrefService* local_state = g_browser_process->local_state();
801 
802   DictionaryPrefUpdate display_email_update(local_state, kUserDisplayEmail);
803   display_email_update->SetWithoutPathExpansion(
804       user_id,
805       new base::StringValue(display_email));
806 }
807 
GetUserDisplayEmail(const std::string & user_id) const808 std::string UserManagerImpl::GetUserDisplayEmail(
809     const std::string& user_id) const {
810   const User* user = FindUser(user_id);
811   return user ? user->display_email() : user_id;
812 }
813 
UpdateUserAccountData(const std::string & user_id,const UserAccountData & account_data)814 void UserManagerImpl::UpdateUserAccountData(
815     const std::string& user_id,
816     const UserAccountData& account_data) {
817   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
818 
819   SaveUserDisplayName(user_id, account_data.display_name());
820 
821   if (User* user = FindUserAndModify(user_id)) {
822     base::string16 given_name = account_data.given_name();
823     user->set_given_name(given_name);
824     if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
825       PrefService* local_state = g_browser_process->local_state();
826 
827       DictionaryPrefUpdate given_name_update(local_state, kUserGivenName);
828       given_name_update->SetWithoutPathExpansion(
829           user_id,
830           new base::StringValue(given_name));
831     }
832   }
833 
834   UpdateUserAccountLocale(user_id, account_data.locale());
835 }
836 
837 // TODO(alemate): http://crbug.com/288941 : Respect preferred language list in
838 // the Google user profile.
839 //
840 // Returns true if callback will be called.
RespectLocalePreference(Profile * profile,const User * user,scoped_ptr<locale_util::SwitchLanguageCallback> callback) const841 bool UserManagerImpl::RespectLocalePreference(
842     Profile* profile,
843     const User* user,
844     scoped_ptr<locale_util::SwitchLanguageCallback> callback) const {
845   if (g_browser_process == NULL)
846     return false;
847   if ((user == NULL) || (user != GetPrimaryUser()) ||
848       (!user->is_profile_created()))
849     return false;
850 
851   // In case of Multi Profile mode we don't apply profile locale because it is
852   // unsafe.
853   if (GetLoggedInUsers().size() != 1)
854     return false;
855   const PrefService* prefs = profile->GetPrefs();
856   if (prefs == NULL)
857     return false;
858 
859   std::string pref_locale;
860   const std::string pref_app_locale =
861       prefs->GetString(prefs::kApplicationLocale);
862   const std::string pref_bkup_locale =
863       prefs->GetString(prefs::kApplicationLocaleBackup);
864 
865   pref_locale = pref_app_locale;
866   if (pref_locale.empty())
867     pref_locale = pref_bkup_locale;
868 
869   const std::string* account_locale = NULL;
870   if (pref_locale.empty() && user->has_gaia_account()) {
871     if (user->GetAccountLocale() == NULL)
872       return false;  // wait until Account profile is loaded.
873     account_locale = user->GetAccountLocale();
874     pref_locale = *account_locale;
875   }
876   const std::string global_app_locale =
877       g_browser_process->GetApplicationLocale();
878   if (pref_locale.empty())
879     pref_locale = global_app_locale;
880   DCHECK(!pref_locale.empty());
881   LOG(WARNING) << "RespectLocalePreference: "
882                << "app_locale='" << pref_app_locale << "', "
883                << "bkup_locale='" << pref_bkup_locale << "', "
884                << (account_locale != NULL
885                        ? (std::string("account_locale='") + (*account_locale) +
886                           "'. ")
887                        : (std::string("account_locale - unused. ")))
888                << " Selected '" << pref_locale << "'";
889   profile->ChangeAppLocale(pref_locale, Profile::APP_LOCALE_CHANGED_VIA_LOGIN);
890 
891   // Here we don't enable keyboard layouts for normal users. Input methods
892   // are set up when the user first logs in. Then the user may customize the
893   // input methods.  Hence changing input methods here, just because the user's
894   // UI language is different from the login screen UI language, is not
895   // desirable. Note that input method preferences are synced, so users can use
896   // their farovite input methods as soon as the preferences are synced.
897   //
898   // For Guest mode, user locale preferences will never get initialized.
899   // So input methods should be enabled somewhere.
900   const bool enable_layouts = UserManager::Get()->IsLoggedInAsGuest();
901   locale_util::SwitchLanguage(pref_locale,
902                               enable_layouts,
903                               false /* login_layouts_only */,
904                               callback.Pass());
905 
906   return true;
907 }
908 
StopPolicyObserverForTesting()909 void UserManagerImpl::StopPolicyObserverForTesting() {
910   avatar_policy_observer_.reset();
911   wallpaper_policy_observer_.reset();
912 }
913 
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)914 void UserManagerImpl::Observe(int type,
915                               const content::NotificationSource& source,
916                               const content::NotificationDetails& details) {
917   switch (type) {
918     case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED:
919       if (!device_local_account_policy_service_) {
920         policy::BrowserPolicyConnectorChromeOS* connector =
921             g_browser_process->platform_part()
922                 ->browser_policy_connector_chromeos();
923         device_local_account_policy_service_ =
924             connector->GetDeviceLocalAccountPolicyService();
925         if (device_local_account_policy_service_)
926           device_local_account_policy_service_->AddObserver(this);
927       }
928       RetrieveTrustedDevicePolicies();
929       UpdateOwnership();
930       break;
931     case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: {
932       Profile* profile = content::Details<Profile>(details).ptr();
933       if (IsUserLoggedIn() &&
934           !IsLoggedInAsGuest() &&
935           !IsLoggedInAsKioskApp()) {
936         if (IsLoggedInAsLocallyManagedUser())
937           SupervisedUserPasswordServiceFactory::GetForProfile(profile);
938         if (IsLoggedInAsRegularUser())
939           ManagerPasswordServiceFactory::GetForProfile(profile);
940 
941         if (!profile->IsOffTheRecord()) {
942           AuthSyncObserver* sync_observer =
943               AuthSyncObserverFactory::GetInstance()->GetForProfile(profile);
944           sync_observer->StartObserving();
945           multi_profile_user_controller_->StartObserving(profile);
946         }
947       }
948 
949       // Now that the user profile has been initialized and
950       // |GetNSSCertDatabaseForProfile| is safe to be used, get the NSS cert
951       // database for the primary user and start certificate loader with it.
952       if (IsUserLoggedIn() &&
953           GetPrimaryUser() &&
954           profile == GetProfileByUser(GetPrimaryUser()) &&
955           CertLoader::IsInitialized() &&
956           base::SysInfo::IsRunningOnChromeOS()) {
957         GetNSSCertDatabaseForProfile(profile,
958                                      base::Bind(&OnGetNSSCertDatabaseForUser));
959       }
960       break;
961     }
962     case chrome::NOTIFICATION_PROFILE_CREATED: {
963       Profile* profile = content::Source<Profile>(source).ptr();
964       User* user = GetUserByProfile(profile);
965       if (user != NULL)
966         user->set_profile_is_created();
967       // If there is pending user switch, do it now.
968       if (!pending_user_switch_.empty()) {
969         // Call SwitchActiveUser async because otherwise it may cause
970         // ProfileManager::GetProfile before the profile gets registered
971         // in ProfileManager. It happens in case of sync profile load when
972         // NOTIFICATION_PROFILE_CREATED is called synchronously.
973         base::MessageLoop::current()->PostTask(FROM_HERE,
974           base::Bind(&UserManagerImpl::SwitchActiveUser,
975                      base::Unretained(this),
976                      pending_user_switch_));
977         pending_user_switch_.clear();
978       }
979       break;
980     }
981     default:
982       NOTREACHED();
983   }
984 }
985 
OnExternalDataSet(const std::string & policy,const std::string & user_id)986 void UserManagerImpl::OnExternalDataSet(const std::string& policy,
987                                         const std::string& user_id) {
988   if (policy == policy::key::kUserAvatarImage)
989     GetUserImageManager(user_id)->OnExternalDataSet(policy);
990   else if (policy == policy::key::kWallpaperImage)
991     WallpaperManager::Get()->OnPolicySet(policy, user_id);
992   else
993     NOTREACHED();
994 }
995 
OnExternalDataCleared(const std::string & policy,const std::string & user_id)996 void UserManagerImpl::OnExternalDataCleared(const std::string& policy,
997                                             const std::string& user_id) {
998   if (policy == policy::key::kUserAvatarImage)
999     GetUserImageManager(user_id)->OnExternalDataCleared(policy);
1000   else if (policy == policy::key::kWallpaperImage)
1001     WallpaperManager::Get()->OnPolicyCleared(policy, user_id);
1002   else
1003     NOTREACHED();
1004 }
1005 
OnExternalDataFetched(const std::string & policy,const std::string & user_id,scoped_ptr<std::string> data)1006 void UserManagerImpl::OnExternalDataFetched(const std::string& policy,
1007                                             const std::string& user_id,
1008                                             scoped_ptr<std::string> data) {
1009   if (policy == policy::key::kUserAvatarImage)
1010     GetUserImageManager(user_id)->OnExternalDataFetched(policy, data.Pass());
1011   else if (policy == policy::key::kWallpaperImage)
1012     WallpaperManager::Get()->OnPolicyFetched(policy, user_id, data.Pass());
1013   else
1014     NOTREACHED();
1015 }
1016 
OnPolicyUpdated(const std::string & user_id)1017 void UserManagerImpl::OnPolicyUpdated(const std::string& user_id) {
1018   const User* user = FindUserInList(user_id);
1019   if (!user || user->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT)
1020     return;
1021   UpdatePublicAccountDisplayName(user_id);
1022   NotifyUserListChanged();
1023 }
1024 
OnDeviceLocalAccountsChanged()1025 void UserManagerImpl::OnDeviceLocalAccountsChanged() {
1026   // No action needed here, changes to the list of device-local accounts get
1027   // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
1028 }
1029 
IsCurrentUserOwner() const1030 bool UserManagerImpl::IsCurrentUserOwner() const {
1031   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1032   base::AutoLock lk(is_current_user_owner_lock_);
1033   return is_current_user_owner_;
1034 }
1035 
SetCurrentUserIsOwner(bool is_current_user_owner)1036 void UserManagerImpl::SetCurrentUserIsOwner(bool is_current_user_owner) {
1037   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1038   {
1039     base::AutoLock lk(is_current_user_owner_lock_);
1040     is_current_user_owner_ = is_current_user_owner;
1041   }
1042   UpdateLoginState();
1043 }
1044 
IsCurrentUserNew() const1045 bool UserManagerImpl::IsCurrentUserNew() const {
1046   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1047   return is_current_user_new_;
1048 }
1049 
IsCurrentUserNonCryptohomeDataEphemeral() const1050 bool UserManagerImpl::IsCurrentUserNonCryptohomeDataEphemeral() const {
1051   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1052   return IsUserLoggedIn() &&
1053          IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email());
1054 }
1055 
CanCurrentUserLock() const1056 bool UserManagerImpl::CanCurrentUserLock() const {
1057   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1058   return IsUserLoggedIn() && active_user_->can_lock() &&
1059       GetCurrentUserFlow()->CanLockScreen();
1060 }
1061 
IsUserLoggedIn() const1062 bool UserManagerImpl::IsUserLoggedIn() const {
1063   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1064   return active_user_;
1065 }
1066 
IsLoggedInAsRegularUser() const1067 bool UserManagerImpl::IsLoggedInAsRegularUser() const {
1068   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1069   return IsUserLoggedIn() &&
1070          active_user_->GetType() == User::USER_TYPE_REGULAR;
1071 }
1072 
IsLoggedInAsDemoUser() const1073 bool UserManagerImpl::IsLoggedInAsDemoUser() const {
1074   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1075   return IsUserLoggedIn() &&
1076          active_user_->GetType() == User::USER_TYPE_RETAIL_MODE;
1077 }
1078 
IsLoggedInAsPublicAccount() const1079 bool UserManagerImpl::IsLoggedInAsPublicAccount() const {
1080   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1081   return IsUserLoggedIn() &&
1082       active_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
1083 }
1084 
IsLoggedInAsGuest() const1085 bool UserManagerImpl::IsLoggedInAsGuest() const {
1086   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1087   return IsUserLoggedIn() &&
1088          active_user_->GetType() == User::USER_TYPE_GUEST;
1089 }
1090 
IsLoggedInAsLocallyManagedUser() const1091 bool UserManagerImpl::IsLoggedInAsLocallyManagedUser() const {
1092   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1093   return IsUserLoggedIn() &&
1094       active_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED;
1095 }
1096 
IsLoggedInAsKioskApp() const1097 bool UserManagerImpl::IsLoggedInAsKioskApp() const {
1098   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1099   return IsUserLoggedIn() &&
1100       active_user_->GetType() == User::USER_TYPE_KIOSK_APP;
1101 }
1102 
IsLoggedInAsStub() const1103 bool UserManagerImpl::IsLoggedInAsStub() const {
1104   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1105   return IsUserLoggedIn() && active_user_->email() == kStubUser;
1106 }
1107 
IsSessionStarted() const1108 bool UserManagerImpl::IsSessionStarted() const {
1109   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1110   return session_started_;
1111 }
1112 
UserSessionsRestored() const1113 bool UserManagerImpl::UserSessionsRestored() const {
1114   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1115   return user_sessions_restored_;
1116 }
1117 
HasBrowserRestarted() const1118 bool UserManagerImpl::HasBrowserRestarted() const {
1119   CommandLine* command_line = CommandLine::ForCurrentProcess();
1120   return base::SysInfo::IsRunningOnChromeOS() &&
1121          command_line->HasSwitch(switches::kLoginUser) &&
1122          !command_line->HasSwitch(switches::kLoginPassword);
1123 }
1124 
IsUserNonCryptohomeDataEphemeral(const std::string & user_id) const1125 bool UserManagerImpl::IsUserNonCryptohomeDataEphemeral(
1126     const std::string& user_id) const {
1127   // Data belonging to the guest, retail mode and stub users is always
1128   // ephemeral.
1129   if (user_id == UserManager::kGuestUserName ||
1130       user_id == UserManager::kRetailModeUserName ||
1131       user_id == kStubUser) {
1132     return true;
1133   }
1134 
1135   // Data belonging to the owner, anyone found on the user list and obsolete
1136   // public accounts whose data has not been removed yet is not ephemeral.
1137   if (user_id == owner_email_  || UserExistsInList(user_id) ||
1138       user_id == g_browser_process->local_state()->
1139           GetString(kPublicAccountPendingDataRemoval)) {
1140     return false;
1141   }
1142 
1143   // Data belonging to the currently logged-in user is ephemeral when:
1144   // a) The user logged into a regular account while the ephemeral users policy
1145   //    was enabled.
1146   //    - or -
1147   // b) The user logged into any other account type.
1148   if (IsUserLoggedIn() && (user_id == GetLoggedInUser()->email()) &&
1149       (is_current_user_ephemeral_regular_user_ || !IsLoggedInAsRegularUser())) {
1150     return true;
1151   }
1152 
1153   // Data belonging to any other user is ephemeral when:
1154   // a) Going through the regular login flow and the ephemeral users policy is
1155   //    enabled.
1156   //    - or -
1157   // b) The browser is restarting after a crash.
1158   return AreEphemeralUsersEnabled() || HasBrowserRestarted();
1159 }
1160 
AddObserver(UserManager::Observer * obs)1161 void UserManagerImpl::AddObserver(UserManager::Observer* obs) {
1162   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1163   observer_list_.AddObserver(obs);
1164 }
1165 
RemoveObserver(UserManager::Observer * obs)1166 void UserManagerImpl::RemoveObserver(UserManager::Observer* obs) {
1167   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1168   observer_list_.RemoveObserver(obs);
1169 }
1170 
AddSessionStateObserver(UserManager::UserSessionStateObserver * obs)1171 void UserManagerImpl::AddSessionStateObserver(
1172     UserManager::UserSessionStateObserver* obs) {
1173   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1174   session_state_observer_list_.AddObserver(obs);
1175 }
1176 
RemoveSessionStateObserver(UserManager::UserSessionStateObserver * obs)1177 void UserManagerImpl::RemoveSessionStateObserver(
1178     UserManager::UserSessionStateObserver* obs) {
1179   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1180   session_state_observer_list_.RemoveObserver(obs);
1181 }
1182 
NotifyLocalStateChanged()1183 void UserManagerImpl::NotifyLocalStateChanged() {
1184   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1185   FOR_EACH_OBSERVER(UserManager::Observer, observer_list_,
1186                     LocalStateChanged(this));
1187 }
1188 
OnProfilePrepared(Profile * profile)1189 void UserManagerImpl::OnProfilePrepared(Profile* profile) {
1190   LoginUtils::Get()->DoBrowserLaunch(profile,
1191                                      NULL);     // host_, not needed here
1192 
1193   if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) {
1194     // Did not log in (we crashed or are debugging), need to restore Sync.
1195     // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
1196     // users once it is fully multi-profile aware. http://crbug.com/238987
1197     // For now if we have other user pending sessions they'll override OAuth
1198     // session restore for previous users.
1199     SessionManager::GetInstance()->RestoreAuthenticationSession(profile);
1200   }
1201 
1202   // Restore other user sessions if any.
1203   RestorePendingUserSessions();
1204 }
1205 
EnsureUsersLoaded()1206 void UserManagerImpl::EnsureUsersLoaded() {
1207   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1208   if (!g_browser_process || !g_browser_process->local_state())
1209     return;
1210 
1211   if (user_loading_stage_ != STAGE_NOT_LOADED)
1212     return;
1213   user_loading_stage_ = STAGE_LOADING;
1214   // Clean up user list first. All code down the path should be synchronous,
1215   // so that local state after transaction rollback is in consistent state.
1216   // This process also should not trigger EnsureUsersLoaded again.
1217   if (supervised_user_manager_->HasFailedUserCreationTransaction())
1218     supervised_user_manager_->RollbackUserCreationTransaction();
1219 
1220   PrefService* local_state = g_browser_process->local_state();
1221   const base::ListValue* prefs_regular_users =
1222       local_state->GetList(kRegularUsers);
1223   const base::ListValue* prefs_public_sessions =
1224       local_state->GetList(kPublicAccounts);
1225   const base::DictionaryValue* prefs_display_names =
1226       local_state->GetDictionary(kUserDisplayName);
1227   const base::DictionaryValue* prefs_given_names =
1228       local_state->GetDictionary(kUserGivenName);
1229   const base::DictionaryValue* prefs_display_emails =
1230       local_state->GetDictionary(kUserDisplayEmail);
1231 
1232   // Load public sessions first.
1233   std::vector<std::string> public_sessions;
1234   std::set<std::string> public_sessions_set;
1235   ParseUserList(*prefs_public_sessions, std::set<std::string>(),
1236                 &public_sessions, &public_sessions_set);
1237   for (std::vector<std::string>::const_iterator it = public_sessions.begin();
1238        it != public_sessions.end(); ++it) {
1239     users_.push_back(User::CreatePublicAccountUser(*it));
1240     UpdatePublicAccountDisplayName(*it);
1241   }
1242 
1243   // Load regular users and locally managed users.
1244   std::vector<std::string> regular_users;
1245   std::set<std::string> regular_users_set;
1246   ParseUserList(*prefs_regular_users, public_sessions_set,
1247                 &regular_users, &regular_users_set);
1248   for (std::vector<std::string>::const_iterator it = regular_users.begin();
1249        it != regular_users.end(); ++it) {
1250     User* user = NULL;
1251     const std::string domain = gaia::ExtractDomainName(*it);
1252     if (domain == UserManager::kLocallyManagedUserDomain)
1253       user = User::CreateLocallyManagedUser(*it);
1254     else
1255       user = User::CreateRegularUser(*it);
1256     user->set_oauth_token_status(LoadUserOAuthStatus(*it));
1257     user->set_force_online_signin(LoadForceOnlineSignin(*it));
1258     users_.push_back(user);
1259 
1260     base::string16 display_name;
1261     if (prefs_display_names->GetStringWithoutPathExpansion(*it,
1262                                                            &display_name)) {
1263       user->set_display_name(display_name);
1264     }
1265 
1266     base::string16 given_name;
1267     if (prefs_given_names->GetStringWithoutPathExpansion(*it, &given_name)) {
1268       user->set_given_name(given_name);
1269     }
1270 
1271     std::string display_email;
1272     if (prefs_display_emails->GetStringWithoutPathExpansion(*it,
1273                                                             &display_email)) {
1274       user->set_display_email(display_email);
1275     }
1276   }
1277 
1278   user_loading_stage_ = STAGE_LOADED;
1279 
1280   for (UserList::iterator ui = users_.begin(), ue = users_.end();
1281        ui != ue; ++ui) {
1282     GetUserImageManager((*ui)->email())->LoadUserImage();
1283   }
1284 }
1285 
RetrieveTrustedDevicePolicies()1286 void UserManagerImpl::RetrieveTrustedDevicePolicies() {
1287   ephemeral_users_enabled_ = false;
1288   owner_email_.clear();
1289 
1290   // Schedule a callback if device policy has not yet been verified.
1291   if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
1292           base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
1293                      base::Unretained(this)))) {
1294     return;
1295   }
1296 
1297   cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
1298                              &ephemeral_users_enabled_);
1299   cros_settings_->GetString(kDeviceOwner, &owner_email_);
1300 
1301   EnsureUsersLoaded();
1302 
1303   bool changed = UpdateAndCleanUpPublicAccounts(
1304       policy::GetDeviceLocalAccounts(cros_settings_));
1305 
1306   // If ephemeral users are enabled and we are on the login screen, take this
1307   // opportunity to clean up by removing all regular users except the owner.
1308   if (ephemeral_users_enabled_ && !IsUserLoggedIn()) {
1309     ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1310                                       kRegularUsers);
1311     prefs_users_update->Clear();
1312     for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1313       const std::string user_email = (*it)->email();
1314       if ((*it)->GetType() == User::USER_TYPE_REGULAR &&
1315           user_email != owner_email_) {
1316         RemoveNonCryptohomeData(user_email);
1317         DeleteUser(*it);
1318         it = users_.erase(it);
1319         changed = true;
1320       } else {
1321         if ((*it)->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT)
1322           prefs_users_update->Append(new base::StringValue(user_email));
1323         ++it;
1324       }
1325     }
1326   }
1327 
1328   if (changed)
1329     NotifyUserListChanged();
1330 }
1331 
AreEphemeralUsersEnabled() const1332 bool UserManagerImpl::AreEphemeralUsersEnabled() const {
1333   policy::BrowserPolicyConnectorChromeOS* connector =
1334       g_browser_process->platform_part()->browser_policy_connector_chromeos();
1335   return ephemeral_users_enabled_ &&
1336          (connector->IsEnterpriseManaged() || !owner_email_.empty());
1337 }
1338 
GetUsersAndModify()1339 UserList& UserManagerImpl::GetUsersAndModify() {
1340   EnsureUsersLoaded();
1341   return users_;
1342 }
1343 
FindUserInList(const std::string & user_id) const1344 const User* UserManagerImpl::FindUserInList(const std::string& user_id) const {
1345   const UserList& users = GetUsers();
1346   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
1347     if ((*it)->email() == user_id)
1348       return *it;
1349   }
1350   return NULL;
1351 }
1352 
UserExistsInList(const std::string & user_id) const1353 const bool UserManagerImpl::UserExistsInList(const std::string& user_id) const {
1354   PrefService* local_state = g_browser_process->local_state();
1355   const base::ListValue* user_list = local_state->GetList(kRegularUsers);
1356   for (size_t i = 0; i < user_list->GetSize(); ++i) {
1357     std::string email;
1358     if (user_list->GetString(i, &email) && (user_id == email))
1359       return true;
1360   }
1361   return false;
1362 }
1363 
FindUserInListAndModify(const std::string & user_id)1364 User* UserManagerImpl::FindUserInListAndModify(const std::string& user_id) {
1365   UserList& users = GetUsersAndModify();
1366   for (UserList::iterator it = users.begin(); it != users.end(); ++it) {
1367     if ((*it)->email() == user_id)
1368       return *it;
1369   }
1370   return NULL;
1371 }
1372 
GuestUserLoggedIn()1373 void UserManagerImpl::GuestUserLoggedIn() {
1374   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1375   active_user_ = User::CreateGuestUser();
1376   // TODO(nkostylev): Add support for passing guest session cryptohome
1377   // mount point. Legacy (--login-profile) value will be used for now.
1378   // http://crosbug.com/230859
1379   active_user_->SetStubImage(User::kInvalidImageIndex, false);
1380   // Initializes wallpaper after active_user_ is set.
1381   WallpaperManager::Get()->SetUserWallpaperNow(UserManager::kGuestUserName);
1382 }
1383 
AddUserRecord(User * user)1384 void UserManagerImpl::AddUserRecord(User* user) {
1385   // Add the user to the front of the user list.
1386   ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1387                                     kRegularUsers);
1388   prefs_users_update->Insert(0, new base::StringValue(user->email()));
1389   users_.insert(users_.begin(), user);
1390 }
1391 
RegularUserLoggedIn(const std::string & user_id)1392 void UserManagerImpl::RegularUserLoggedIn(const std::string& user_id) {
1393   // Remove the user from the user list.
1394   active_user_ = RemoveRegularOrLocallyManagedUserFromList(user_id);
1395 
1396   // If the user was not found on the user list, create a new user.
1397   is_current_user_new_ = !active_user_;
1398   if (!active_user_) {
1399     active_user_ = User::CreateRegularUser(user_id);
1400     active_user_->set_oauth_token_status(LoadUserOAuthStatus(user_id));
1401     SaveUserDisplayName(active_user_->email(),
1402                         base::UTF8ToUTF16(active_user_->GetAccountName(true)));
1403     WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1404   }
1405 
1406   AddUserRecord(active_user_);
1407 
1408   GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, false);
1409 
1410   WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1411 
1412   // Make sure that new data is persisted to Local State.
1413   g_browser_process->local_state()->CommitPendingWrite();
1414 }
1415 
RegularUserLoggedInAsEphemeral(const std::string & user_id)1416 void UserManagerImpl::RegularUserLoggedInAsEphemeral(
1417     const std::string& user_id) {
1418   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1419   is_current_user_new_ = true;
1420   is_current_user_ephemeral_regular_user_ = true;
1421   active_user_ = User::CreateRegularUser(user_id);
1422   GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, false);
1423   WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1424 }
1425 
LocallyManagedUserLoggedIn(const std::string & user_id)1426 void UserManagerImpl::LocallyManagedUserLoggedIn(
1427     const std::string& user_id) {
1428   // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
1429 
1430   // Remove the user from the user list.
1431   active_user_ = RemoveRegularOrLocallyManagedUserFromList(user_id);
1432   // If the user was not found on the user list, create a new user.
1433   if (!active_user_) {
1434     is_current_user_new_ = true;
1435     active_user_ = User::CreateLocallyManagedUser(user_id);
1436     // Leaving OAuth token status at the default state = unknown.
1437     WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1438   } else {
1439     if (supervised_user_manager_->CheckForFirstRun(user_id)) {
1440       is_current_user_new_ = true;
1441       WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1442     } else {
1443       is_current_user_new_ = false;
1444     }
1445   }
1446 
1447   // Add the user to the front of the user list.
1448   ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1449                                     kRegularUsers);
1450   prefs_users_update->Insert(0, new base::StringValue(user_id));
1451   users_.insert(users_.begin(), active_user_);
1452 
1453   // Now that user is in the list, save display name.
1454   if (is_current_user_new_) {
1455     SaveUserDisplayName(active_user_->email(),
1456                         active_user_->GetDisplayName());
1457   }
1458 
1459   GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, true);
1460   WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1461 
1462   // Make sure that new data is persisted to Local State.
1463   g_browser_process->local_state()->CommitPendingWrite();
1464 }
1465 
PublicAccountUserLoggedIn(User * user)1466 void UserManagerImpl::PublicAccountUserLoggedIn(User* user) {
1467   is_current_user_new_ = true;
1468   active_user_ = user;
1469   // The UserImageManager chooses a random avatar picture when a user logs in
1470   // for the first time. Tell the UserImageManager that this user is not new to
1471   // prevent the avatar from getting changed.
1472   GetUserImageManager(user->email())->UserLoggedIn(false, true);
1473   WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1474 }
1475 
KioskAppLoggedIn(const std::string & app_id)1476 void UserManagerImpl::KioskAppLoggedIn(const std::string& app_id) {
1477   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1478   policy::DeviceLocalAccount::Type device_local_account_type;
1479   DCHECK(policy::IsDeviceLocalAccountUser(app_id,
1480                                           &device_local_account_type));
1481   DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
1482             device_local_account_type);
1483 
1484   active_user_ = User::CreateKioskAppUser(app_id);
1485   active_user_->SetStubImage(User::kInvalidImageIndex, false);
1486 
1487   WallpaperManager::Get()->SetUserWallpaperNow(app_id);
1488 
1489   // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
1490   // the kiosk_app_id in these objects, removing the need to re-parse the
1491   // device-local account list here to extract the kiosk_app_id.
1492   const std::vector<policy::DeviceLocalAccount> device_local_accounts =
1493       policy::GetDeviceLocalAccounts(cros_settings_);
1494   const policy::DeviceLocalAccount* account = NULL;
1495   for (std::vector<policy::DeviceLocalAccount>::const_iterator
1496            it = device_local_accounts.begin();
1497        it != device_local_accounts.end(); ++it) {
1498     if (it->user_id == app_id) {
1499       account = &*it;
1500       break;
1501     }
1502   }
1503   std::string kiosk_app_id;
1504   if (account) {
1505     kiosk_app_id = account->kiosk_app_id;
1506   } else {
1507     LOG(ERROR) << "Logged into nonexistent kiosk-app account: " << app_id;
1508     NOTREACHED();
1509   }
1510 
1511   CommandLine* command_line = CommandLine::ForCurrentProcess();
1512   command_line->AppendSwitch(::switches::kForceAppMode);
1513   command_line->AppendSwitchASCII(::switches::kAppId, kiosk_app_id);
1514 
1515   // Disable window animation since kiosk app runs in a single full screen
1516   // window and window animation causes start-up janks.
1517   command_line->AppendSwitch(
1518       wm::switches::kWindowAnimationsDisabled);
1519 }
1520 
DemoAccountLoggedIn()1521 void UserManagerImpl::DemoAccountLoggedIn() {
1522   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1523   active_user_ = User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName);
1524   active_user_->SetStubImage(User::kInvalidImageIndex, false);
1525   WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName);
1526 
1527   CommandLine* command_line = CommandLine::ForCurrentProcess();
1528   command_line->AppendSwitch(::switches::kForceAppMode);
1529   command_line->AppendSwitchASCII(::switches::kAppId,
1530                                   DemoAppLauncher::kDemoAppId);
1531 
1532   // Disable window animation since the demo app runs in a single full screen
1533   // window and window animation causes start-up janks.
1534   CommandLine::ForCurrentProcess()->AppendSwitch(
1535       wm::switches::kWindowAnimationsDisabled);
1536 }
1537 
RetailModeUserLoggedIn()1538 void UserManagerImpl::RetailModeUserLoggedIn() {
1539   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1540   is_current_user_new_ = true;
1541   active_user_ = User::CreateRetailModeUser();
1542   GetUserImageManager(UserManager::kRetailModeUserName)->UserLoggedIn(
1543       is_current_user_new_,
1544       true);
1545   WallpaperManager::Get()->SetUserWallpaperNow(
1546       UserManager::kRetailModeUserName);
1547 }
1548 
NotifyOnLogin()1549 void UserManagerImpl::NotifyOnLogin() {
1550   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1551 
1552   // Override user homedir, check for ProfileManager being initialized as
1553   // it may not exist in unit tests.
1554   if (g_browser_process->profile_manager()) {
1555     if (GetLoggedInUsers().size() == 1) {
1556       base::FilePath homedir = ProfileHelper::GetProfilePathByUserIdHash(
1557           primary_user_->username_hash());
1558       // This path has been either created by cryptohome (on real Chrome OS
1559       // device) or by ProfileManager (on chromeos=1 desktop builds).
1560       PathService::OverrideAndCreateIfNeeded(base::DIR_HOME,
1561                                              homedir,
1562                                              true /* path is absolute */,
1563                                              false /* don't create */);
1564     }
1565   }
1566 
1567   UpdateNumberOfUsers();
1568   NotifyActiveUserHashChanged(active_user_->username_hash());
1569   NotifyActiveUserChanged(active_user_);
1570   UpdateLoginState();
1571 
1572   // TODO(nkostylev): Deprecate this notification in favor of
1573   // ActiveUserChanged() observer call.
1574   content::NotificationService::current()->Notify(
1575       chrome::NOTIFICATION_LOGIN_USER_CHANGED,
1576       content::Source<UserManager>(this),
1577       content::Details<const User>(active_user_));
1578 
1579   // Owner must be first user in session. DeviceSettingsService can't deal with
1580   // multiple user and will mix up ownership, crbug.com/230018.
1581   if (GetLoggedInUsers().size() == 1) {
1582     OwnerSettingsServiceFactory::GetInstance()->SetUsername(
1583         active_user_->email());
1584     if (NetworkPortalDetector::IsInitialized()) {
1585       NetworkPortalDetector::Get()->SetStrategy(
1586           PortalDetectorStrategy::STRATEGY_ID_SESSION);
1587     }
1588   }
1589 }
1590 
LoadUserOAuthStatus(const std::string & user_id) const1591 User::OAuthTokenStatus UserManagerImpl::LoadUserOAuthStatus(
1592     const std::string& user_id) const {
1593   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1594 
1595   PrefService* local_state = g_browser_process->local_state();
1596   const base::DictionaryValue* prefs_oauth_status =
1597       local_state->GetDictionary(kUserOAuthTokenStatus);
1598   int oauth_token_status = User::OAUTH_TOKEN_STATUS_UNKNOWN;
1599   if (prefs_oauth_status &&
1600       prefs_oauth_status->GetIntegerWithoutPathExpansion(
1601           user_id, &oauth_token_status)) {
1602     User::OAuthTokenStatus result =
1603         static_cast<User::OAuthTokenStatus>(oauth_token_status);
1604     if (result == User::OAUTH2_TOKEN_STATUS_INVALID)
1605       GetUserFlow(user_id)->HandleOAuthTokenStatusChange(result);
1606     return result;
1607   }
1608   return User::OAUTH_TOKEN_STATUS_UNKNOWN;
1609 }
1610 
LoadForceOnlineSignin(const std::string & user_id) const1611 bool UserManagerImpl::LoadForceOnlineSignin(const std::string& user_id) const {
1612   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1613 
1614   PrefService* local_state = g_browser_process->local_state();
1615   const base::DictionaryValue* prefs_force_online =
1616       local_state->GetDictionary(kUserForceOnlineSignin);
1617   bool force_online_signin = false;
1618   if (prefs_force_online) {
1619     prefs_force_online->GetBooleanWithoutPathExpansion(user_id,
1620                                                        &force_online_signin);
1621   }
1622   return force_online_signin;
1623 }
1624 
UpdateOwnership()1625 void UserManagerImpl::UpdateOwnership() {
1626   bool is_owner = DeviceSettingsService::Get()->HasPrivateOwnerKey();
1627   VLOG(1) << "Current user " << (is_owner ? "is owner" : "is not owner");
1628 
1629   SetCurrentUserIsOwner(is_owner);
1630 }
1631 
RemoveNonCryptohomeData(const std::string & user_id)1632 void UserManagerImpl::RemoveNonCryptohomeData(const std::string& user_id) {
1633   WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id);
1634   GetUserImageManager(user_id)->DeleteUserImage();
1635 
1636   PrefService* prefs = g_browser_process->local_state();
1637   DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
1638   prefs_display_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1639 
1640   DictionaryPrefUpdate prefs_given_name_update(prefs, kUserGivenName);
1641   prefs_given_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1642 
1643   DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
1644   prefs_display_email_update->RemoveWithoutPathExpansion(user_id, NULL);
1645 
1646   DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
1647   prefs_oauth_update->RemoveWithoutPathExpansion(user_id, NULL);
1648 
1649   DictionaryPrefUpdate prefs_force_online_update(prefs, kUserForceOnlineSignin);
1650   prefs_force_online_update->RemoveWithoutPathExpansion(user_id, NULL);
1651 
1652   supervised_user_manager_->RemoveNonCryptohomeData(user_id);
1653 
1654   multi_profile_user_controller_->RemoveCachedValues(user_id);
1655 }
1656 
RemoveRegularOrLocallyManagedUserFromList(const std::string & user_id)1657 User* UserManagerImpl::RemoveRegularOrLocallyManagedUserFromList(
1658     const std::string& user_id) {
1659   ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1660                                     kRegularUsers);
1661   prefs_users_update->Clear();
1662   User* user = NULL;
1663   for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1664     const std::string user_email = (*it)->email();
1665     if (user_email == user_id) {
1666       user = *it;
1667       it = users_.erase(it);
1668     } else {
1669       if ((*it)->GetType() == User::USER_TYPE_REGULAR ||
1670           (*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) {
1671         prefs_users_update->Append(new base::StringValue(user_email));
1672       }
1673       ++it;
1674     }
1675   }
1676   return user;
1677 }
1678 
CleanUpPublicAccountNonCryptohomeDataPendingRemoval()1679 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
1680   PrefService* local_state = g_browser_process->local_state();
1681   const std::string public_account_pending_data_removal =
1682       local_state->GetString(kPublicAccountPendingDataRemoval);
1683   if (public_account_pending_data_removal.empty() ||
1684       (IsUserLoggedIn() &&
1685        public_account_pending_data_removal == GetActiveUser()->email())) {
1686     return;
1687   }
1688 
1689   RemoveNonCryptohomeData(public_account_pending_data_removal);
1690   local_state->ClearPref(kPublicAccountPendingDataRemoval);
1691 }
1692 
CleanUpPublicAccountNonCryptohomeData(const std::vector<std::string> & old_public_accounts)1693 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
1694     const std::vector<std::string>& old_public_accounts) {
1695   std::set<std::string> users;
1696   for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it)
1697     users.insert((*it)->email());
1698 
1699   // If the user is logged into a public account that has been removed from the
1700   // user list, mark the account's data as pending removal after logout.
1701   if (IsLoggedInAsPublicAccount()) {
1702     const std::string active_user_id = GetActiveUser()->email();
1703     if (users.find(active_user_id) == users.end()) {
1704       g_browser_process->local_state()->SetString(
1705           kPublicAccountPendingDataRemoval, active_user_id);
1706       users.insert(active_user_id);
1707     }
1708   }
1709 
1710   // Remove the data belonging to any other public accounts that are no longer
1711   // found on the user list.
1712   for (std::vector<std::string>::const_iterator
1713            it = old_public_accounts.begin();
1714        it != old_public_accounts.end(); ++it) {
1715     if (users.find(*it) == users.end())
1716       RemoveNonCryptohomeData(*it);
1717   }
1718 }
1719 
UpdateAndCleanUpPublicAccounts(const std::vector<policy::DeviceLocalAccount> & device_local_accounts)1720 bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
1721     const std::vector<policy::DeviceLocalAccount>& device_local_accounts) {
1722   // Try to remove any public account data marked as pending removal.
1723   CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
1724 
1725   // Get the current list of public accounts.
1726   std::vector<std::string> old_public_accounts;
1727   for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it) {
1728     if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT)
1729       old_public_accounts.push_back((*it)->email());
1730   }
1731 
1732   // Get the new list of public accounts from policy.
1733   std::vector<std::string> new_public_accounts;
1734   for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
1735            device_local_accounts.begin();
1736        it != device_local_accounts.end(); ++it) {
1737     // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
1738     // standard login framework: http://crbug.com/234694
1739     if (it->type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
1740       new_public_accounts.push_back(it->user_id);
1741   }
1742 
1743   // If the list of public accounts has not changed, return.
1744   if (new_public_accounts.size() == old_public_accounts.size()) {
1745     bool changed = false;
1746     for (size_t i = 0; i < new_public_accounts.size(); ++i) {
1747       if (new_public_accounts[i] != old_public_accounts[i]) {
1748         changed = true;
1749         break;
1750       }
1751     }
1752     if (!changed)
1753       return false;
1754   }
1755 
1756   // Persist the new list of public accounts in a pref.
1757   ListPrefUpdate prefs_public_accounts_update(g_browser_process->local_state(),
1758                                               kPublicAccounts);
1759   prefs_public_accounts_update->Clear();
1760   for (std::vector<std::string>::const_iterator it =
1761            new_public_accounts.begin();
1762        it != new_public_accounts.end(); ++it) {
1763     prefs_public_accounts_update->AppendString(*it);
1764   }
1765 
1766   // Remove the old public accounts from the user list.
1767   for (UserList::iterator it = users_.begin(); it != users_.end();) {
1768     if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
1769       if (*it != GetLoggedInUser())
1770         DeleteUser(*it);
1771       it = users_.erase(it);
1772     } else {
1773       ++it;
1774     }
1775   }
1776 
1777   // Add the new public accounts to the front of the user list.
1778   for (std::vector<std::string>::const_reverse_iterator it =
1779            new_public_accounts.rbegin();
1780        it != new_public_accounts.rend(); ++it) {
1781     if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email())
1782       users_.insert(users_.begin(), GetLoggedInUser());
1783     else
1784       users_.insert(users_.begin(), User::CreatePublicAccountUser(*it));
1785     UpdatePublicAccountDisplayName(*it);
1786   }
1787 
1788   for (UserList::iterator ui = users_.begin(),
1789                           ue = users_.begin() + new_public_accounts.size();
1790        ui != ue; ++ui) {
1791     GetUserImageManager((*ui)->email())->LoadUserImage();
1792   }
1793 
1794   // Remove data belonging to public accounts that are no longer found on the
1795   // user list.
1796   CleanUpPublicAccountNonCryptohomeData(old_public_accounts);
1797 
1798   return true;
1799 }
1800 
UpdatePublicAccountDisplayName(const std::string & user_id)1801 void UserManagerImpl::UpdatePublicAccountDisplayName(
1802     const std::string& user_id) {
1803   std::string display_name;
1804 
1805   if (device_local_account_policy_service_) {
1806     policy::DeviceLocalAccountPolicyBroker* broker =
1807         device_local_account_policy_service_->GetBrokerForUser(user_id);
1808     if (broker)
1809       display_name = broker->GetDisplayName();
1810   }
1811 
1812   // Set or clear the display name.
1813   SaveUserDisplayName(user_id, base::UTF8ToUTF16(display_name));
1814 }
1815 
GetCurrentUserFlow() const1816 UserFlow* UserManagerImpl::GetCurrentUserFlow() const {
1817   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1818   if (!IsUserLoggedIn())
1819     return GetDefaultUserFlow();
1820   return GetUserFlow(GetLoggedInUser()->email());
1821 }
1822 
GetUserFlow(const std::string & user_id) const1823 UserFlow* UserManagerImpl::GetUserFlow(const std::string& user_id) const {
1824   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1825   FlowMap::const_iterator it = specific_flows_.find(user_id);
1826   if (it != specific_flows_.end())
1827     return it->second;
1828   return GetDefaultUserFlow();
1829 }
1830 
SetUserFlow(const std::string & user_id,UserFlow * flow)1831 void UserManagerImpl::SetUserFlow(const std::string& user_id, UserFlow* flow) {
1832   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1833   ResetUserFlow(user_id);
1834   specific_flows_[user_id] = flow;
1835 }
1836 
ResetUserFlow(const std::string & user_id)1837 void UserManagerImpl::ResetUserFlow(const std::string& user_id) {
1838   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1839   FlowMap::iterator it = specific_flows_.find(user_id);
1840   if (it != specific_flows_.end()) {
1841     delete it->second;
1842     specific_flows_.erase(it);
1843   }
1844 }
1845 
GetAppModeChromeClientOAuthInfo(std::string * chrome_client_id,std::string * chrome_client_secret)1846 bool UserManagerImpl::GetAppModeChromeClientOAuthInfo(
1847     std::string* chrome_client_id, std::string* chrome_client_secret) {
1848   if (!chrome::IsRunningInForcedAppMode() ||
1849       chrome_client_id_.empty() ||
1850       chrome_client_secret_.empty()) {
1851     return false;
1852   }
1853 
1854   *chrome_client_id = chrome_client_id_;
1855   *chrome_client_secret = chrome_client_secret_;
1856   return true;
1857 }
1858 
SetAppModeChromeClientOAuthInfo(const std::string & chrome_client_id,const std::string & chrome_client_secret)1859 void UserManagerImpl::SetAppModeChromeClientOAuthInfo(
1860     const std::string& chrome_client_id,
1861     const std::string& chrome_client_secret) {
1862   if (!chrome::IsRunningInForcedAppMode())
1863     return;
1864 
1865   chrome_client_id_ = chrome_client_id;
1866   chrome_client_secret_ = chrome_client_secret;
1867 }
1868 
AreLocallyManagedUsersAllowed() const1869 bool UserManagerImpl::AreLocallyManagedUsersAllowed() const {
1870   bool locally_managed_users_allowed = false;
1871   cros_settings_->GetBoolean(kAccountsPrefSupervisedUsersEnabled,
1872                              &locally_managed_users_allowed);
1873   return locally_managed_users_allowed;
1874 }
1875 
GetUserProfileDir(const std::string & user_id) const1876 base::FilePath UserManagerImpl::GetUserProfileDir(
1877     const std::string& user_id) const {
1878   // TODO(dpolukhin): Remove Chrome OS specific profile path logic from
1879   // ProfileManager and use only this function to construct profile path.
1880   // TODO(nkostylev): Cleanup profile dir related code paths crbug.com/294233
1881   base::FilePath profile_dir;
1882   const User* user = FindUser(user_id);
1883   if (user && !user->username_hash().empty())
1884     profile_dir = ProfileHelper::GetUserProfileDir(user->username_hash());
1885 
1886   ProfileManager* profile_manager = g_browser_process->profile_manager();
1887   profile_dir = profile_manager->user_data_dir().Append(profile_dir);
1888 
1889   return profile_dir;
1890 }
1891 
GetDefaultUserFlow() const1892 UserFlow* UserManagerImpl::GetDefaultUserFlow() const {
1893   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1894   if (!default_flow_.get())
1895     default_flow_.reset(new DefaultUserFlow());
1896   return default_flow_.get();
1897 }
1898 
NotifyUserListChanged()1899 void UserManagerImpl::NotifyUserListChanged() {
1900   content::NotificationService::current()->Notify(
1901       chrome::NOTIFICATION_USER_LIST_CHANGED,
1902       content::Source<UserManager>(this),
1903       content::NotificationService::NoDetails());
1904 }
1905 
NotifyActiveUserChanged(const User * active_user)1906 void UserManagerImpl::NotifyActiveUserChanged(const User* active_user) {
1907   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1908   FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1909                     session_state_observer_list_,
1910                     ActiveUserChanged(active_user));
1911 }
1912 
NotifyUserAddedToSession(const User * added_user)1913 void UserManagerImpl::NotifyUserAddedToSession(const User* added_user) {
1914   UpdateNumberOfUsers();
1915   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1916   FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1917                     session_state_observer_list_,
1918                     UserAddedToSession(added_user));
1919 }
1920 
NotifyActiveUserHashChanged(const std::string & hash)1921 void UserManagerImpl::NotifyActiveUserHashChanged(const std::string& hash) {
1922   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1923   FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1924                     session_state_observer_list_,
1925                     ActiveUserHashChanged(hash));
1926 }
1927 
NotifyPendingUserSessionsRestoreFinished()1928 void UserManagerImpl::NotifyPendingUserSessionsRestoreFinished() {
1929   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1930   user_sessions_restored_ = true;
1931   FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1932                     session_state_observer_list_,
1933                     PendingUserSessionsRestoreFinished());
1934 }
1935 
UpdateLoginState()1936 void UserManagerImpl::UpdateLoginState() {
1937   if (!LoginState::IsInitialized())
1938     return;  // LoginState may not be intialized in tests.
1939   LoginState::LoggedInState logged_in_state;
1940   logged_in_state = active_user_ ? LoginState::LOGGED_IN_ACTIVE
1941       : LoginState::LOGGED_IN_NONE;
1942 
1943   LoginState::LoggedInUserType login_user_type;
1944   if (logged_in_state == LoginState::LOGGED_IN_NONE)
1945     login_user_type = LoginState::LOGGED_IN_USER_NONE;
1946   else if (is_current_user_owner_)
1947     login_user_type = LoginState::LOGGED_IN_USER_OWNER;
1948   else if (active_user_->GetType() == User::USER_TYPE_GUEST)
1949     login_user_type = LoginState::LOGGED_IN_USER_GUEST;
1950   else if (active_user_->GetType() == User::USER_TYPE_RETAIL_MODE)
1951     login_user_type = LoginState::LOGGED_IN_USER_RETAIL_MODE;
1952   else if (active_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT)
1953     login_user_type = LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT;
1954   else if (active_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED)
1955     login_user_type = LoginState::LOGGED_IN_USER_LOCALLY_MANAGED;
1956   else if (active_user_->GetType() == User::USER_TYPE_KIOSK_APP)
1957     login_user_type = LoginState::LOGGED_IN_USER_KIOSK_APP;
1958   else
1959     login_user_type = LoginState::LOGGED_IN_USER_REGULAR;
1960 
1961   if (primary_user_) {
1962     LoginState::Get()->SetLoggedInStateAndPrimaryUser(
1963         logged_in_state, login_user_type, primary_user_->username_hash());
1964   } else {
1965     LoginState::Get()->SetLoggedInState(logged_in_state, login_user_type);
1966   }
1967 }
1968 
SetLRUUser(User * user)1969 void UserManagerImpl::SetLRUUser(User* user) {
1970   UserList::iterator it = std::find(lru_logged_in_users_.begin(),
1971                                     lru_logged_in_users_.end(),
1972                                     user);
1973   if (it != lru_logged_in_users_.end())
1974     lru_logged_in_users_.erase(it);
1975   lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user);
1976 }
1977 
OnRestoreActiveSessions(const SessionManagerClient::ActiveSessionsMap & sessions,bool success)1978 void UserManagerImpl::OnRestoreActiveSessions(
1979     const SessionManagerClient::ActiveSessionsMap& sessions,
1980     bool success) {
1981   if (!success) {
1982     LOG(ERROR) << "Could not get list of active user sessions after crash.";
1983     // If we could not get list of active user sessions it is safer to just
1984     // sign out so that we don't get in the inconsistent state.
1985     DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
1986     return;
1987   }
1988 
1989   // One profile has been already loaded on browser start.
1990   DCHECK(GetLoggedInUsers().size() == 1);
1991   DCHECK(GetActiveUser());
1992   std::string active_user_id = GetActiveUser()->email();
1993 
1994   SessionManagerClient::ActiveSessionsMap::const_iterator it;
1995   for (it = sessions.begin(); it != sessions.end(); ++it) {
1996     if (active_user_id == it->first)
1997       continue;
1998     pending_user_sessions_[it->first] = it->second;
1999   }
2000   RestorePendingUserSessions();
2001 }
2002 
RestorePendingUserSessions()2003 void UserManagerImpl::RestorePendingUserSessions() {
2004   if (pending_user_sessions_.empty()) {
2005     NotifyPendingUserSessionsRestoreFinished();
2006     return;
2007   }
2008 
2009   // Get next user to restore sessions and delete it from list.
2010   SessionManagerClient::ActiveSessionsMap::const_iterator it =
2011       pending_user_sessions_.begin();
2012   std::string user_id = it->first;
2013   std::string user_id_hash = it->second;
2014   DCHECK(!user_id.empty());
2015   DCHECK(!user_id_hash.empty());
2016   pending_user_sessions_.erase(user_id);
2017 
2018   // Check that this user is not logged in yet.
2019   UserList logged_in_users = GetLoggedInUsers();
2020   bool user_already_logged_in = false;
2021   for (UserList::const_iterator it = logged_in_users.begin();
2022        it != logged_in_users.end(); ++it) {
2023     const User* user = (*it);
2024     if (user->email() == user_id) {
2025       user_already_logged_in = true;
2026       break;
2027     }
2028   }
2029   DCHECK(!user_already_logged_in);
2030 
2031   if (!user_already_logged_in) {
2032     UserContext user_context(user_id);
2033     user_context.SetUserIDHash(user_id_hash);
2034     user_context.SetIsUsingOAuth(false);
2035     // Will call OnProfilePrepared() once profile has been loaded.
2036     LoginUtils::Get()->PrepareProfile(user_context,
2037                                       false,          // has_cookies
2038                                       true,           // has_active_session
2039                                       this);
2040   } else {
2041     RestorePendingUserSessions();
2042   }
2043 }
2044 
SendRegularUserLoginMetrics(const std::string & user_id)2045 void UserManagerImpl::SendRegularUserLoginMetrics(const std::string& user_id) {
2046   // If this isn't the first time Chrome was run after the system booted,
2047   // assume that Chrome was restarted because a previous session ended.
2048   if (!CommandLine::ForCurrentProcess()->HasSwitch(
2049           switches::kFirstExecAfterBoot)) {
2050     const std::string last_email =
2051         g_browser_process->local_state()->GetString(kLastLoggedInRegularUser);
2052     const base::TimeDelta time_to_login =
2053         base::TimeTicks::Now() - manager_creation_time_;
2054     if (!last_email.empty() && user_id != last_email &&
2055         time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) {
2056       UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay",
2057           time_to_login.InSeconds(), 0, kLogoutToLoginDelayMaxSec, 50);
2058     }
2059   }
2060 }
2061 
OnUserNotAllowed(const std::string & user_email)2062 void UserManagerImpl::OnUserNotAllowed(const std::string& user_email) {
2063   LOG(ERROR) << "Shutdown session because a user is not allowed to be in the "
2064                 "current session";
2065   chromeos::ShowMultiprofilesSessionAbortedDialog(user_email);
2066 }
2067 
UpdateUserAccountLocale(const std::string & user_id,const std::string & locale)2068 void UserManagerImpl::UpdateUserAccountLocale(const std::string& user_id,
2069                                               const std::string& locale) {
2070   if (!locale.empty() &&
2071       locale != g_browser_process->GetApplicationLocale()) {
2072     BrowserThread::PostBlockingPoolTask(
2073         FROM_HERE,
2074         base::Bind(ResolveLocale, locale,
2075             base::Bind(&UserManagerImpl::DoUpdateAccountLocale,
2076                        base::Unretained(this),
2077                        user_id)));
2078   } else {
2079     DoUpdateAccountLocale(user_id, locale);
2080   }
2081 }
2082 
DoUpdateAccountLocale(const std::string & user_id,const std::string & resolved_locale)2083 void UserManagerImpl::DoUpdateAccountLocale(
2084     const std::string& user_id,
2085     const std::string& resolved_locale) {
2086   if (User* user = FindUserAndModify(user_id))
2087     user->SetAccountLocale(resolved_locale);
2088 }
2089 
UpdateNumberOfUsers()2090 void UserManagerImpl::UpdateNumberOfUsers() {
2091   size_t users = GetLoggedInUsers().size();
2092   if (users) {
2093     // Write the user number as UMA stat when a multi user session is possible.
2094     if ((users + GetUsersAdmittedForMultiProfile().size()) > 1)
2095       ash::MultiProfileUMA::RecordUserCount(users);
2096   }
2097 
2098   base::debug::SetCrashKeyValue(crash_keys::kNumberOfUsers,
2099       base::StringPrintf("%" PRIuS, GetLoggedInUsers().size()));
2100 }
2101 
DeleteUser(User * user)2102 void UserManagerImpl::DeleteUser(User* user) {
2103   const bool is_active_user = (user == active_user_);
2104   delete user;
2105   if (is_active_user)
2106     active_user_ = NULL;
2107 }
2108 
2109 }  // namespace chromeos
2110