Cleanup UserManager dependency of CloudExternalDataPolicyObserver.
[chromium-blink-merge.git] / chrome / browser / chromeos / login / users / user_manager_impl.cc
blob99405e0584cea0afd4b3a665b10ef92e6e896369
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.
5 #include "chrome/browser/chromeos/login/users/user_manager_impl.h"
7 #include <cstddef>
8 #include <set>
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/browser_process.h"
32 #include "chrome/browser/chrome_notification_types.h"
33 #include "chrome/browser/chromeos/login/auth/user_context.h"
34 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
35 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
36 #include "chrome/browser/chromeos/login/signin/auth_sync_observer.h"
37 #include "chrome/browser/chromeos/login/signin/auth_sync_observer_factory.h"
38 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h"
39 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
40 #include "chrome/browser/chromeos/login/users/remove_user_delegate.h"
41 #include "chrome/browser/chromeos/login/users/supervised_user_manager_impl.h"
42 #include "chrome/browser/chromeos/login/wizard_controller.h"
43 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
44 #include "chrome/browser/chromeos/policy/device_local_account.h"
45 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog.h"
46 #include "chrome/browser/chromeos/profiles/profile_helper.h"
47 #include "chrome/browser/chromeos/session_length_limiter.h"
48 #include "chrome/browser/profiles/profile.h"
49 #include "chrome/browser/profiles/profile_manager.h"
50 #include "chrome/browser/supervised_user/chromeos/manager_password_service_factory.h"
51 #include "chrome/browser/supervised_user/chromeos/supervised_user_password_service_factory.h"
52 #include "chrome/common/chrome_constants.h"
53 #include "chrome/common/chrome_paths.h"
54 #include "chrome/common/chrome_switches.h"
55 #include "chrome/common/crash_keys.h"
56 #include "chrome/common/pref_names.h"
57 #include "chromeos/chromeos_switches.h"
58 #include "chromeos/cryptohome/async_method_caller.h"
59 #include "chromeos/dbus/dbus_thread_manager.h"
60 #include "chromeos/login/login_state.h"
61 #include "chromeos/settings/cros_settings_names.h"
62 #include "content/public/browser/browser_thread.h"
63 #include "content/public/browser/notification_service.h"
64 #include "google_apis/gaia/gaia_auth_util.h"
65 #include "google_apis/gaia/google_service_auth_error.h"
66 #include "policy/policy_constants.h"
67 #include "ui/base/l10n/l10n_util.h"
68 #include "ui/wm/core/wm_core_switches.h"
70 using content::BrowserThread;
72 namespace chromeos {
73 namespace {
75 // A vector pref of the the regular users known on this device, arranged in LRU
76 // order.
77 const char kRegularUsers[] = "LoggedInUsers";
79 // A vector pref of the public accounts defined on this device.
80 const char kPublicAccounts[] = "PublicAccounts";
82 // A string pref that gets set when a public account is removed but a user is
83 // currently logged into that account, requiring the account's data to be
84 // removed after logout.
85 const char kPublicAccountPendingDataRemoval[] =
86 "PublicAccountPendingDataRemoval";
88 // A dictionary that maps user IDs to the displayed name.
89 const char kUserDisplayName[] = "UserDisplayName";
91 // A dictionary that maps user IDs to the user's given name.
92 const char kUserGivenName[] = "UserGivenName";
94 // A dictionary that maps user IDs to the displayed (non-canonical) emails.
95 const char kUserDisplayEmail[] = "UserDisplayEmail";
97 // A dictionary that maps user IDs to OAuth token presence flag.
98 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus";
100 // A dictionary that maps user IDs to a flag indicating whether online
101 // authentication against GAIA should be enforced during the next sign-in.
102 const char kUserForceOnlineSignin[] = "UserForceOnlineSignin";
104 // A string pref containing the ID of the last user who logged in if it was
105 // a regular user or an empty string if it was another type of user (guest,
106 // kiosk, public account, etc.).
107 const char kLastLoggedInRegularUser[] = "LastLoggedInRegularUser";
109 // Upper bound for a histogram metric reporting the amount of time between
110 // one regular user logging out and a different regular user logging in.
111 const int kLogoutToLoginDelayMaxSec = 1800;
113 // Callback that is called after user removal is complete.
114 void OnRemoveUserComplete(const std::string& user_email,
115 bool success,
116 cryptohome::MountError return_code) {
117 // Log the error, but there's not much we can do.
118 if (!success) {
119 LOG(ERROR) << "Removal of cryptohome for " << user_email
120 << " failed, return code: " << return_code;
124 // Helper function that copies users from |users_list| to |users_vector| and
125 // |users_set|. Duplicates and users already present in |existing_users| are
126 // skipped.
127 void ParseUserList(const base::ListValue& users_list,
128 const std::set<std::string>& existing_users,
129 std::vector<std::string>* users_vector,
130 std::set<std::string>* users_set) {
131 users_vector->clear();
132 users_set->clear();
133 for (size_t i = 0; i < users_list.GetSize(); ++i) {
134 std::string email;
135 if (!users_list.GetString(i, &email) || email.empty()) {
136 LOG(ERROR) << "Corrupt entry in user list at index " << i << ".";
137 continue;
139 if (existing_users.find(email) != existing_users.end() ||
140 !users_set->insert(email).second) {
141 LOG(ERROR) << "Duplicate user: " << email;
142 continue;
144 users_vector->push_back(email);
148 // Runs on SequencedWorkerPool thread. Passes resolved locale to
149 // |on_resolve_callback| on UI thread.
150 void ResolveLocale(
151 const std::string& raw_locale,
152 base::Callback<void(const std::string&)> on_resolve_callback) {
153 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
154 std::string resolved_locale;
155 // Ignore result
156 l10n_util::CheckAndResolveLocale(raw_locale, &resolved_locale);
157 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
158 base::Bind(on_resolve_callback, resolved_locale));
161 } // namespace
163 // static
164 void UserManager::RegisterPrefs(PrefRegistrySimple* registry) {
165 registry->RegisterListPref(kRegularUsers);
166 registry->RegisterListPref(kPublicAccounts);
167 registry->RegisterStringPref(kPublicAccountPendingDataRemoval, "");
168 registry->RegisterStringPref(kLastLoggedInRegularUser, "");
169 registry->RegisterDictionaryPref(kUserDisplayName);
170 registry->RegisterDictionaryPref(kUserGivenName);
171 registry->RegisterDictionaryPref(kUserDisplayEmail);
172 registry->RegisterDictionaryPref(kUserOAuthTokenStatus);
173 registry->RegisterDictionaryPref(kUserForceOnlineSignin);
174 SupervisedUserManager::RegisterPrefs(registry);
175 SessionLengthLimiter::RegisterPrefs(registry);
178 UserManagerImpl::UserManagerImpl()
179 : cros_settings_(CrosSettings::Get()),
180 device_local_account_policy_service_(NULL),
181 user_loading_stage_(STAGE_NOT_LOADED),
182 active_user_(NULL),
183 primary_user_(NULL),
184 session_started_(false),
185 user_sessions_restored_(false),
186 is_current_user_owner_(false),
187 is_current_user_new_(false),
188 is_current_user_ephemeral_regular_user_(false),
189 ephemeral_users_enabled_(false),
190 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
191 manager_creation_time_(base::TimeTicks::Now()) {
192 UpdateNumberOfUsers();
193 // UserManager instance should be used only on UI thread.
194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
195 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
196 content::NotificationService::AllSources());
197 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
198 content::NotificationService::AllSources());
199 registrar_.Add(this,
200 chrome::NOTIFICATION_PROFILE_CREATED,
201 content::NotificationService::AllSources());
202 RetrieveTrustedDevicePolicies();
203 local_accounts_subscription_ = cros_settings_->AddSettingsObserver(
204 kAccountsPrefDeviceLocalAccounts,
205 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
206 base::Unretained(this)));
207 multi_profile_user_controller_.reset(new MultiProfileUserController(
208 this, g_browser_process->local_state()));
210 policy::BrowserPolicyConnectorChromeOS* connector =
211 g_browser_process->platform_part()->browser_policy_connector_chromeos();
212 avatar_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
213 cros_settings_,
214 connector->GetDeviceLocalAccountPolicyService(),
215 policy::key::kUserAvatarImage,
216 this));
217 avatar_policy_observer_->Init();
219 wallpaper_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
220 cros_settings_,
221 connector->GetDeviceLocalAccountPolicyService(),
222 policy::key::kWallpaperImage,
223 this));
224 wallpaper_policy_observer_->Init();
226 UpdateLoginState();
229 UserManagerImpl::~UserManagerImpl() {
230 // Can't use STLDeleteElements because of the private destructor of User.
231 for (UserList::iterator it = users_.begin(); it != users_.end();
232 it = users_.erase(it)) {
233 DeleteUser(*it);
235 // These are pointers to the same User instances that were in users_ list.
236 logged_in_users_.clear();
237 lru_logged_in_users_.clear();
239 DeleteUser(active_user_);
242 void UserManagerImpl::Shutdown() {
243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
244 local_accounts_subscription_.reset();
245 // Stop the session length limiter.
246 session_length_limiter_.reset();
248 if (device_local_account_policy_service_)
249 device_local_account_policy_service_->RemoveObserver(this);
251 for (UserImageManagerMap::iterator it = user_image_managers_.begin(),
252 ie = user_image_managers_.end();
253 it != ie; ++it) {
254 it->second->Shutdown();
256 multi_profile_user_controller_.reset();
257 avatar_policy_observer_.reset();
258 wallpaper_policy_observer_.reset();
259 registrar_.RemoveAll();
262 MultiProfileUserController* UserManagerImpl::GetMultiProfileUserController() {
263 return multi_profile_user_controller_.get();
266 UserImageManager* UserManagerImpl::GetUserImageManager(
267 const std::string& user_id) {
268 UserImageManagerMap::iterator ui = user_image_managers_.find(user_id);
269 if (ui != user_image_managers_.end())
270 return ui->second.get();
271 linked_ptr<UserImageManagerImpl> mgr(new UserImageManagerImpl(user_id, this));
272 user_image_managers_[user_id] = mgr;
273 return mgr.get();
276 SupervisedUserManager* UserManagerImpl::GetSupervisedUserManager() {
277 return supervised_user_manager_.get();
280 const UserList& UserManagerImpl::GetUsers() const {
281 const_cast<UserManagerImpl*>(this)->EnsureUsersLoaded();
282 return users_;
285 UserList UserManagerImpl::GetUsersAdmittedForMultiProfile() const {
286 // Supervised users are not allowed to use multi-profiles.
287 if (logged_in_users_.size() == 1 &&
288 GetPrimaryUser()->GetType() != User::USER_TYPE_REGULAR) {
289 return UserList();
292 UserList result;
293 const UserList& users = GetUsers();
294 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
295 if ((*it)->GetType() == User::USER_TYPE_REGULAR && !(*it)->is_logged_in()) {
296 MultiProfileUserController::UserAllowedInSessionResult check =
297 multi_profile_user_controller_->
298 IsUserAllowedInSession((*it)->email());
299 if (check == MultiProfileUserController::
300 NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS) {
301 return UserList();
304 // Users with a policy that prevents them being added to a session will be
305 // shown in login UI but will be grayed out.
306 // Same applies to owner account (see http://crbug.com/385034).
307 if (check == MultiProfileUserController::ALLOWED ||
308 check == MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS ||
309 check == MultiProfileUserController::NOT_ALLOWED_OWNER_AS_SECONDARY) {
310 result.push_back(*it);
315 return result;
318 const UserList& UserManagerImpl::GetLoggedInUsers() const {
319 return logged_in_users_;
322 const UserList& UserManagerImpl::GetLRULoggedInUsers() {
323 // If there is no user logged in, we return the active user as the only one.
324 if (lru_logged_in_users_.empty() && active_user_) {
325 temp_single_logged_in_users_.clear();
326 temp_single_logged_in_users_.insert(temp_single_logged_in_users_.begin(),
327 active_user_);
328 return temp_single_logged_in_users_;
330 return lru_logged_in_users_;
333 UserList UserManagerImpl::GetUnlockUsers() const {
334 const UserList& logged_in_users = GetLoggedInUsers();
335 if (logged_in_users.empty())
336 return UserList();
338 UserList unlock_users;
339 Profile* profile = ProfileHelper::Get()->GetProfileByUser(primary_user_);
340 std::string primary_behavior =
341 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
343 // Specific case: only one logged in user or
344 // primary user has primary-only multi-profile policy.
345 if (logged_in_users.size() == 1 ||
346 primary_behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
347 if (primary_user_->can_lock())
348 unlock_users.push_back(primary_user_);
349 } else {
350 // Fill list of potential unlock users based on multi-profile policy state.
351 for (UserList::const_iterator it = logged_in_users.begin();
352 it != logged_in_users.end(); ++it) {
353 User* user = (*it);
354 Profile* profile = ProfileHelper::Get()->GetProfileByUser(user);
355 const std::string behavior =
356 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
357 if (behavior == MultiProfileUserController::kBehaviorUnrestricted &&
358 user->can_lock()) {
359 unlock_users.push_back(user);
360 } else if (behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
361 NOTREACHED()
362 << "Spotted primary-only multi-profile policy for non-primary user";
367 return unlock_users;
370 const std::string& UserManagerImpl::GetOwnerEmail() {
371 return owner_email_;
374 void UserManagerImpl::UserLoggedIn(const std::string& user_id,
375 const std::string& username_hash,
376 bool browser_restart) {
377 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
379 User* user = FindUserInListAndModify(user_id);
380 if (active_user_ && user) {
381 user->set_is_logged_in(true);
382 user->set_username_hash(username_hash);
383 logged_in_users_.push_back(user);
384 lru_logged_in_users_.push_back(user);
385 // Reset the new user flag if the user already exists.
386 is_current_user_new_ = false;
387 NotifyUserAddedToSession(user);
388 // Remember that we need to switch to this user as soon as profile ready.
389 pending_user_switch_ = user_id;
390 return;
393 policy::DeviceLocalAccount::Type device_local_account_type;
394 if (user_id == UserManager::kGuestUserName) {
395 GuestUserLoggedIn();
396 } else if (user_id == UserManager::kRetailModeUserName) {
397 RetailModeUserLoggedIn();
398 } else if (policy::IsDeviceLocalAccountUser(user_id,
399 &device_local_account_type) &&
400 device_local_account_type ==
401 policy::DeviceLocalAccount::TYPE_KIOSK_APP) {
402 KioskAppLoggedIn(user_id);
403 } else if (DemoAppLauncher::IsDemoAppSession(user_id)) {
404 DemoAccountLoggedIn();
405 } else {
406 EnsureUsersLoaded();
408 if (user && user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
409 PublicAccountUserLoggedIn(user);
410 } else if ((user && user->GetType() == User::USER_TYPE_LOCALLY_MANAGED) ||
411 (!user && gaia::ExtractDomainName(user_id) ==
412 UserManager::kLocallyManagedUserDomain)) {
413 LocallyManagedUserLoggedIn(user_id);
414 } else if (browser_restart && user_id == g_browser_process->local_state()->
415 GetString(kPublicAccountPendingDataRemoval)) {
416 PublicAccountUserLoggedIn(User::CreatePublicAccountUser(user_id));
417 } else if (user_id != owner_email_ && !user &&
418 (AreEphemeralUsersEnabled() || browser_restart)) {
419 RegularUserLoggedInAsEphemeral(user_id);
420 } else {
421 RegularUserLoggedIn(user_id);
424 // Initialize the session length limiter and start it only if
425 // session limit is defined by the policy.
426 session_length_limiter_.reset(new SessionLengthLimiter(NULL,
427 browser_restart));
429 DCHECK(active_user_);
430 active_user_->set_is_logged_in(true);
431 active_user_->set_is_active(true);
432 active_user_->set_username_hash(username_hash);
434 // Place user who just signed in to the top of the logged in users.
435 logged_in_users_.insert(logged_in_users_.begin(), active_user_);
436 SetLRUUser(active_user_);
438 if (!primary_user_) {
439 primary_user_ = active_user_;
440 if (primary_user_->GetType() == User::USER_TYPE_REGULAR)
441 SendRegularUserLoginMetrics(user_id);
444 UMA_HISTOGRAM_ENUMERATION("UserManager.LoginUserType",
445 active_user_->GetType(), User::NUM_USER_TYPES);
447 g_browser_process->local_state()->SetString(kLastLoggedInRegularUser,
448 (active_user_->GetType() == User::USER_TYPE_REGULAR) ? user_id : "");
450 NotifyOnLogin();
453 void UserManagerImpl::SwitchActiveUser(const std::string& user_id) {
454 User* user = FindUserAndModify(user_id);
455 if (!user) {
456 NOTREACHED() << "Switching to a non-existing user";
457 return;
459 if (user == active_user_) {
460 NOTREACHED() << "Switching to a user who is already active";
461 return;
463 if (!user->is_logged_in()) {
464 NOTREACHED() << "Switching to a user that is not logged in";
465 return;
467 if (user->GetType() != User::USER_TYPE_REGULAR) {
468 NOTREACHED() << "Switching to a non-regular user";
469 return;
471 if (user->username_hash().empty()) {
472 NOTREACHED() << "Switching to a user that doesn't have username_hash set";
473 return;
476 DCHECK(active_user_);
477 active_user_->set_is_active(false);
478 user->set_is_active(true);
479 active_user_ = user;
481 // Move the user to the front.
482 SetLRUUser(active_user_);
484 NotifyActiveUserHashChanged(active_user_->username_hash());
485 NotifyActiveUserChanged(active_user_);
488 void UserManagerImpl::RestoreActiveSessions() {
489 DBusThreadManager::Get()->GetSessionManagerClient()->RetrieveActiveSessions(
490 base::Bind(&UserManagerImpl::OnRestoreActiveSessions,
491 base::Unretained(this)));
494 void UserManagerImpl::SessionStarted() {
495 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
496 session_started_ = true;
497 UpdateLoginState();
498 content::NotificationService::current()->Notify(
499 chrome::NOTIFICATION_SESSION_STARTED,
500 content::Source<UserManager>(this),
501 content::Details<const User>(active_user_));
502 if (is_current_user_new_) {
503 // Make sure that the new user's data is persisted to Local State.
504 g_browser_process->local_state()->CommitPendingWrite();
508 void UserManagerImpl::RemoveUser(const std::string& user_id,
509 RemoveUserDelegate* delegate) {
510 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
512 const User* user = FindUser(user_id);
513 if (!user || (user->GetType() != User::USER_TYPE_REGULAR &&
514 user->GetType() != User::USER_TYPE_LOCALLY_MANAGED))
515 return;
517 // Sanity check: we must not remove single user unless it's an enterprise
518 // device. This check may seem redundant at a first sight because
519 // this single user must be an owner and we perform special check later
520 // in order not to remove an owner. However due to non-instant nature of
521 // ownership assignment this later check may sometimes fail.
522 // See http://crosbug.com/12723
523 policy::BrowserPolicyConnectorChromeOS* connector =
524 g_browser_process->platform_part()
525 ->browser_policy_connector_chromeos();
526 if (users_.size() < 2 && !connector->IsEnterpriseManaged())
527 return;
529 // Sanity check: do not allow any of the the logged in users to be removed.
530 for (UserList::const_iterator it = logged_in_users_.begin();
531 it != logged_in_users_.end(); ++it) {
532 if ((*it)->email() == user_id)
533 return;
536 RemoveUserInternal(user_id, delegate);
539 void UserManagerImpl::RemoveUserInternal(const std::string& user_email,
540 RemoveUserDelegate* delegate) {
541 CrosSettings* cros_settings = CrosSettings::Get();
543 // Ensure the value of owner email has been fetched.
544 if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues(
545 base::Bind(&UserManagerImpl::RemoveUserInternal,
546 base::Unretained(this),
547 user_email, delegate))) {
548 // Value of owner email is not fetched yet. RemoveUserInternal will be
549 // called again after fetch completion.
550 return;
552 std::string owner;
553 cros_settings->GetString(kDeviceOwner, &owner);
554 if (user_email == owner) {
555 // Owner is not allowed to be removed from the device.
556 return;
558 RemoveNonOwnerUserInternal(user_email, delegate);
561 void UserManagerImpl::RemoveNonOwnerUserInternal(const std::string& user_email,
562 RemoveUserDelegate* delegate) {
563 if (delegate)
564 delegate->OnBeforeUserRemoved(user_email);
565 RemoveUserFromList(user_email);
566 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
567 user_email, base::Bind(&OnRemoveUserComplete, user_email));
569 if (delegate)
570 delegate->OnUserRemoved(user_email);
573 void UserManagerImpl::RemoveUserFromList(const std::string& user_id) {
574 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
575 RemoveNonCryptohomeData(user_id);
576 if (user_loading_stage_ == STAGE_LOADED) {
577 DeleteUser(RemoveRegularOrLocallyManagedUserFromList(user_id));
578 } else if (user_loading_stage_ == STAGE_LOADING) {
579 DCHECK(gaia::ExtractDomainName(user_id) ==
580 UserManager::kLocallyManagedUserDomain);
581 // Special case, removing partially-constructed supervised user during user
582 // list loading.
583 ListPrefUpdate users_update(g_browser_process->local_state(),
584 kRegularUsers);
585 users_update->Remove(base::StringValue(user_id), NULL);
586 } else {
587 NOTREACHED() << "Users are not loaded yet.";
588 return;
590 // Make sure that new data is persisted to Local State.
591 g_browser_process->local_state()->CommitPendingWrite();
594 bool UserManagerImpl::IsKnownUser(const std::string& user_id) const {
595 return FindUser(user_id) != NULL;
598 const User* UserManagerImpl::FindUser(const std::string& user_id) const {
599 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
600 if (active_user_ && active_user_->email() == user_id)
601 return active_user_;
602 return FindUserInList(user_id);
605 User* UserManagerImpl::FindUserAndModify(const std::string& user_id) {
606 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
607 if (active_user_ && active_user_->email() == user_id)
608 return active_user_;
609 return FindUserInListAndModify(user_id);
612 const User* UserManagerImpl::GetLoggedInUser() const {
613 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
614 return active_user_;
617 User* UserManagerImpl::GetLoggedInUser() {
618 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
619 return active_user_;
622 const User* UserManagerImpl::GetActiveUser() const {
623 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
624 return active_user_;
627 User* UserManagerImpl::GetActiveUser() {
628 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
629 return active_user_;
632 const User* UserManagerImpl::GetPrimaryUser() const {
633 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
634 return primary_user_;
637 void UserManagerImpl::SaveUserOAuthStatus(
638 const std::string& user_id,
639 User::OAuthTokenStatus oauth_token_status) {
640 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
642 DVLOG(1) << "Saving user OAuth token status in Local State";
643 User* user = FindUserAndModify(user_id);
644 if (user)
645 user->set_oauth_token_status(oauth_token_status);
647 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(oauth_token_status);
649 // Do not update local state if data stored or cached outside the user's
650 // cryptohome is to be treated as ephemeral.
651 if (IsUserNonCryptohomeDataEphemeral(user_id))
652 return;
654 PrefService* local_state = g_browser_process->local_state();
656 DictionaryPrefUpdate oauth_status_update(local_state, kUserOAuthTokenStatus);
657 oauth_status_update->SetWithoutPathExpansion(user_id,
658 new base::FundamentalValue(static_cast<int>(oauth_token_status)));
661 void UserManagerImpl::SaveForceOnlineSignin(const std::string& user_id,
662 bool force_online_signin) {
663 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
665 // Do not update local state if data stored or cached outside the user's
666 // cryptohome is to be treated as ephemeral.
667 if (IsUserNonCryptohomeDataEphemeral(user_id))
668 return;
670 DictionaryPrefUpdate force_online_update(g_browser_process->local_state(),
671 kUserForceOnlineSignin);
672 force_online_update->SetBooleanWithoutPathExpansion(user_id,
673 force_online_signin);
676 void UserManagerImpl::SaveUserDisplayName(const std::string& user_id,
677 const base::string16& display_name) {
678 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
680 if (User* user = FindUserAndModify(user_id)) {
681 user->set_display_name(display_name);
683 // Do not update local state if data stored or cached outside the user's
684 // cryptohome is to be treated as ephemeral.
685 if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
686 PrefService* local_state = g_browser_process->local_state();
688 DictionaryPrefUpdate display_name_update(local_state, kUserDisplayName);
689 display_name_update->SetWithoutPathExpansion(
690 user_id,
691 new base::StringValue(display_name));
693 supervised_user_manager_->UpdateManagerName(user_id, display_name);
698 base::string16 UserManagerImpl::GetUserDisplayName(
699 const std::string& user_id) const {
700 const User* user = FindUser(user_id);
701 return user ? user->display_name() : base::string16();
704 void UserManagerImpl::SaveUserDisplayEmail(const std::string& user_id,
705 const std::string& display_email) {
706 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
708 User* user = FindUserAndModify(user_id);
709 if (!user)
710 return; // Ignore if there is no such user.
712 user->set_display_email(display_email);
714 // Do not update local state if data stored or cached outside the user's
715 // cryptohome is to be treated as ephemeral.
716 if (IsUserNonCryptohomeDataEphemeral(user_id))
717 return;
719 PrefService* local_state = g_browser_process->local_state();
721 DictionaryPrefUpdate display_email_update(local_state, kUserDisplayEmail);
722 display_email_update->SetWithoutPathExpansion(
723 user_id,
724 new base::StringValue(display_email));
727 std::string UserManagerImpl::GetUserDisplayEmail(
728 const std::string& user_id) const {
729 const User* user = FindUser(user_id);
730 return user ? user->display_email() : user_id;
733 void UserManagerImpl::UpdateUserAccountData(
734 const std::string& user_id,
735 const UserAccountData& account_data) {
736 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
738 SaveUserDisplayName(user_id, account_data.display_name());
740 if (User* user = FindUserAndModify(user_id)) {
741 base::string16 given_name = account_data.given_name();
742 user->set_given_name(given_name);
743 if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
744 PrefService* local_state = g_browser_process->local_state();
746 DictionaryPrefUpdate given_name_update(local_state, kUserGivenName);
747 given_name_update->SetWithoutPathExpansion(
748 user_id,
749 new base::StringValue(given_name));
753 UpdateUserAccountLocale(user_id, account_data.locale());
756 void UserManagerImpl::StopPolicyObserverForTesting() {
757 avatar_policy_observer_.reset();
758 wallpaper_policy_observer_.reset();
761 void UserManagerImpl::Observe(int type,
762 const content::NotificationSource& source,
763 const content::NotificationDetails& details) {
764 switch (type) {
765 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED:
766 if (!device_local_account_policy_service_) {
767 policy::BrowserPolicyConnectorChromeOS* connector =
768 g_browser_process->platform_part()
769 ->browser_policy_connector_chromeos();
770 device_local_account_policy_service_ =
771 connector->GetDeviceLocalAccountPolicyService();
772 if (device_local_account_policy_service_)
773 device_local_account_policy_service_->AddObserver(this);
775 RetrieveTrustedDevicePolicies();
776 UpdateOwnership();
777 break;
778 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: {
779 Profile* profile = content::Details<Profile>(details).ptr();
780 if (IsUserLoggedIn() &&
781 !IsLoggedInAsGuest() &&
782 !IsLoggedInAsKioskApp()) {
783 if (IsLoggedInAsLocallyManagedUser())
784 SupervisedUserPasswordServiceFactory::GetForProfile(profile);
785 if (IsLoggedInAsRegularUser())
786 ManagerPasswordServiceFactory::GetForProfile(profile);
788 if (!profile->IsOffTheRecord()) {
789 AuthSyncObserver* sync_observer =
790 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile);
791 sync_observer->StartObserving();
792 multi_profile_user_controller_->StartObserving(profile);
795 break;
797 case chrome::NOTIFICATION_PROFILE_CREATED: {
798 Profile* profile = content::Source<Profile>(source).ptr();
799 User* user = ProfileHelper::Get()->GetUserByProfile(profile);
800 if (user != NULL)
801 user->set_profile_is_created();
802 // If there is pending user switch, do it now.
803 if (!pending_user_switch_.empty()) {
804 // Call SwitchActiveUser async because otherwise it may cause
805 // ProfileManager::GetProfile before the profile gets registered
806 // in ProfileManager. It happens in case of sync profile load when
807 // NOTIFICATION_PROFILE_CREATED is called synchronously.
808 base::MessageLoop::current()->PostTask(FROM_HERE,
809 base::Bind(&UserManagerImpl::SwitchActiveUser,
810 base::Unretained(this),
811 pending_user_switch_));
812 pending_user_switch_.clear();
814 break;
816 default:
817 NOTREACHED();
821 void UserManagerImpl::OnExternalDataSet(const std::string& policy,
822 const std::string& user_id) {
823 if (policy == policy::key::kUserAvatarImage)
824 GetUserImageManager(user_id)->OnExternalDataSet(policy);
825 else if (policy == policy::key::kWallpaperImage)
826 WallpaperManager::Get()->OnPolicySet(policy, user_id);
827 else
828 NOTREACHED();
831 void UserManagerImpl::OnExternalDataCleared(const std::string& policy,
832 const std::string& user_id) {
833 if (policy == policy::key::kUserAvatarImage)
834 GetUserImageManager(user_id)->OnExternalDataCleared(policy);
835 else if (policy == policy::key::kWallpaperImage)
836 WallpaperManager::Get()->OnPolicyCleared(policy, user_id);
837 else
838 NOTREACHED();
841 void UserManagerImpl::OnExternalDataFetched(const std::string& policy,
842 const std::string& user_id,
843 scoped_ptr<std::string> data) {
844 if (policy == policy::key::kUserAvatarImage)
845 GetUserImageManager(user_id)->OnExternalDataFetched(policy, data.Pass());
846 else if (policy == policy::key::kWallpaperImage)
847 WallpaperManager::Get()->OnPolicyFetched(policy, user_id, data.Pass());
848 else
849 NOTREACHED();
852 void UserManagerImpl::OnPolicyUpdated(const std::string& user_id) {
853 const User* user = FindUserInList(user_id);
854 if (!user || user->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT)
855 return;
856 UpdatePublicAccountDisplayName(user_id);
857 NotifyUserListChanged();
860 void UserManagerImpl::OnDeviceLocalAccountsChanged() {
861 // No action needed here, changes to the list of device-local accounts get
862 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
865 bool UserManagerImpl::IsCurrentUserOwner() const {
866 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
867 base::AutoLock lk(is_current_user_owner_lock_);
868 return is_current_user_owner_;
871 void UserManagerImpl::SetCurrentUserIsOwner(bool is_current_user_owner) {
872 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
874 base::AutoLock lk(is_current_user_owner_lock_);
875 is_current_user_owner_ = is_current_user_owner;
877 UpdateLoginState();
880 bool UserManagerImpl::IsCurrentUserNew() const {
881 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
882 return is_current_user_new_;
885 bool UserManagerImpl::IsCurrentUserNonCryptohomeDataEphemeral() const {
886 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
887 return IsUserLoggedIn() &&
888 IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email());
891 bool UserManagerImpl::CanCurrentUserLock() const {
892 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
893 return IsUserLoggedIn() && active_user_->can_lock() &&
894 GetCurrentUserFlow()->CanLockScreen();
897 bool UserManagerImpl::IsUserLoggedIn() const {
898 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
899 return active_user_;
902 bool UserManagerImpl::IsLoggedInAsRegularUser() const {
903 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
904 return IsUserLoggedIn() &&
905 active_user_->GetType() == User::USER_TYPE_REGULAR;
908 bool UserManagerImpl::IsLoggedInAsDemoUser() const {
909 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
910 return IsUserLoggedIn() &&
911 active_user_->GetType() == User::USER_TYPE_RETAIL_MODE;
914 bool UserManagerImpl::IsLoggedInAsPublicAccount() const {
915 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
916 return IsUserLoggedIn() &&
917 active_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
920 bool UserManagerImpl::IsLoggedInAsGuest() const {
921 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
922 return IsUserLoggedIn() &&
923 active_user_->GetType() == User::USER_TYPE_GUEST;
926 bool UserManagerImpl::IsLoggedInAsLocallyManagedUser() const {
927 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
928 return IsUserLoggedIn() &&
929 active_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED;
932 bool UserManagerImpl::IsLoggedInAsKioskApp() const {
933 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
934 return IsUserLoggedIn() &&
935 active_user_->GetType() == User::USER_TYPE_KIOSK_APP;
938 bool UserManagerImpl::IsLoggedInAsStub() const {
939 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
940 return IsUserLoggedIn() && active_user_->email() == kStubUser;
943 bool UserManagerImpl::IsSessionStarted() const {
944 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
945 return session_started_;
948 bool UserManagerImpl::UserSessionsRestored() const {
949 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
950 return user_sessions_restored_;
953 bool UserManagerImpl::IsUserNonCryptohomeDataEphemeral(
954 const std::string& user_id) const {
955 // Data belonging to the guest, retail mode and stub users is always
956 // ephemeral.
957 if (user_id == UserManager::kGuestUserName ||
958 user_id == UserManager::kRetailModeUserName ||
959 user_id == kStubUser) {
960 return true;
963 // Data belonging to the owner, anyone found on the user list and obsolete
964 // public accounts whose data has not been removed yet is not ephemeral.
965 if (user_id == owner_email_ || UserExistsInList(user_id) ||
966 user_id == g_browser_process->local_state()->
967 GetString(kPublicAccountPendingDataRemoval)) {
968 return false;
971 // Data belonging to the currently logged-in user is ephemeral when:
972 // a) The user logged into a regular account while the ephemeral users policy
973 // was enabled.
974 // - or -
975 // b) The user logged into any other account type.
976 if (IsUserLoggedIn() && (user_id == GetLoggedInUser()->email()) &&
977 (is_current_user_ephemeral_regular_user_ || !IsLoggedInAsRegularUser())) {
978 return true;
981 // Data belonging to any other user is ephemeral when:
982 // a) Going through the regular login flow and the ephemeral users policy is
983 // enabled.
984 // - or -
985 // b) The browser is restarting after a crash.
986 return AreEphemeralUsersEnabled() ||
987 UserSessionManager::GetInstance()->HasBrowserRestarted();
990 void UserManagerImpl::AddObserver(UserManager::Observer* obs) {
991 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
992 observer_list_.AddObserver(obs);
995 void UserManagerImpl::RemoveObserver(UserManager::Observer* obs) {
996 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
997 observer_list_.RemoveObserver(obs);
1000 void UserManagerImpl::AddSessionStateObserver(
1001 UserManager::UserSessionStateObserver* obs) {
1002 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1003 session_state_observer_list_.AddObserver(obs);
1006 void UserManagerImpl::RemoveSessionStateObserver(
1007 UserManager::UserSessionStateObserver* obs) {
1008 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1009 session_state_observer_list_.RemoveObserver(obs);
1012 void UserManagerImpl::NotifyLocalStateChanged() {
1013 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1014 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_,
1015 LocalStateChanged(this));
1018 void UserManagerImpl::OnProfilePrepared(Profile* profile) {
1019 LoginUtils::Get()->DoBrowserLaunch(profile,
1020 NULL); // host_, not needed here
1022 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) {
1023 // Did not log in (we crashed or are debugging), need to restore Sync.
1024 // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
1025 // users once it is fully multi-profile aware. http://crbug.com/238987
1026 // For now if we have other user pending sessions they'll override OAuth
1027 // session restore for previous users.
1028 UserSessionManager::GetInstance()->RestoreAuthenticationSession(profile);
1031 // Restore other user sessions if any.
1032 RestorePendingUserSessions();
1035 void UserManagerImpl::EnsureUsersLoaded() {
1036 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1037 if (!g_browser_process || !g_browser_process->local_state())
1038 return;
1040 if (user_loading_stage_ != STAGE_NOT_LOADED)
1041 return;
1042 user_loading_stage_ = STAGE_LOADING;
1043 // Clean up user list first. All code down the path should be synchronous,
1044 // so that local state after transaction rollback is in consistent state.
1045 // This process also should not trigger EnsureUsersLoaded again.
1046 if (supervised_user_manager_->HasFailedUserCreationTransaction())
1047 supervised_user_manager_->RollbackUserCreationTransaction();
1049 PrefService* local_state = g_browser_process->local_state();
1050 const base::ListValue* prefs_regular_users =
1051 local_state->GetList(kRegularUsers);
1052 const base::ListValue* prefs_public_sessions =
1053 local_state->GetList(kPublicAccounts);
1054 const base::DictionaryValue* prefs_display_names =
1055 local_state->GetDictionary(kUserDisplayName);
1056 const base::DictionaryValue* prefs_given_names =
1057 local_state->GetDictionary(kUserGivenName);
1058 const base::DictionaryValue* prefs_display_emails =
1059 local_state->GetDictionary(kUserDisplayEmail);
1061 // Load public sessions first.
1062 std::vector<std::string> public_sessions;
1063 std::set<std::string> public_sessions_set;
1064 ParseUserList(*prefs_public_sessions, std::set<std::string>(),
1065 &public_sessions, &public_sessions_set);
1066 for (std::vector<std::string>::const_iterator it = public_sessions.begin();
1067 it != public_sessions.end(); ++it) {
1068 users_.push_back(User::CreatePublicAccountUser(*it));
1069 UpdatePublicAccountDisplayName(*it);
1072 // Load regular users and locally managed users.
1073 std::vector<std::string> regular_users;
1074 std::set<std::string> regular_users_set;
1075 ParseUserList(*prefs_regular_users, public_sessions_set,
1076 &regular_users, &regular_users_set);
1077 for (std::vector<std::string>::const_iterator it = regular_users.begin();
1078 it != regular_users.end(); ++it) {
1079 User* user = NULL;
1080 const std::string domain = gaia::ExtractDomainName(*it);
1081 if (domain == UserManager::kLocallyManagedUserDomain)
1082 user = User::CreateLocallyManagedUser(*it);
1083 else
1084 user = User::CreateRegularUser(*it);
1085 user->set_oauth_token_status(LoadUserOAuthStatus(*it));
1086 user->set_force_online_signin(LoadForceOnlineSignin(*it));
1087 users_.push_back(user);
1089 base::string16 display_name;
1090 if (prefs_display_names->GetStringWithoutPathExpansion(*it,
1091 &display_name)) {
1092 user->set_display_name(display_name);
1095 base::string16 given_name;
1096 if (prefs_given_names->GetStringWithoutPathExpansion(*it, &given_name)) {
1097 user->set_given_name(given_name);
1100 std::string display_email;
1101 if (prefs_display_emails->GetStringWithoutPathExpansion(*it,
1102 &display_email)) {
1103 user->set_display_email(display_email);
1107 user_loading_stage_ = STAGE_LOADED;
1109 for (UserList::iterator ui = users_.begin(), ue = users_.end();
1110 ui != ue; ++ui) {
1111 GetUserImageManager((*ui)->email())->LoadUserImage();
1115 void UserManagerImpl::RetrieveTrustedDevicePolicies() {
1116 ephemeral_users_enabled_ = false;
1117 owner_email_.clear();
1119 // Schedule a callback if device policy has not yet been verified.
1120 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
1121 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
1122 base::Unretained(this)))) {
1123 return;
1126 cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
1127 &ephemeral_users_enabled_);
1128 cros_settings_->GetString(kDeviceOwner, &owner_email_);
1130 EnsureUsersLoaded();
1132 bool changed = UpdateAndCleanUpPublicAccounts(
1133 policy::GetDeviceLocalAccounts(cros_settings_));
1135 // If ephemeral users are enabled and we are on the login screen, take this
1136 // opportunity to clean up by removing all regular users except the owner.
1137 if (ephemeral_users_enabled_ && !IsUserLoggedIn()) {
1138 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1139 kRegularUsers);
1140 prefs_users_update->Clear();
1141 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1142 const std::string user_email = (*it)->email();
1143 if ((*it)->GetType() == User::USER_TYPE_REGULAR &&
1144 user_email != owner_email_) {
1145 RemoveNonCryptohomeData(user_email);
1146 DeleteUser(*it);
1147 it = users_.erase(it);
1148 changed = true;
1149 } else {
1150 if ((*it)->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT)
1151 prefs_users_update->Append(new base::StringValue(user_email));
1152 ++it;
1157 if (changed)
1158 NotifyUserListChanged();
1161 bool UserManagerImpl::AreEphemeralUsersEnabled() const {
1162 policy::BrowserPolicyConnectorChromeOS* connector =
1163 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1164 return ephemeral_users_enabled_ &&
1165 (connector->IsEnterpriseManaged() || !owner_email_.empty());
1168 UserList& UserManagerImpl::GetUsersAndModify() {
1169 EnsureUsersLoaded();
1170 return users_;
1173 const User* UserManagerImpl::FindUserInList(const std::string& user_id) const {
1174 const UserList& users = GetUsers();
1175 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
1176 if ((*it)->email() == user_id)
1177 return *it;
1179 return NULL;
1182 const bool UserManagerImpl::UserExistsInList(const std::string& user_id) const {
1183 PrefService* local_state = g_browser_process->local_state();
1184 const base::ListValue* user_list = local_state->GetList(kRegularUsers);
1185 for (size_t i = 0; i < user_list->GetSize(); ++i) {
1186 std::string email;
1187 if (user_list->GetString(i, &email) && (user_id == email))
1188 return true;
1190 return false;
1193 User* UserManagerImpl::FindUserInListAndModify(const std::string& user_id) {
1194 UserList& users = GetUsersAndModify();
1195 for (UserList::iterator it = users.begin(); it != users.end(); ++it) {
1196 if ((*it)->email() == user_id)
1197 return *it;
1199 return NULL;
1202 void UserManagerImpl::GuestUserLoggedIn() {
1203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1204 active_user_ = User::CreateGuestUser();
1205 // TODO(nkostylev): Add support for passing guest session cryptohome
1206 // mount point. Legacy (--login-profile) value will be used for now.
1207 // http://crosbug.com/230859
1208 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1209 // Initializes wallpaper after active_user_ is set.
1210 WallpaperManager::Get()->SetUserWallpaperNow(UserManager::kGuestUserName);
1213 void UserManagerImpl::AddUserRecord(User* user) {
1214 // Add the user to the front of the user list.
1215 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1216 kRegularUsers);
1217 prefs_users_update->Insert(0, new base::StringValue(user->email()));
1218 users_.insert(users_.begin(), user);
1221 void UserManagerImpl::RegularUserLoggedIn(const std::string& user_id) {
1222 // Remove the user from the user list.
1223 active_user_ = RemoveRegularOrLocallyManagedUserFromList(user_id);
1225 // If the user was not found on the user list, create a new user.
1226 is_current_user_new_ = !active_user_;
1227 if (!active_user_) {
1228 active_user_ = User::CreateRegularUser(user_id);
1229 active_user_->set_oauth_token_status(LoadUserOAuthStatus(user_id));
1230 SaveUserDisplayName(active_user_->email(),
1231 base::UTF8ToUTF16(active_user_->GetAccountName(true)));
1232 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1235 AddUserRecord(active_user_);
1237 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, false);
1239 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1241 // Make sure that new data is persisted to Local State.
1242 g_browser_process->local_state()->CommitPendingWrite();
1245 void UserManagerImpl::RegularUserLoggedInAsEphemeral(
1246 const std::string& user_id) {
1247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1248 is_current_user_new_ = true;
1249 is_current_user_ephemeral_regular_user_ = true;
1250 active_user_ = User::CreateRegularUser(user_id);
1251 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, false);
1252 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1255 void UserManagerImpl::LocallyManagedUserLoggedIn(
1256 const std::string& user_id) {
1257 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
1259 // Remove the user from the user list.
1260 active_user_ = RemoveRegularOrLocallyManagedUserFromList(user_id);
1261 // If the user was not found on the user list, create a new user.
1262 if (!active_user_) {
1263 is_current_user_new_ = true;
1264 active_user_ = User::CreateLocallyManagedUser(user_id);
1265 // Leaving OAuth token status at the default state = unknown.
1266 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1267 } else {
1268 if (supervised_user_manager_->CheckForFirstRun(user_id)) {
1269 is_current_user_new_ = true;
1270 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1271 } else {
1272 is_current_user_new_ = false;
1276 // Add the user to the front of the user list.
1277 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1278 kRegularUsers);
1279 prefs_users_update->Insert(0, new base::StringValue(user_id));
1280 users_.insert(users_.begin(), active_user_);
1282 // Now that user is in the list, save display name.
1283 if (is_current_user_new_) {
1284 SaveUserDisplayName(active_user_->email(),
1285 active_user_->GetDisplayName());
1288 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, true);
1289 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1291 // Make sure that new data is persisted to Local State.
1292 g_browser_process->local_state()->CommitPendingWrite();
1295 void UserManagerImpl::PublicAccountUserLoggedIn(User* user) {
1296 is_current_user_new_ = true;
1297 active_user_ = user;
1298 // The UserImageManager chooses a random avatar picture when a user logs in
1299 // for the first time. Tell the UserImageManager that this user is not new to
1300 // prevent the avatar from getting changed.
1301 GetUserImageManager(user->email())->UserLoggedIn(false, true);
1302 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1305 void UserManagerImpl::KioskAppLoggedIn(const std::string& app_id) {
1306 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1307 policy::DeviceLocalAccount::Type device_local_account_type;
1308 DCHECK(policy::IsDeviceLocalAccountUser(app_id,
1309 &device_local_account_type));
1310 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
1311 device_local_account_type);
1313 active_user_ = User::CreateKioskAppUser(app_id);
1314 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1316 WallpaperManager::Get()->SetUserWallpaperNow(app_id);
1318 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
1319 // the kiosk_app_id in these objects, removing the need to re-parse the
1320 // device-local account list here to extract the kiosk_app_id.
1321 const std::vector<policy::DeviceLocalAccount> device_local_accounts =
1322 policy::GetDeviceLocalAccounts(cros_settings_);
1323 const policy::DeviceLocalAccount* account = NULL;
1324 for (std::vector<policy::DeviceLocalAccount>::const_iterator
1325 it = device_local_accounts.begin();
1326 it != device_local_accounts.end(); ++it) {
1327 if (it->user_id == app_id) {
1328 account = &*it;
1329 break;
1332 std::string kiosk_app_id;
1333 if (account) {
1334 kiosk_app_id = account->kiosk_app_id;
1335 } else {
1336 LOG(ERROR) << "Logged into nonexistent kiosk-app account: " << app_id;
1337 NOTREACHED();
1340 CommandLine* command_line = CommandLine::ForCurrentProcess();
1341 command_line->AppendSwitch(::switches::kForceAppMode);
1342 command_line->AppendSwitchASCII(::switches::kAppId, kiosk_app_id);
1344 // Disable window animation since kiosk app runs in a single full screen
1345 // window and window animation causes start-up janks.
1346 command_line->AppendSwitch(
1347 wm::switches::kWindowAnimationsDisabled);
1350 void UserManagerImpl::DemoAccountLoggedIn() {
1351 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1352 active_user_ = User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName);
1353 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1354 WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName);
1356 CommandLine* command_line = CommandLine::ForCurrentProcess();
1357 command_line->AppendSwitch(::switches::kForceAppMode);
1358 command_line->AppendSwitchASCII(::switches::kAppId,
1359 DemoAppLauncher::kDemoAppId);
1361 // Disable window animation since the demo app runs in a single full screen
1362 // window and window animation causes start-up janks.
1363 CommandLine::ForCurrentProcess()->AppendSwitch(
1364 wm::switches::kWindowAnimationsDisabled);
1367 void UserManagerImpl::RetailModeUserLoggedIn() {
1368 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1369 is_current_user_new_ = true;
1370 active_user_ = User::CreateRetailModeUser();
1371 GetUserImageManager(UserManager::kRetailModeUserName)->UserLoggedIn(
1372 is_current_user_new_,
1373 true);
1374 WallpaperManager::Get()->SetUserWallpaperNow(
1375 UserManager::kRetailModeUserName);
1378 void UserManagerImpl::NotifyOnLogin() {
1379 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1381 UserSessionManager::OverrideHomedir();
1383 UpdateNumberOfUsers();
1384 NotifyActiveUserHashChanged(active_user_->username_hash());
1385 NotifyActiveUserChanged(active_user_);
1386 UpdateLoginState();
1388 // TODO(nkostylev): Deprecate this notification in favor of
1389 // ActiveUserChanged() observer call.
1390 content::NotificationService::current()->Notify(
1391 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
1392 content::Source<UserManager>(this),
1393 content::Details<const User>(active_user_));
1395 UserSessionManager::GetInstance()->PerformPostUserLoggedInActions();
1398 User::OAuthTokenStatus UserManagerImpl::LoadUserOAuthStatus(
1399 const std::string& user_id) const {
1400 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1402 PrefService* local_state = g_browser_process->local_state();
1403 const base::DictionaryValue* prefs_oauth_status =
1404 local_state->GetDictionary(kUserOAuthTokenStatus);
1405 int oauth_token_status = User::OAUTH_TOKEN_STATUS_UNKNOWN;
1406 if (prefs_oauth_status &&
1407 prefs_oauth_status->GetIntegerWithoutPathExpansion(
1408 user_id, &oauth_token_status)) {
1409 User::OAuthTokenStatus result =
1410 static_cast<User::OAuthTokenStatus>(oauth_token_status);
1411 if (result == User::OAUTH2_TOKEN_STATUS_INVALID)
1412 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(result);
1413 return result;
1415 return User::OAUTH_TOKEN_STATUS_UNKNOWN;
1418 bool UserManagerImpl::LoadForceOnlineSignin(const std::string& user_id) const {
1419 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1421 PrefService* local_state = g_browser_process->local_state();
1422 const base::DictionaryValue* prefs_force_online =
1423 local_state->GetDictionary(kUserForceOnlineSignin);
1424 bool force_online_signin = false;
1425 if (prefs_force_online) {
1426 prefs_force_online->GetBooleanWithoutPathExpansion(user_id,
1427 &force_online_signin);
1429 return force_online_signin;
1432 void UserManagerImpl::UpdateOwnership() {
1433 bool is_owner = DeviceSettingsService::Get()->HasPrivateOwnerKey();
1434 VLOG(1) << "Current user " << (is_owner ? "is owner" : "is not owner");
1436 SetCurrentUserIsOwner(is_owner);
1439 void UserManagerImpl::RemoveNonCryptohomeData(const std::string& user_id) {
1440 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id);
1441 GetUserImageManager(user_id)->DeleteUserImage();
1443 PrefService* prefs = g_browser_process->local_state();
1444 DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
1445 prefs_display_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1447 DictionaryPrefUpdate prefs_given_name_update(prefs, kUserGivenName);
1448 prefs_given_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1450 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
1451 prefs_display_email_update->RemoveWithoutPathExpansion(user_id, NULL);
1453 DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
1454 prefs_oauth_update->RemoveWithoutPathExpansion(user_id, NULL);
1456 DictionaryPrefUpdate prefs_force_online_update(prefs, kUserForceOnlineSignin);
1457 prefs_force_online_update->RemoveWithoutPathExpansion(user_id, NULL);
1459 supervised_user_manager_->RemoveNonCryptohomeData(user_id);
1461 multi_profile_user_controller_->RemoveCachedValues(user_id);
1464 User* UserManagerImpl::RemoveRegularOrLocallyManagedUserFromList(
1465 const std::string& user_id) {
1466 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1467 kRegularUsers);
1468 prefs_users_update->Clear();
1469 User* user = NULL;
1470 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1471 const std::string user_email = (*it)->email();
1472 if (user_email == user_id) {
1473 user = *it;
1474 it = users_.erase(it);
1475 } else {
1476 if ((*it)->GetType() == User::USER_TYPE_REGULAR ||
1477 (*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) {
1478 prefs_users_update->Append(new base::StringValue(user_email));
1480 ++it;
1483 return user;
1486 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
1487 PrefService* local_state = g_browser_process->local_state();
1488 const std::string public_account_pending_data_removal =
1489 local_state->GetString(kPublicAccountPendingDataRemoval);
1490 if (public_account_pending_data_removal.empty() ||
1491 (IsUserLoggedIn() &&
1492 public_account_pending_data_removal == GetActiveUser()->email())) {
1493 return;
1496 RemoveNonCryptohomeData(public_account_pending_data_removal);
1497 local_state->ClearPref(kPublicAccountPendingDataRemoval);
1500 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
1501 const std::vector<std::string>& old_public_accounts) {
1502 std::set<std::string> users;
1503 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it)
1504 users.insert((*it)->email());
1506 // If the user is logged into a public account that has been removed from the
1507 // user list, mark the account's data as pending removal after logout.
1508 if (IsLoggedInAsPublicAccount()) {
1509 const std::string active_user_id = GetActiveUser()->email();
1510 if (users.find(active_user_id) == users.end()) {
1511 g_browser_process->local_state()->SetString(
1512 kPublicAccountPendingDataRemoval, active_user_id);
1513 users.insert(active_user_id);
1517 // Remove the data belonging to any other public accounts that are no longer
1518 // found on the user list.
1519 for (std::vector<std::string>::const_iterator
1520 it = old_public_accounts.begin();
1521 it != old_public_accounts.end(); ++it) {
1522 if (users.find(*it) == users.end())
1523 RemoveNonCryptohomeData(*it);
1527 bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
1528 const std::vector<policy::DeviceLocalAccount>& device_local_accounts) {
1529 // Try to remove any public account data marked as pending removal.
1530 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
1532 // Get the current list of public accounts.
1533 std::vector<std::string> old_public_accounts;
1534 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it) {
1535 if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT)
1536 old_public_accounts.push_back((*it)->email());
1539 // Get the new list of public accounts from policy.
1540 std::vector<std::string> new_public_accounts;
1541 for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
1542 device_local_accounts.begin();
1543 it != device_local_accounts.end(); ++it) {
1544 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
1545 // standard login framework: http://crbug.com/234694
1546 if (it->type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
1547 new_public_accounts.push_back(it->user_id);
1550 // If the list of public accounts has not changed, return.
1551 if (new_public_accounts.size() == old_public_accounts.size()) {
1552 bool changed = false;
1553 for (size_t i = 0; i < new_public_accounts.size(); ++i) {
1554 if (new_public_accounts[i] != old_public_accounts[i]) {
1555 changed = true;
1556 break;
1559 if (!changed)
1560 return false;
1563 // Persist the new list of public accounts in a pref.
1564 ListPrefUpdate prefs_public_accounts_update(g_browser_process->local_state(),
1565 kPublicAccounts);
1566 prefs_public_accounts_update->Clear();
1567 for (std::vector<std::string>::const_iterator it =
1568 new_public_accounts.begin();
1569 it != new_public_accounts.end(); ++it) {
1570 prefs_public_accounts_update->AppendString(*it);
1573 // Remove the old public accounts from the user list.
1574 for (UserList::iterator it = users_.begin(); it != users_.end();) {
1575 if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
1576 if (*it != GetLoggedInUser())
1577 DeleteUser(*it);
1578 it = users_.erase(it);
1579 } else {
1580 ++it;
1584 // Add the new public accounts to the front of the user list.
1585 for (std::vector<std::string>::const_reverse_iterator it =
1586 new_public_accounts.rbegin();
1587 it != new_public_accounts.rend(); ++it) {
1588 if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email())
1589 users_.insert(users_.begin(), GetLoggedInUser());
1590 else
1591 users_.insert(users_.begin(), User::CreatePublicAccountUser(*it));
1592 UpdatePublicAccountDisplayName(*it);
1595 for (UserList::iterator ui = users_.begin(),
1596 ue = users_.begin() + new_public_accounts.size();
1597 ui != ue; ++ui) {
1598 GetUserImageManager((*ui)->email())->LoadUserImage();
1601 // Remove data belonging to public accounts that are no longer found on the
1602 // user list.
1603 CleanUpPublicAccountNonCryptohomeData(old_public_accounts);
1605 return true;
1608 void UserManagerImpl::UpdatePublicAccountDisplayName(
1609 const std::string& user_id) {
1610 std::string display_name;
1612 if (device_local_account_policy_service_) {
1613 policy::DeviceLocalAccountPolicyBroker* broker =
1614 device_local_account_policy_service_->GetBrokerForUser(user_id);
1615 if (broker)
1616 display_name = broker->GetDisplayName();
1619 // Set or clear the display name.
1620 SaveUserDisplayName(user_id, base::UTF8ToUTF16(display_name));
1623 UserFlow* UserManagerImpl::GetCurrentUserFlow() const {
1624 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1625 if (!IsUserLoggedIn())
1626 return GetDefaultUserFlow();
1627 return GetUserFlow(GetLoggedInUser()->email());
1630 UserFlow* UserManagerImpl::GetUserFlow(const std::string& user_id) const {
1631 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1632 FlowMap::const_iterator it = specific_flows_.find(user_id);
1633 if (it != specific_flows_.end())
1634 return it->second;
1635 return GetDefaultUserFlow();
1638 void UserManagerImpl::SetUserFlow(const std::string& user_id, UserFlow* flow) {
1639 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1640 ResetUserFlow(user_id);
1641 specific_flows_[user_id] = flow;
1644 void UserManagerImpl::ResetUserFlow(const std::string& user_id) {
1645 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1646 FlowMap::iterator it = specific_flows_.find(user_id);
1647 if (it != specific_flows_.end()) {
1648 delete it->second;
1649 specific_flows_.erase(it);
1653 bool UserManagerImpl::AreLocallyManagedUsersAllowed() const {
1654 bool locally_managed_users_allowed = false;
1655 cros_settings_->GetBoolean(kAccountsPrefSupervisedUsersEnabled,
1656 &locally_managed_users_allowed);
1657 return locally_managed_users_allowed;
1660 UserFlow* UserManagerImpl::GetDefaultUserFlow() const {
1661 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1662 if (!default_flow_.get())
1663 default_flow_.reset(new DefaultUserFlow());
1664 return default_flow_.get();
1667 void UserManagerImpl::NotifyUserListChanged() {
1668 content::NotificationService::current()->Notify(
1669 chrome::NOTIFICATION_USER_LIST_CHANGED,
1670 content::Source<UserManager>(this),
1671 content::NotificationService::NoDetails());
1674 void UserManagerImpl::NotifyActiveUserChanged(const User* active_user) {
1675 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1676 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1677 session_state_observer_list_,
1678 ActiveUserChanged(active_user));
1681 void UserManagerImpl::NotifyUserAddedToSession(const User* added_user) {
1682 UpdateNumberOfUsers();
1683 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1684 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1685 session_state_observer_list_,
1686 UserAddedToSession(added_user));
1689 void UserManagerImpl::NotifyActiveUserHashChanged(const std::string& hash) {
1690 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1691 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1692 session_state_observer_list_,
1693 ActiveUserHashChanged(hash));
1696 void UserManagerImpl::NotifyPendingUserSessionsRestoreFinished() {
1697 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1698 user_sessions_restored_ = true;
1699 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1700 session_state_observer_list_,
1701 PendingUserSessionsRestoreFinished());
1704 void UserManagerImpl::UpdateLoginState() {
1705 if (!LoginState::IsInitialized())
1706 return; // LoginState may not be intialized in tests.
1707 LoginState::LoggedInState logged_in_state;
1708 logged_in_state = active_user_ ? LoginState::LOGGED_IN_ACTIVE
1709 : LoginState::LOGGED_IN_NONE;
1711 LoginState::LoggedInUserType login_user_type;
1712 if (logged_in_state == LoginState::LOGGED_IN_NONE)
1713 login_user_type = LoginState::LOGGED_IN_USER_NONE;
1714 else if (is_current_user_owner_)
1715 login_user_type = LoginState::LOGGED_IN_USER_OWNER;
1716 else if (active_user_->GetType() == User::USER_TYPE_GUEST)
1717 login_user_type = LoginState::LOGGED_IN_USER_GUEST;
1718 else if (active_user_->GetType() == User::USER_TYPE_RETAIL_MODE)
1719 login_user_type = LoginState::LOGGED_IN_USER_RETAIL_MODE;
1720 else if (active_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT)
1721 login_user_type = LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT;
1722 else if (active_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED)
1723 login_user_type = LoginState::LOGGED_IN_USER_LOCALLY_MANAGED;
1724 else if (active_user_->GetType() == User::USER_TYPE_KIOSK_APP)
1725 login_user_type = LoginState::LOGGED_IN_USER_KIOSK_APP;
1726 else
1727 login_user_type = LoginState::LOGGED_IN_USER_REGULAR;
1729 if (primary_user_) {
1730 LoginState::Get()->SetLoggedInStateAndPrimaryUser(
1731 logged_in_state, login_user_type, primary_user_->username_hash());
1732 } else {
1733 LoginState::Get()->SetLoggedInState(logged_in_state, login_user_type);
1737 void UserManagerImpl::SetLRUUser(User* user) {
1738 UserList::iterator it = std::find(lru_logged_in_users_.begin(),
1739 lru_logged_in_users_.end(),
1740 user);
1741 if (it != lru_logged_in_users_.end())
1742 lru_logged_in_users_.erase(it);
1743 lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user);
1746 void UserManagerImpl::OnRestoreActiveSessions(
1747 const SessionManagerClient::ActiveSessionsMap& sessions,
1748 bool success) {
1749 if (!success) {
1750 LOG(ERROR) << "Could not get list of active user sessions after crash.";
1751 // If we could not get list of active user sessions it is safer to just
1752 // sign out so that we don't get in the inconsistent state.
1753 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
1754 return;
1757 // One profile has been already loaded on browser start.
1758 DCHECK(GetLoggedInUsers().size() == 1);
1759 DCHECK(GetActiveUser());
1760 std::string active_user_id = GetActiveUser()->email();
1762 SessionManagerClient::ActiveSessionsMap::const_iterator it;
1763 for (it = sessions.begin(); it != sessions.end(); ++it) {
1764 if (active_user_id == it->first)
1765 continue;
1766 pending_user_sessions_[it->first] = it->second;
1768 RestorePendingUserSessions();
1771 void UserManagerImpl::RestorePendingUserSessions() {
1772 if (pending_user_sessions_.empty()) {
1773 NotifyPendingUserSessionsRestoreFinished();
1774 return;
1777 // Get next user to restore sessions and delete it from list.
1778 SessionManagerClient::ActiveSessionsMap::const_iterator it =
1779 pending_user_sessions_.begin();
1780 std::string user_id = it->first;
1781 std::string user_id_hash = it->second;
1782 DCHECK(!user_id.empty());
1783 DCHECK(!user_id_hash.empty());
1784 pending_user_sessions_.erase(user_id);
1786 // Check that this user is not logged in yet.
1787 UserList logged_in_users = GetLoggedInUsers();
1788 bool user_already_logged_in = false;
1789 for (UserList::const_iterator it = logged_in_users.begin();
1790 it != logged_in_users.end(); ++it) {
1791 const User* user = (*it);
1792 if (user->email() == user_id) {
1793 user_already_logged_in = true;
1794 break;
1797 DCHECK(!user_already_logged_in);
1799 if (!user_already_logged_in) {
1800 UserContext user_context(user_id);
1801 user_context.SetUserIDHash(user_id_hash);
1802 user_context.SetIsUsingOAuth(false);
1803 // Will call OnProfilePrepared() once profile has been loaded.
1804 LoginUtils::Get()->PrepareProfile(user_context,
1805 false, // has_auth_cookies
1806 true, // has_active_session
1807 this);
1808 } else {
1809 RestorePendingUserSessions();
1813 void UserManagerImpl::SendRegularUserLoginMetrics(const std::string& user_id) {
1814 // If this isn't the first time Chrome was run after the system booted,
1815 // assume that Chrome was restarted because a previous session ended.
1816 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1817 switches::kFirstExecAfterBoot)) {
1818 const std::string last_email =
1819 g_browser_process->local_state()->GetString(kLastLoggedInRegularUser);
1820 const base::TimeDelta time_to_login =
1821 base::TimeTicks::Now() - manager_creation_time_;
1822 if (!last_email.empty() && user_id != last_email &&
1823 time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) {
1824 UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay",
1825 time_to_login.InSeconds(), 0, kLogoutToLoginDelayMaxSec, 50);
1830 void UserManagerImpl::OnUserNotAllowed(const std::string& user_email) {
1831 LOG(ERROR) << "Shutdown session because a user is not allowed to be in the "
1832 "current session";
1833 chromeos::ShowMultiprofilesSessionAbortedDialog(user_email);
1836 void UserManagerImpl::UpdateUserAccountLocale(const std::string& user_id,
1837 const std::string& locale) {
1838 if (!locale.empty() &&
1839 locale != g_browser_process->GetApplicationLocale()) {
1840 BrowserThread::PostBlockingPoolTask(
1841 FROM_HERE,
1842 base::Bind(ResolveLocale, locale,
1843 base::Bind(&UserManagerImpl::DoUpdateAccountLocale,
1844 base::Unretained(this),
1845 user_id)));
1846 } else {
1847 DoUpdateAccountLocale(user_id, locale);
1851 void UserManagerImpl::DoUpdateAccountLocale(
1852 const std::string& user_id,
1853 const std::string& resolved_locale) {
1854 if (User* user = FindUserAndModify(user_id))
1855 user->SetAccountLocale(resolved_locale);
1858 void UserManagerImpl::UpdateNumberOfUsers() {
1859 size_t users = GetLoggedInUsers().size();
1860 if (users) {
1861 // Write the user number as UMA stat when a multi user session is possible.
1862 if ((users + GetUsersAdmittedForMultiProfile().size()) > 1)
1863 ash::MultiProfileUMA::RecordUserCount(users);
1866 base::debug::SetCrashKeyValue(crash_keys::kNumberOfUsers,
1867 base::StringPrintf("%" PRIuS, GetLoggedInUsers().size()));
1870 void UserManagerImpl::DeleteUser(User* user) {
1871 const bool is_active_user = (user == active_user_);
1872 delete user;
1873 if (is_active_user)
1874 active_user_ = NULL;
1877 } // namespace chromeos