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"
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
;
75 // A vector pref of the the regular users known on this device, arranged in LRU
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
,
116 cryptohome::MountError return_code
) {
117 // Log the error, but there's not much we can do.
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
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();
133 for (size_t i
= 0; i
< users_list
.GetSize(); ++i
) {
135 if (!users_list
.GetString(i
, &email
) || email
.empty()) {
136 LOG(ERROR
) << "Corrupt entry in user list at index " << i
<< ".";
139 if (existing_users
.find(email
) != existing_users
.end() ||
140 !users_set
->insert(email
).second
) {
141 LOG(ERROR
) << "Duplicate user: " << email
;
144 users_vector
->push_back(email
);
148 // Runs on SequencedWorkerPool thread. Passes resolved locale to
149 // |on_resolve_callback| on UI thread.
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
;
156 l10n_util::CheckAndResolveLocale(raw_locale
, &resolved_locale
);
157 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
158 base::Bind(on_resolve_callback
, resolved_locale
));
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
),
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());
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(
214 connector
->GetDeviceLocalAccountPolicyService(),
215 policy::key::kUserAvatarImage
,
217 avatar_policy_observer_
->Init();
219 wallpaper_policy_observer_
.reset(new policy::CloudExternalDataPolicyObserver(
221 connector
->GetDeviceLocalAccountPolicyService(),
222 policy::key::kWallpaperImage
,
224 wallpaper_policy_observer_
->Init();
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
)) {
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();
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
;
276 SupervisedUserManager
* UserManagerImpl::GetSupervisedUserManager() {
277 return supervised_user_manager_
.get();
280 const UserList
& UserManagerImpl::GetUsers() const {
281 const_cast<UserManagerImpl
*>(this)->EnsureUsersLoaded();
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
) {
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
) {
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
);
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(),
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())
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_
);
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
) {
354 Profile
* profile
= ProfileHelper::Get()->GetProfileByUser(user
);
355 const std::string behavior
=
356 profile
->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior
);
357 if (behavior
== MultiProfileUserController::kBehaviorUnrestricted
&&
359 unlock_users
.push_back(user
);
360 } else if (behavior
== MultiProfileUserController::kBehaviorPrimaryOnly
) {
362 << "Spotted primary-only multi-profile policy for non-primary user";
370 const std::string
& UserManagerImpl::GetOwnerEmail() {
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
;
393 policy::DeviceLocalAccount::Type device_local_account_type
;
394 if (user_id
== UserManager::kGuestUserName
) {
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();
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
);
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
,
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
: "");
453 void UserManagerImpl::SwitchActiveUser(const std::string
& user_id
) {
454 User
* user
= FindUserAndModify(user_id
);
456 NOTREACHED() << "Switching to a non-existing user";
459 if (user
== active_user_
) {
460 NOTREACHED() << "Switching to a user who is already active";
463 if (!user
->is_logged_in()) {
464 NOTREACHED() << "Switching to a user that is not logged in";
467 if (user
->GetType() != User::USER_TYPE_REGULAR
) {
468 NOTREACHED() << "Switching to a non-regular user";
471 if (user
->username_hash().empty()) {
472 NOTREACHED() << "Switching to a user that doesn't have username_hash set";
476 DCHECK(active_user_
);
477 active_user_
->set_is_active(false);
478 user
->set_is_active(true);
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;
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
))
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())
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
)
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.
553 cros_settings
->GetString(kDeviceOwner
, &owner
);
554 if (user_email
== owner
) {
555 // Owner is not allowed to be removed from the device.
558 RemoveNonOwnerUserInternal(user_email
, delegate
);
561 void UserManagerImpl::RemoveNonOwnerUserInternal(const std::string
& user_email
,
562 RemoveUserDelegate
* delegate
) {
564 delegate
->OnBeforeUserRemoved(user_email
);
565 RemoveUserFromList(user_email
);
566 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
567 user_email
, base::Bind(&OnRemoveUserComplete
, user_email
));
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
583 ListPrefUpdate
users_update(g_browser_process
->local_state(),
585 users_update
->Remove(base::StringValue(user_id
), NULL
);
587 NOTREACHED() << "Users are not loaded yet.";
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
)
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
)
609 return FindUserInListAndModify(user_id
);
612 const User
* UserManagerImpl::GetLoggedInUser() const {
613 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
617 User
* UserManagerImpl::GetLoggedInUser() {
618 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
622 const User
* UserManagerImpl::GetActiveUser() const {
623 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
627 User
* UserManagerImpl::GetActiveUser() {
628 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
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
);
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
))
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
))
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(
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
);
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
))
719 PrefService
* local_state
= g_browser_process
->local_state();
721 DictionaryPrefUpdate
display_email_update(local_state
, kUserDisplayEmail
);
722 display_email_update
->SetWithoutPathExpansion(
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(
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
) {
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();
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
);
797 case chrome::NOTIFICATION_PROFILE_CREATED
: {
798 Profile
* profile
= content::Source
<Profile
>(source
).ptr();
799 User
* user
= ProfileHelper::Get()->GetUserByProfile(profile
);
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();
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
);
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
);
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());
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
)
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
;
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
));
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
957 if (user_id
== UserManager::kGuestUserName
||
958 user_id
== UserManager::kRetailModeUserName
||
959 user_id
== kStubUser
) {
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
)) {
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
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())) {
981 // Data belonging to any other user is ephemeral when:
982 // a) Going through the regular login flow and the ephemeral users policy is
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())
1040 if (user_loading_stage_
!= STAGE_NOT_LOADED
)
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 ®ular_users
, ®ular_users_set
);
1077 for (std::vector
<std::string
>::const_iterator it
= regular_users
.begin();
1078 it
!= regular_users
.end(); ++it
) {
1080 const std::string domain
= gaia::ExtractDomainName(*it
);
1081 if (domain
== UserManager::kLocallyManagedUserDomain
)
1082 user
= User::CreateLocallyManagedUser(*it
);
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
,
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
,
1103 user
->set_display_email(display_email
);
1107 user_loading_stage_
= STAGE_LOADED
;
1109 for (UserList::iterator ui
= users_
.begin(), ue
= users_
.end();
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)))) {
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(),
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
);
1147 it
= users_
.erase(it
);
1150 if ((*it
)->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT
)
1151 prefs_users_update
->Append(new base::StringValue(user_email
));
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();
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
)
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
) {
1187 if (user_list
->GetString(i
, &email
) && (user_id
== email
))
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
)
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(),
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
);
1268 if (supervised_user_manager_
->CheckForFirstRun(user_id
)) {
1269 is_current_user_new_
= true;
1270 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
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(),
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
) {
1332 std::string kiosk_app_id
;
1334 kiosk_app_id
= account
->kiosk_app_id
;
1336 LOG(ERROR
) << "Logged into nonexistent kiosk-app account: " << app_id
;
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_
,
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_
);
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
);
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(),
1468 prefs_users_update
->Clear();
1470 for (UserList::iterator it
= users_
.begin(); it
!= users_
.end(); ) {
1471 const std::string user_email
= (*it
)->email();
1472 if (user_email
== user_id
) {
1474 it
= users_
.erase(it
);
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
));
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())) {
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
]) {
1563 // Persist the new list of public accounts in a pref.
1564 ListPrefUpdate
prefs_public_accounts_update(g_browser_process
->local_state(),
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())
1578 it
= users_
.erase(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());
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();
1598 GetUserImageManager((*ui
)->email())->LoadUserImage();
1601 // Remove data belonging to public accounts that are no longer found on the
1603 CleanUpPublicAccountNonCryptohomeData(old_public_accounts
);
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
);
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())
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()) {
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
;
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());
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(),
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
,
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();
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
)
1766 pending_user_sessions_
[it
->first
] = it
->second
;
1768 RestorePendingUserSessions();
1771 void UserManagerImpl::RestorePendingUserSessions() {
1772 if (pending_user_sessions_
.empty()) {
1773 NotifyPendingUserSessionsRestoreFinished();
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;
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
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 "
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(
1842 base::Bind(ResolveLocale
, locale
,
1843 base::Bind(&UserManagerImpl::DoUpdateAccountLocale
,
1844 base::Unretained(this),
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();
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_
);
1874 active_user_
= NULL
;
1877 } // namespace chromeos