1 // Copyright (c) 2013 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/user_manager_impl.h"
10 #include "ash/multi_profile_uma.h"
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/command_line.h"
14 #include "base/compiler_specific.h"
15 #include "base/files/file_path.h"
16 #include "base/format_macros.h"
17 #include "base/logging.h"
18 #include "base/metrics/histogram.h"
19 #include "base/prefs/pref_registry_simple.h"
20 #include "base/prefs/pref_service.h"
21 #include "base/prefs/scoped_user_pref_update.h"
22 #include "base/rand_util.h"
23 #include "base/strings/string_util.h"
24 #include "base/strings/stringprintf.h"
25 #include "base/strings/utf_string_conversions.h"
26 #include "base/sys_info.h"
27 #include "base/threading/worker_pool.h"
28 #include "base/values.h"
29 #include "chrome/browser/app_mode/app_mode_utils.h"
30 #include "chrome/browser/browser_process.h"
31 #include "chrome/browser/chrome_notification_types.h"
32 #include "chrome/browser/chromeos/base/locale_util.h"
33 #include "chrome/browser/chromeos/login/auth_sync_observer.h"
34 #include "chrome/browser/chromeos/login/auth_sync_observer_factory.h"
35 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
36 #include "chrome/browser/chromeos/login/login_display.h"
37 #include "chrome/browser/chromeos/login/login_utils.h"
38 #include "chrome/browser/chromeos/login/multi_profile_user_controller.h"
39 #include "chrome/browser/chromeos/login/remove_user_delegate.h"
40 #include "chrome/browser/chromeos/login/supervised_user_manager_impl.h"
41 #include "chrome/browser/chromeos/login/user_image_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/managed_mode/chromeos/managed_user_password_service_factory.h"
49 #include "chrome/browser/managed_mode/chromeos/manager_password_service_factory.h"
50 #include "chrome/browser/net/nss_context.h"
51 #include "chrome/browser/profiles/profile.h"
52 #include "chrome/browser/profiles/profile_manager.h"
53 #include "chrome/browser/sync/profile_sync_service.h"
54 #include "chrome/browser/sync/profile_sync_service_factory.h"
55 #include "chrome/common/chrome_constants.h"
56 #include "chrome/common/chrome_switches.h"
57 #include "chrome/common/crash_keys.h"
58 #include "chrome/common/pref_names.h"
59 #include "chromeos/cert_loader.h"
60 #include "chromeos/chromeos_switches.h"
61 #include "chromeos/cryptohome/async_method_caller.h"
62 #include "chromeos/dbus/dbus_thread_manager.h"
63 #include "chromeos/login/login_state.h"
64 #include "chromeos/settings/cros_settings_names.h"
65 #include "content/public/browser/browser_thread.h"
66 #include "content/public/browser/notification_service.h"
67 #include "google_apis/gaia/gaia_auth_util.h"
68 #include "google_apis/gaia/google_service_auth_error.h"
69 #include "policy/policy_constants.h"
70 #include "ui/base/l10n/l10n_util.h"
71 #include "ui/wm/core/wm_core_switches.h"
73 using content::BrowserThread
;
78 // A vector pref of the the regular users known on this device, arranged in LRU
80 const char kRegularUsers
[] = "LoggedInUsers";
82 // A vector pref of the public accounts defined on this device.
83 const char kPublicAccounts
[] = "PublicAccounts";
85 // A string pref that gets set when a public account is removed but a user is
86 // currently logged into that account, requiring the account's data to be
87 // removed after logout.
88 const char kPublicAccountPendingDataRemoval
[] =
89 "PublicAccountPendingDataRemoval";
91 // A dictionary that maps user IDs to the displayed name.
92 const char kUserDisplayName
[] = "UserDisplayName";
94 // A dictionary that maps user IDs to the user's given name.
95 const char kUserGivenName
[] = "UserGivenName";
97 // A dictionary that maps user IDs to the displayed (non-canonical) emails.
98 const char kUserDisplayEmail
[] = "UserDisplayEmail";
100 // A dictionary that maps user IDs to OAuth token presence flag.
101 const char kUserOAuthTokenStatus
[] = "OAuthTokenStatus";
103 // A dictionary that maps user IDs to a flag indicating whether online
104 // authentication against GAIA should be enforced during the next sign-in.
105 const char kUserForceOnlineSignin
[] = "UserForceOnlineSignin";
107 // A string pref containing the ID of the last user who logged in if it was
108 // a regular user or an empty string if it was another type of user (guest,
109 // kiosk, public account, etc.).
110 const char kLastLoggedInRegularUser
[] = "LastLoggedInRegularUser";
112 // Upper bound for a histogram metric reporting the amount of time between
113 // one regular user logging out and a different regular user logging in.
114 const int kLogoutToLoginDelayMaxSec
= 1800;
116 // Callback that is called after user removal is complete.
117 void OnRemoveUserComplete(const std::string
& user_email
,
119 cryptohome::MountError return_code
) {
120 // Log the error, but there's not much we can do.
122 LOG(ERROR
) << "Removal of cryptohome for " << user_email
123 << " failed, return code: " << return_code
;
127 // Helper function that copies users from |users_list| to |users_vector| and
128 // |users_set|. Duplicates and users already present in |existing_users| are
130 void ParseUserList(const base::ListValue
& users_list
,
131 const std::set
<std::string
>& existing_users
,
132 std::vector
<std::string
>* users_vector
,
133 std::set
<std::string
>* users_set
) {
134 users_vector
->clear();
136 for (size_t i
= 0; i
< users_list
.GetSize(); ++i
) {
138 if (!users_list
.GetString(i
, &email
) || email
.empty()) {
139 LOG(ERROR
) << "Corrupt entry in user list at index " << i
<< ".";
142 if (existing_users
.find(email
) != existing_users
.end() ||
143 !users_set
->insert(email
).second
) {
144 LOG(ERROR
) << "Duplicate user: " << email
;
147 users_vector
->push_back(email
);
151 class UserHashMatcher
{
153 explicit UserHashMatcher(const std::string
& h
) : username_hash(h
) {}
154 bool operator()(const User
* user
) const {
155 return user
->username_hash() == username_hash
;
159 const std::string
& username_hash
;
162 // Runs on SequencedWorkerPool thread. Passes resolved locale to
163 // |on_resolve_callback| on UI thread.
165 const std::string
& raw_locale
,
166 base::Callback
<void(const std::string
&)> on_resolve_callback
) {
167 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI
));
168 std::string resolved_locale
;
170 l10n_util::CheckAndResolveLocale(raw_locale
, &resolved_locale
);
171 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
172 base::Bind(on_resolve_callback
, resolved_locale
));
175 // Callback to GetNSSCertDatabaseForProfile. It starts CertLoader using the
176 // provided NSS database. It must be called for primary user only.
177 void OnGetNSSCertDatabaseForUser(net::NSSCertDatabase
* database
) {
178 if (!CertLoader::IsInitialized())
181 CertLoader::Get()->StartWithNSSDB(database
);
187 void UserManager::RegisterPrefs(PrefRegistrySimple
* registry
) {
188 registry
->RegisterListPref(kRegularUsers
);
189 registry
->RegisterListPref(kPublicAccounts
);
190 registry
->RegisterStringPref(kPublicAccountPendingDataRemoval
, "");
191 registry
->RegisterStringPref(kLastLoggedInRegularUser
, "");
192 registry
->RegisterDictionaryPref(kUserDisplayName
);
193 registry
->RegisterDictionaryPref(kUserGivenName
);
194 registry
->RegisterDictionaryPref(kUserDisplayEmail
);
195 registry
->RegisterDictionaryPref(kUserOAuthTokenStatus
);
196 registry
->RegisterDictionaryPref(kUserForceOnlineSignin
);
197 SupervisedUserManager::RegisterPrefs(registry
);
198 SessionLengthLimiter::RegisterPrefs(registry
);
201 UserManagerImpl::UserManagerImpl()
202 : cros_settings_(CrosSettings::Get()),
203 device_local_account_policy_service_(NULL
),
204 user_loading_stage_(STAGE_NOT_LOADED
),
207 session_started_(false),
208 user_sessions_restored_(false),
209 is_current_user_owner_(false),
210 is_current_user_new_(false),
211 is_current_user_ephemeral_regular_user_(false),
212 ephemeral_users_enabled_(false),
213 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
214 manager_creation_time_(base::TimeTicks::Now()) {
215 UpdateNumberOfUsers();
216 // UserManager instance should be used only on UI thread.
217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
218 registrar_
.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED
,
219 content::NotificationService::AllSources());
220 registrar_
.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED
,
221 content::NotificationService::AllSources());
223 chrome::NOTIFICATION_PROFILE_CREATED
,
224 content::NotificationService::AllSources());
225 RetrieveTrustedDevicePolicies();
226 local_accounts_subscription_
= cros_settings_
->AddSettingsObserver(
227 kAccountsPrefDeviceLocalAccounts
,
228 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies
,
229 base::Unretained(this)));
230 supervised_users_subscription_
= cros_settings_
->AddSettingsObserver(
231 kAccountsPrefSupervisedUsersEnabled
,
232 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies
,
233 base::Unretained(this)));
234 multi_profile_user_controller_
.reset(new MultiProfileUserController(
235 this, g_browser_process
->local_state()));
237 policy::BrowserPolicyConnectorChromeOS
* connector
=
238 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
239 avatar_policy_observer_
.reset(new policy::CloudExternalDataPolicyObserver(
242 connector
->GetDeviceLocalAccountPolicyService(),
243 policy::key::kUserAvatarImage
,
245 avatar_policy_observer_
->Init();
247 wallpaper_policy_observer_
.reset(new policy::CloudExternalDataPolicyObserver(
250 connector
->GetDeviceLocalAccountPolicyService(),
251 policy::key::kWallpaperImage
,
253 wallpaper_policy_observer_
->Init();
258 UserManagerImpl::~UserManagerImpl() {
259 // Can't use STLDeleteElements because of the private destructor of User.
260 for (UserList::iterator it
= users_
.begin(); it
!= users_
.end();
261 it
= users_
.erase(it
)) {
264 // These are pointers to the same User instances that were in users_ list.
265 logged_in_users_
.clear();
266 lru_logged_in_users_
.clear();
268 DeleteUser(active_user_
);
271 void UserManagerImpl::Shutdown() {
272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
273 local_accounts_subscription_
.reset();
274 supervised_users_subscription_
.reset();
275 // Stop the session length limiter.
276 session_length_limiter_
.reset();
278 if (device_local_account_policy_service_
)
279 device_local_account_policy_service_
->RemoveObserver(this);
281 for (UserImageManagerMap::iterator it
= user_image_managers_
.begin(),
282 ie
= user_image_managers_
.end();
284 it
->second
->Shutdown();
286 multi_profile_user_controller_
.reset();
287 avatar_policy_observer_
.reset();
288 wallpaper_policy_observer_
.reset();
291 MultiProfileUserController
* UserManagerImpl::GetMultiProfileUserController() {
292 return multi_profile_user_controller_
.get();
295 UserImageManager
* UserManagerImpl::GetUserImageManager(
296 const std::string
& user_id
) {
297 UserImageManagerMap::iterator ui
= user_image_managers_
.find(user_id
);
298 if (ui
!= user_image_managers_
.end())
299 return ui
->second
.get();
300 linked_ptr
<UserImageManagerImpl
> mgr(new UserImageManagerImpl(user_id
, this));
301 user_image_managers_
[user_id
] = mgr
;
305 SupervisedUserManager
* UserManagerImpl::GetSupervisedUserManager() {
306 return supervised_user_manager_
.get();
309 const UserList
& UserManagerImpl::GetUsers() const {
310 const_cast<UserManagerImpl
*>(this)->EnsureUsersLoaded();
314 UserList
UserManagerImpl::GetUsersAdmittedForMultiProfile() const {
315 if (!UserManager::IsMultipleProfilesAllowed())
318 // Supervised users are not allowed to use multi profile.
319 if (logged_in_users_
.size() == 1 &&
320 GetPrimaryUser()->GetType() != User::USER_TYPE_REGULAR
)
324 int num_users_allowed
= 0;
325 const UserList
& users
= GetUsers();
326 for (UserList::const_iterator it
= users
.begin(); it
!= users
.end(); ++it
) {
327 if ((*it
)->GetType() == User::USER_TYPE_REGULAR
&& !(*it
)->is_logged_in()) {
328 MultiProfileUserController::UserAllowedInSessionResult check
=
329 multi_profile_user_controller_
->
330 IsUserAllowedInSession((*it
)->email());
331 if (check
== MultiProfileUserController::
332 NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS
) {
336 // Users with a policy that prevents them being added to a session will be
337 // shown in login UI but will be grayed out.
338 if (check
== MultiProfileUserController::ALLOWED
||
339 check
== MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS
) {
340 result
.push_back(*it
);
341 if (check
== MultiProfileUserController::ALLOWED
)
347 // We only show multi-profiles sign in UI if there's at least one user that
348 // is allowed to be added to the session.
349 if (!num_users_allowed
)
355 const UserList
& UserManagerImpl::GetLoggedInUsers() const {
356 return logged_in_users_
;
359 const UserList
& UserManagerImpl::GetLRULoggedInUsers() {
360 // If there is no user logged in, we return the active user as the only one.
361 if (lru_logged_in_users_
.empty() && active_user_
) {
362 temp_single_logged_in_users_
.clear();
363 temp_single_logged_in_users_
.insert(temp_single_logged_in_users_
.begin(),
365 return temp_single_logged_in_users_
;
367 return lru_logged_in_users_
;
370 UserList
UserManagerImpl::GetUnlockUsers() const {
371 const UserList
& logged_in_users
= GetLoggedInUsers();
372 if (logged_in_users
.empty())
375 UserList unlock_users
;
376 Profile
* profile
= GetProfileByUser(primary_user_
);
377 std::string primary_behavior
=
378 profile
->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior
);
380 // Specific case: only one logged in user or
381 // primary user has primary-only multi-profile policy.
382 if (logged_in_users
.size() == 1 ||
383 primary_behavior
== MultiProfileUserController::kBehaviorPrimaryOnly
) {
384 if (primary_user_
->can_lock())
385 unlock_users
.push_back(primary_user_
);
387 // Fill list of potential unlock users based on multi-profile policy state.
388 for (UserList::const_iterator it
= logged_in_users
.begin();
389 it
!= logged_in_users
.end(); ++it
) {
391 Profile
* profile
= GetProfileByUser(user
);
392 const std::string behavior
=
393 profile
->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior
);
394 if (behavior
== MultiProfileUserController::kBehaviorUnrestricted
&&
396 unlock_users
.push_back(user
);
397 } else if (behavior
== MultiProfileUserController::kBehaviorPrimaryOnly
) {
399 << "Spotted primary-only multi-profile policy for non-primary user";
407 const std::string
& UserManagerImpl::GetOwnerEmail() {
411 void UserManagerImpl::UserLoggedIn(const std::string
& user_id
,
412 const std::string
& username_hash
,
413 bool browser_restart
) {
414 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
416 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles
))
417 DCHECK(!IsUserLoggedIn());
419 User
* user
= FindUserInListAndModify(user_id
);
420 if (active_user_
&& user
) {
421 user
->set_is_logged_in(true);
422 user
->set_username_hash(username_hash
);
423 logged_in_users_
.push_back(user
);
424 lru_logged_in_users_
.push_back(user
);
425 // Reset the new user flag if the user already exists.
426 is_current_user_new_
= false;
427 NotifyUserAddedToSession(user
);
428 // Remember that we need to switch to this user as soon as profile ready.
429 pending_user_switch_
= user_id
;
433 policy::DeviceLocalAccount::Type device_local_account_type
;
434 if (user_id
== UserManager::kGuestUserName
) {
436 } else if (user_id
== UserManager::kRetailModeUserName
) {
437 RetailModeUserLoggedIn();
438 } else if (policy::IsDeviceLocalAccountUser(user_id
,
439 &device_local_account_type
) &&
440 device_local_account_type
==
441 policy::DeviceLocalAccount::TYPE_KIOSK_APP
) {
442 KioskAppLoggedIn(user_id
);
443 } else if (DemoAppLauncher::IsDemoAppSession(user_id
)) {
444 DemoAccountLoggedIn();
448 if (user
&& user
->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT
) {
449 PublicAccountUserLoggedIn(user
);
450 } else if ((user
&& user
->GetType() == User::USER_TYPE_LOCALLY_MANAGED
) ||
451 (!user
&& gaia::ExtractDomainName(user_id
) ==
452 UserManager::kLocallyManagedUserDomain
)) {
453 LocallyManagedUserLoggedIn(user_id
);
454 } else if (browser_restart
&& user_id
== g_browser_process
->local_state()->
455 GetString(kPublicAccountPendingDataRemoval
)) {
456 PublicAccountUserLoggedIn(User::CreatePublicAccountUser(user_id
));
457 } else if (user_id
!= owner_email_
&& !user
&&
458 (AreEphemeralUsersEnabled() || browser_restart
)) {
459 RegularUserLoggedInAsEphemeral(user_id
);
461 RegularUserLoggedIn(user_id
);
464 // Initialize the session length limiter and start it only if
465 // session limit is defined by the policy.
466 session_length_limiter_
.reset(new SessionLengthLimiter(NULL
,
469 DCHECK(active_user_
);
470 active_user_
->set_is_logged_in(true);
471 active_user_
->set_is_active(true);
472 active_user_
->set_username_hash(username_hash
);
474 // Place user who just signed in to the top of the logged in users.
475 logged_in_users_
.insert(logged_in_users_
.begin(), active_user_
);
476 SetLRUUser(active_user_
);
478 if (!primary_user_
) {
479 primary_user_
= active_user_
;
480 if (primary_user_
->GetType() == User::USER_TYPE_REGULAR
)
481 SendRegularUserLoginMetrics(user_id
);
484 UMA_HISTOGRAM_ENUMERATION("UserManager.LoginUserType",
485 active_user_
->GetType(), User::NUM_USER_TYPES
);
487 g_browser_process
->local_state()->SetString(kLastLoggedInRegularUser
,
488 (active_user_
->GetType() == User::USER_TYPE_REGULAR
) ? user_id
: "");
493 void UserManagerImpl::SwitchActiveUser(const std::string
& user_id
) {
494 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles
))
497 User
* user
= FindUserAndModify(user_id
);
499 NOTREACHED() << "Switching to a non-existing user";
502 if (user
== active_user_
) {
503 NOTREACHED() << "Switching to a user who is already active";
506 if (!user
->is_logged_in()) {
507 NOTREACHED() << "Switching to a user that is not logged in";
510 if (user
->GetType() != User::USER_TYPE_REGULAR
) {
511 NOTREACHED() << "Switching to a non-regular user";
514 if (user
->username_hash().empty()) {
515 NOTREACHED() << "Switching to a user that doesn't have username_hash set";
519 DCHECK(active_user_
);
520 active_user_
->set_is_active(false);
521 user
->set_is_active(true);
524 // Move the user to the front.
525 SetLRUUser(active_user_
);
527 NotifyActiveUserHashChanged(active_user_
->username_hash());
528 NotifyActiveUserChanged(active_user_
);
531 void UserManagerImpl::RestoreActiveSessions() {
532 DBusThreadManager::Get()->GetSessionManagerClient()->RetrieveActiveSessions(
533 base::Bind(&UserManagerImpl::OnRestoreActiveSessions
,
534 base::Unretained(this)));
537 void UserManagerImpl::SessionStarted() {
538 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
539 session_started_
= true;
541 content::NotificationService::current()->Notify(
542 chrome::NOTIFICATION_SESSION_STARTED
,
543 content::Source
<UserManager
>(this),
544 content::Details
<const User
>(active_user_
));
545 if (is_current_user_new_
) {
546 // Make sure that the new user's data is persisted to Local State.
547 g_browser_process
->local_state()->CommitPendingWrite();
551 void UserManagerImpl::RemoveUser(const std::string
& user_id
,
552 RemoveUserDelegate
* delegate
) {
553 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
555 const User
* user
= FindUser(user_id
);
556 if (!user
|| (user
->GetType() != User::USER_TYPE_REGULAR
&&
557 user
->GetType() != User::USER_TYPE_LOCALLY_MANAGED
))
560 // Sanity check: we must not remove single user unless it's an enterprise
561 // device. This check may seem redundant at a first sight because
562 // this single user must be an owner and we perform special check later
563 // in order not to remove an owner. However due to non-instant nature of
564 // ownership assignment this later check may sometimes fail.
565 // See http://crosbug.com/12723
566 policy::BrowserPolicyConnectorChromeOS
* connector
=
567 g_browser_process
->platform_part()
568 ->browser_policy_connector_chromeos();
569 if (users_
.size() < 2 && !connector
->IsEnterpriseManaged())
572 // Sanity check: do not allow any of the the logged in users to be removed.
573 for (UserList::const_iterator it
= logged_in_users_
.begin();
574 it
!= logged_in_users_
.end(); ++it
) {
575 if ((*it
)->email() == user_id
)
579 RemoveUserInternal(user_id
, delegate
);
582 void UserManagerImpl::RemoveUserInternal(const std::string
& user_email
,
583 RemoveUserDelegate
* delegate
) {
584 CrosSettings
* cros_settings
= CrosSettings::Get();
586 // Ensure the value of owner email has been fetched.
587 if (CrosSettingsProvider::TRUSTED
!= cros_settings
->PrepareTrustedValues(
588 base::Bind(&UserManagerImpl::RemoveUserInternal
,
589 base::Unretained(this),
590 user_email
, delegate
))) {
591 // Value of owner email is not fetched yet. RemoveUserInternal will be
592 // called again after fetch completion.
596 cros_settings
->GetString(kDeviceOwner
, &owner
);
597 if (user_email
== owner
) {
598 // Owner is not allowed to be removed from the device.
601 RemoveNonOwnerUserInternal(user_email
, delegate
);
604 void UserManagerImpl::RemoveNonOwnerUserInternal(const std::string
& user_email
,
605 RemoveUserDelegate
* delegate
) {
607 delegate
->OnBeforeUserRemoved(user_email
);
608 RemoveUserFromList(user_email
);
609 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
610 user_email
, base::Bind(&OnRemoveUserComplete
, user_email
));
613 delegate
->OnUserRemoved(user_email
);
616 void UserManagerImpl::RemoveUserFromList(const std::string
& user_id
) {
617 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
618 RemoveNonCryptohomeData(user_id
);
619 if (user_loading_stage_
== STAGE_LOADED
) {
620 DeleteUser(RemoveRegularOrLocallyManagedUserFromList(user_id
));
621 } else if (user_loading_stage_
== STAGE_LOADING
) {
622 DCHECK(gaia::ExtractDomainName(user_id
) ==
623 UserManager::kLocallyManagedUserDomain
);
624 // Special case, removing partially-constructed supervised user during user
626 ListPrefUpdate
users_update(g_browser_process
->local_state(),
628 users_update
->Remove(base::StringValue(user_id
), NULL
);
630 NOTREACHED() << "Users are not loaded yet.";
633 // Make sure that new data is persisted to Local State.
634 g_browser_process
->local_state()->CommitPendingWrite();
637 bool UserManagerImpl::IsKnownUser(const std::string
& user_id
) const {
638 return FindUser(user_id
) != NULL
;
641 const User
* UserManagerImpl::FindUser(const std::string
& user_id
) const {
642 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
643 if (active_user_
&& active_user_
->email() == user_id
)
645 return FindUserInList(user_id
);
648 User
* UserManagerImpl::FindUserAndModify(const std::string
& user_id
) {
649 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
650 if (active_user_
&& active_user_
->email() == user_id
)
652 return FindUserInListAndModify(user_id
);
655 const User
* UserManagerImpl::GetLoggedInUser() const {
656 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
660 User
* UserManagerImpl::GetLoggedInUser() {
661 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
665 const User
* UserManagerImpl::GetActiveUser() const {
666 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
670 User
* UserManagerImpl::GetActiveUser() {
671 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
675 const User
* UserManagerImpl::GetPrimaryUser() const {
676 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
677 return primary_user_
;
680 User
* UserManagerImpl::GetUserByProfile(Profile
* profile
) const {
681 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
682 if (ProfileHelper::IsSigninProfile(profile
))
685 if (IsMultipleProfilesAllowed()) {
686 const std::string username_hash
=
687 ProfileHelper::GetUserIdHashFromProfile(profile
);
688 const UserList
& users
= GetUsers();
689 const UserList::const_iterator pos
= std::find_if(
690 users
.begin(), users
.end(), UserHashMatcher(username_hash
));
691 if (pos
!= users
.end())
694 // Many tests do not have their users registered with UserManager and
695 // runs here. If |active_user_| matches |profile|, returns it.
696 return active_user_
&&
697 ProfileHelper::GetProfilePathByUserIdHash(
698 active_user_
->username_hash()) == profile
->GetPath()
705 Profile
* UserManagerImpl::GetProfileByUser(const User
* user
) const {
706 Profile
* profile
= NULL
;
707 if (IsMultipleProfilesAllowed() && user
->is_profile_created())
708 profile
= ProfileHelper::GetProfileByUserIdHash(user
->username_hash());
710 profile
= ProfileManager::GetActiveUserProfile();
712 // GetActiveUserProfile() or GetProfileByUserIdHash() returns a new instance
713 // of ProfileImpl(), but actually its OffTheRecordProfile() should be used.
714 if (profile
&& IsLoggedInAsGuest())
715 profile
= profile
->GetOffTheRecordProfile();
719 void UserManagerImpl::SaveUserOAuthStatus(
720 const std::string
& user_id
,
721 User::OAuthTokenStatus oauth_token_status
) {
722 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
724 DVLOG(1) << "Saving user OAuth token status in Local State";
725 User
* user
= FindUserAndModify(user_id
);
727 user
->set_oauth_token_status(oauth_token_status
);
729 GetUserFlow(user_id
)->HandleOAuthTokenStatusChange(oauth_token_status
);
731 // Do not update local state if data stored or cached outside the user's
732 // cryptohome is to be treated as ephemeral.
733 if (IsUserNonCryptohomeDataEphemeral(user_id
))
736 PrefService
* local_state
= g_browser_process
->local_state();
738 DictionaryPrefUpdate
oauth_status_update(local_state
, kUserOAuthTokenStatus
);
739 oauth_status_update
->SetWithoutPathExpansion(user_id
,
740 new base::FundamentalValue(static_cast<int>(oauth_token_status
)));
743 void UserManagerImpl::SaveForceOnlineSignin(const std::string
& user_id
,
744 bool force_online_signin
) {
745 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
747 // Do not update local state if data stored or cached outside the user's
748 // cryptohome is to be treated as ephemeral.
749 if (IsUserNonCryptohomeDataEphemeral(user_id
))
752 DictionaryPrefUpdate
force_online_update(g_browser_process
->local_state(),
753 kUserForceOnlineSignin
);
754 force_online_update
->SetBooleanWithoutPathExpansion(user_id
,
755 force_online_signin
);
758 void UserManagerImpl::SaveUserDisplayName(const std::string
& user_id
,
759 const base::string16
& display_name
) {
760 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
762 if (User
* user
= FindUserAndModify(user_id
)) {
763 user
->set_display_name(display_name
);
765 // Do not update local state if data stored or cached outside the user's
766 // cryptohome is to be treated as ephemeral.
767 if (!IsUserNonCryptohomeDataEphemeral(user_id
)) {
768 PrefService
* local_state
= g_browser_process
->local_state();
770 DictionaryPrefUpdate
display_name_update(local_state
, kUserDisplayName
);
771 display_name_update
->SetWithoutPathExpansion(
773 new base::StringValue(display_name
));
775 supervised_user_manager_
->UpdateManagerName(user_id
, display_name
);
780 base::string16
UserManagerImpl::GetUserDisplayName(
781 const std::string
& user_id
) const {
782 const User
* user
= FindUser(user_id
);
783 return user
? user
->display_name() : base::string16();
786 void UserManagerImpl::SaveUserDisplayEmail(const std::string
& user_id
,
787 const std::string
& display_email
) {
788 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
790 User
* user
= FindUserAndModify(user_id
);
792 return; // Ignore if there is no such user.
794 user
->set_display_email(display_email
);
796 // Do not update local state if data stored or cached outside the user's
797 // cryptohome is to be treated as ephemeral.
798 if (IsUserNonCryptohomeDataEphemeral(user_id
))
801 PrefService
* local_state
= g_browser_process
->local_state();
803 DictionaryPrefUpdate
display_email_update(local_state
, kUserDisplayEmail
);
804 display_email_update
->SetWithoutPathExpansion(
806 new base::StringValue(display_email
));
809 std::string
UserManagerImpl::GetUserDisplayEmail(
810 const std::string
& user_id
) const {
811 const User
* user
= FindUser(user_id
);
812 return user
? user
->display_email() : user_id
;
815 void UserManagerImpl::UpdateUserAccountData(
816 const std::string
& user_id
,
817 const UserAccountData
& account_data
) {
818 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
820 SaveUserDisplayName(user_id
, account_data
.display_name());
822 if (User
* user
= FindUserAndModify(user_id
)) {
823 base::string16 given_name
= account_data
.given_name();
824 user
->set_given_name(given_name
);
825 if (!IsUserNonCryptohomeDataEphemeral(user_id
)) {
826 PrefService
* local_state
= g_browser_process
->local_state();
828 DictionaryPrefUpdate
given_name_update(local_state
, kUserGivenName
);
829 given_name_update
->SetWithoutPathExpansion(
831 new base::StringValue(given_name
));
835 UpdateUserAccountLocale(user_id
, account_data
.locale());
838 // TODO(alemate): http://crbug.com/288941 : Respect preferred language list in
839 // the Google user profile.
841 // Returns true if callback will be called.
842 bool UserManagerImpl::RespectLocalePreference(
845 scoped_ptr
<locale_util::SwitchLanguageCallback
> callback
) const {
846 if (g_browser_process
== NULL
)
848 if ((user
== NULL
) || (user
!= GetPrimaryUser()) ||
849 (!user
->is_profile_created()))
852 // In case of Multi Profile mode we don't apply profile locale because it is
854 if (GetLoggedInUsers().size() != 1)
856 const PrefService
* prefs
= profile
->GetPrefs();
860 std::string pref_locale
;
861 const std::string pref_app_locale
=
862 prefs
->GetString(prefs::kApplicationLocale
);
863 const std::string pref_bkup_locale
=
864 prefs
->GetString(prefs::kApplicationLocaleBackup
);
866 pref_locale
= pref_app_locale
;
867 if (pref_locale
.empty())
868 pref_locale
= pref_bkup_locale
;
870 const std::string
* account_locale
= NULL
;
871 if (pref_locale
.empty() && user
->has_gaia_account()) {
872 if (user
->GetAccountLocale() == NULL
)
873 return false; // wait until Account profile is loaded.
874 account_locale
= user
->GetAccountLocale();
875 pref_locale
= *account_locale
;
877 const std::string global_app_locale
=
878 g_browser_process
->GetApplicationLocale();
879 if (pref_locale
.empty())
880 pref_locale
= global_app_locale
;
881 DCHECK(!pref_locale
.empty());
882 LOG(WARNING
) << "RespectLocalePreference: "
883 << "app_locale='" << pref_app_locale
<< "', "
884 << "bkup_locale='" << pref_bkup_locale
<< "', "
885 << (account_locale
!= NULL
886 ? (std::string("account_locale='") + (*account_locale
) +
888 : (std::string("account_locale - unused. ")))
889 << " Selected '" << pref_locale
<< "'";
890 profile
->ChangeAppLocale(pref_locale
, Profile::APP_LOCALE_CHANGED_VIA_LOGIN
);
892 // Here we don't enable keyboard layouts for normal users. Input methods
893 // are set up when the user first logs in. Then the user may customize the
894 // input methods. Hence changing input methods here, just because the user's
895 // UI language is different from the login screen UI language, is not
896 // desirable. Note that input method preferences are synced, so users can use
897 // their farovite input methods as soon as the preferences are synced.
899 // For Guest mode, user locale preferences will never get initialized.
900 // So input methods should be enabled somewhere.
901 const bool enable_layouts
= UserManager::Get()->IsLoggedInAsGuest();
902 locale_util::SwitchLanguage(pref_locale
,
904 false /* login_layouts_only */,
910 void UserManagerImpl::StopPolicyObserverForTesting() {
911 avatar_policy_observer_
.reset();
912 wallpaper_policy_observer_
.reset();
915 void UserManagerImpl::Observe(int type
,
916 const content::NotificationSource
& source
,
917 const content::NotificationDetails
& details
) {
919 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED
:
920 if (!device_local_account_policy_service_
) {
921 policy::BrowserPolicyConnectorChromeOS
* connector
=
922 g_browser_process
->platform_part()
923 ->browser_policy_connector_chromeos();
924 device_local_account_policy_service_
=
925 connector
->GetDeviceLocalAccountPolicyService();
926 if (device_local_account_policy_service_
)
927 device_local_account_policy_service_
->AddObserver(this);
929 // Making this call synchronously is not gonna cut it because
930 // notification order is not defined and in a single message loop run and
931 // getting trusted settings rely on a reload that happens on the very same
932 // notification observation.
933 base::MessageLoop::current()->PostTask(FROM_HERE
,
934 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies
,
935 base::Unretained(this)));
936 UserManagerImpl::UpdateOwnership();
938 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED
: {
939 Profile
* profile
= content::Details
<Profile
>(details
).ptr();
940 if (IsUserLoggedIn() &&
941 !IsLoggedInAsGuest() &&
942 !IsLoggedInAsKioskApp()) {
943 if (IsLoggedInAsLocallyManagedUser())
944 ManagedUserPasswordServiceFactory::GetForProfile(profile
);
945 if (IsLoggedInAsRegularUser())
946 ManagerPasswordServiceFactory::GetForProfile(profile
);
948 if (!profile
->IsOffTheRecord()) {
949 AuthSyncObserver
* sync_observer
=
950 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile
);
951 sync_observer
->StartObserving();
952 multi_profile_user_controller_
->StartObserving(profile
);
956 // Now that the user profile has been initialized and
957 // |GetNSSCertDatabaseForProfile| is safe to be used, get the NSS cert
958 // database for the primary user and start certificate loader with it.
959 if (IsUserLoggedIn() &&
961 profile
== GetProfileByUser(GetPrimaryUser()) &&
962 CertLoader::IsInitialized() &&
963 base::SysInfo::IsRunningOnChromeOS()) {
964 GetNSSCertDatabaseForProfile(profile
,
965 base::Bind(&OnGetNSSCertDatabaseForUser
));
969 case chrome::NOTIFICATION_PROFILE_CREATED
: {
970 Profile
* profile
= content::Source
<Profile
>(source
).ptr();
971 User
* user
= GetUserByProfile(profile
);
973 user
->set_profile_is_created();
974 // If there is pending user switch, do it now.
975 if (!pending_user_switch_
.empty()) {
976 // Call SwitchActiveUser async because otherwise it may cause
977 // ProfileManager::GetProfile before the profile gets registered
978 // in ProfileManager. It happens in case of sync profile load when
979 // NOTIFICATION_PROFILE_CREATED is called synchronously.
980 base::MessageLoop::current()->PostTask(FROM_HERE
,
981 base::Bind(&UserManagerImpl::SwitchActiveUser
,
982 base::Unretained(this),
983 pending_user_switch_
));
984 pending_user_switch_
.clear();
993 void UserManagerImpl::OnExternalDataSet(const std::string
& policy
,
994 const std::string
& user_id
) {
995 if (policy
== policy::key::kUserAvatarImage
)
996 GetUserImageManager(user_id
)->OnExternalDataSet(policy
);
997 else if (policy
== policy::key::kWallpaperImage
)
998 WallpaperManager::Get()->OnPolicySet(policy
, user_id
);
1003 void UserManagerImpl::OnExternalDataCleared(const std::string
& policy
,
1004 const std::string
& user_id
) {
1005 if (policy
== policy::key::kUserAvatarImage
)
1006 GetUserImageManager(user_id
)->OnExternalDataCleared(policy
);
1007 else if (policy
== policy::key::kWallpaperImage
)
1008 WallpaperManager::Get()->OnPolicyCleared(policy
, user_id
);
1013 void UserManagerImpl::OnExternalDataFetched(const std::string
& policy
,
1014 const std::string
& user_id
,
1015 scoped_ptr
<std::string
> data
) {
1016 if (policy
== policy::key::kUserAvatarImage
)
1017 GetUserImageManager(user_id
)->OnExternalDataFetched(policy
, data
.Pass());
1018 else if (policy
== policy::key::kWallpaperImage
)
1019 WallpaperManager::Get()->OnPolicyFetched(policy
, user_id
, data
.Pass());
1024 void UserManagerImpl::OnPolicyUpdated(const std::string
& user_id
) {
1025 UpdatePublicAccountDisplayName(user_id
);
1026 NotifyUserListChanged();
1029 void UserManagerImpl::OnDeviceLocalAccountsChanged() {
1030 // No action needed here, changes to the list of device-local accounts get
1031 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
1034 bool UserManagerImpl::IsCurrentUserOwner() const {
1035 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1036 base::AutoLock
lk(is_current_user_owner_lock_
);
1037 return is_current_user_owner_
;
1040 void UserManagerImpl::SetCurrentUserIsOwner(bool is_current_user_owner
) {
1041 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1043 base::AutoLock
lk(is_current_user_owner_lock_
);
1044 is_current_user_owner_
= is_current_user_owner
;
1049 bool UserManagerImpl::IsCurrentUserNew() const {
1050 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1051 return is_current_user_new_
;
1054 bool UserManagerImpl::IsCurrentUserNonCryptohomeDataEphemeral() const {
1055 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1056 return IsUserLoggedIn() &&
1057 IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email());
1060 bool UserManagerImpl::CanCurrentUserLock() const {
1061 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1062 return IsUserLoggedIn() && active_user_
->can_lock() &&
1063 GetCurrentUserFlow()->CanLockScreen();
1066 bool UserManagerImpl::IsUserLoggedIn() const {
1067 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1068 return active_user_
;
1071 bool UserManagerImpl::IsLoggedInAsRegularUser() const {
1072 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1073 return IsUserLoggedIn() &&
1074 active_user_
->GetType() == User::USER_TYPE_REGULAR
;
1077 bool UserManagerImpl::IsLoggedInAsDemoUser() const {
1078 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1079 return IsUserLoggedIn() &&
1080 active_user_
->GetType() == User::USER_TYPE_RETAIL_MODE
;
1083 bool UserManagerImpl::IsLoggedInAsPublicAccount() const {
1084 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1085 return IsUserLoggedIn() &&
1086 active_user_
->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT
;
1089 bool UserManagerImpl::IsLoggedInAsGuest() const {
1090 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1091 return IsUserLoggedIn() &&
1092 active_user_
->GetType() == User::USER_TYPE_GUEST
;
1095 bool UserManagerImpl::IsLoggedInAsLocallyManagedUser() const {
1096 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1097 return IsUserLoggedIn() &&
1098 active_user_
->GetType() == User::USER_TYPE_LOCALLY_MANAGED
;
1101 bool UserManagerImpl::IsLoggedInAsKioskApp() const {
1102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1103 return IsUserLoggedIn() &&
1104 active_user_
->GetType() == User::USER_TYPE_KIOSK_APP
;
1107 bool UserManagerImpl::IsLoggedInAsStub() const {
1108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1109 return IsUserLoggedIn() && active_user_
->email() == kStubUser
;
1112 bool UserManagerImpl::IsSessionStarted() const {
1113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1114 return session_started_
;
1117 bool UserManagerImpl::UserSessionsRestored() const {
1118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1119 return user_sessions_restored_
;
1122 bool UserManagerImpl::HasBrowserRestarted() const {
1123 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
1124 return base::SysInfo::IsRunningOnChromeOS() &&
1125 command_line
->HasSwitch(switches::kLoginUser
) &&
1126 !command_line
->HasSwitch(switches::kLoginPassword
);
1129 bool UserManagerImpl::IsUserNonCryptohomeDataEphemeral(
1130 const std::string
& user_id
) const {
1131 // Data belonging to the guest, retail mode and stub users is always
1133 if (user_id
== UserManager::kGuestUserName
||
1134 user_id
== UserManager::kRetailModeUserName
||
1135 user_id
== kStubUser
) {
1139 // Data belonging to the owner, anyone found on the user list and obsolete
1140 // public accounts whose data has not been removed yet is not ephemeral.
1141 if (user_id
== owner_email_
|| UserExistsInList(user_id
) ||
1142 user_id
== g_browser_process
->local_state()->
1143 GetString(kPublicAccountPendingDataRemoval
)) {
1147 // Data belonging to the currently logged-in user is ephemeral when:
1148 // a) The user logged into a regular account while the ephemeral users policy
1151 // b) The user logged into any other account type.
1152 if (IsUserLoggedIn() && (user_id
== GetLoggedInUser()->email()) &&
1153 (is_current_user_ephemeral_regular_user_
|| !IsLoggedInAsRegularUser())) {
1157 // Data belonging to any other user is ephemeral when:
1158 // a) Going through the regular login flow and the ephemeral users policy is
1161 // b) The browser is restarting after a crash.
1162 return AreEphemeralUsersEnabled() || HasBrowserRestarted();
1165 void UserManagerImpl::AddObserver(UserManager::Observer
* obs
) {
1166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1167 observer_list_
.AddObserver(obs
);
1170 void UserManagerImpl::RemoveObserver(UserManager::Observer
* obs
) {
1171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1172 observer_list_
.RemoveObserver(obs
);
1175 void UserManagerImpl::AddSessionStateObserver(
1176 UserManager::UserSessionStateObserver
* obs
) {
1177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1178 session_state_observer_list_
.AddObserver(obs
);
1181 void UserManagerImpl::RemoveSessionStateObserver(
1182 UserManager::UserSessionStateObserver
* obs
) {
1183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1184 session_state_observer_list_
.RemoveObserver(obs
);
1187 void UserManagerImpl::NotifyLocalStateChanged() {
1188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1189 FOR_EACH_OBSERVER(UserManager::Observer
, observer_list_
,
1190 LocalStateChanged(this));
1193 void UserManagerImpl::OnProfilePrepared(Profile
* profile
) {
1194 LoginUtils::Get()->DoBrowserLaunch(profile
,
1195 NULL
); // host_, not needed here
1197 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName
)) {
1198 // Did not log in (we crashed or are debugging), need to restore Sync.
1199 // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
1200 // users once it is fully multi-profile aware. http://crbug.com/238987
1201 // For now if we have other user pending sessions they'll override OAuth
1202 // session restore for previous users.
1203 LoginUtils::Get()->RestoreAuthenticationSession(profile
);
1206 // Restore other user sessions if any.
1207 RestorePendingUserSessions();
1210 void UserManagerImpl::EnsureUsersLoaded() {
1211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1212 if (!g_browser_process
|| !g_browser_process
->local_state())
1215 if (user_loading_stage_
!= STAGE_NOT_LOADED
)
1217 user_loading_stage_
= STAGE_LOADING
;
1218 // Clean up user list first. All code down the path should be synchronous,
1219 // so that local state after transaction rollback is in consistent state.
1220 // This process also should not trigger EnsureUsersLoaded again.
1221 if (supervised_user_manager_
->HasFailedUserCreationTransaction())
1222 supervised_user_manager_
->RollbackUserCreationTransaction();
1224 PrefService
* local_state
= g_browser_process
->local_state();
1225 const base::ListValue
* prefs_regular_users
=
1226 local_state
->GetList(kRegularUsers
);
1227 const base::ListValue
* prefs_public_sessions
=
1228 local_state
->GetList(kPublicAccounts
);
1229 const base::DictionaryValue
* prefs_display_names
=
1230 local_state
->GetDictionary(kUserDisplayName
);
1231 const base::DictionaryValue
* prefs_given_names
=
1232 local_state
->GetDictionary(kUserGivenName
);
1233 const base::DictionaryValue
* prefs_display_emails
=
1234 local_state
->GetDictionary(kUserDisplayEmail
);
1236 // Load public sessions first.
1237 std::vector
<std::string
> public_sessions
;
1238 std::set
<std::string
> public_sessions_set
;
1239 ParseUserList(*prefs_public_sessions
, std::set
<std::string
>(),
1240 &public_sessions
, &public_sessions_set
);
1241 for (std::vector
<std::string
>::const_iterator it
= public_sessions
.begin();
1242 it
!= public_sessions
.end(); ++it
) {
1243 users_
.push_back(User::CreatePublicAccountUser(*it
));
1244 UpdatePublicAccountDisplayName(*it
);
1247 // Load regular users and locally managed users.
1248 std::vector
<std::string
> regular_users
;
1249 std::set
<std::string
> regular_users_set
;
1250 ParseUserList(*prefs_regular_users
, public_sessions_set
,
1251 ®ular_users
, ®ular_users_set
);
1252 for (std::vector
<std::string
>::const_iterator it
= regular_users
.begin();
1253 it
!= regular_users
.end(); ++it
) {
1255 const std::string domain
= gaia::ExtractDomainName(*it
);
1256 if (domain
== UserManager::kLocallyManagedUserDomain
)
1257 user
= User::CreateLocallyManagedUser(*it
);
1259 user
= User::CreateRegularUser(*it
);
1260 user
->set_oauth_token_status(LoadUserOAuthStatus(*it
));
1261 user
->set_force_online_signin(LoadForceOnlineSignin(*it
));
1262 users_
.push_back(user
);
1264 base::string16 display_name
;
1265 if (prefs_display_names
->GetStringWithoutPathExpansion(*it
,
1267 user
->set_display_name(display_name
);
1270 base::string16 given_name
;
1271 if (prefs_given_names
->GetStringWithoutPathExpansion(*it
, &given_name
)) {
1272 user
->set_given_name(given_name
);
1275 std::string display_email
;
1276 if (prefs_display_emails
->GetStringWithoutPathExpansion(*it
,
1278 user
->set_display_email(display_email
);
1282 user_loading_stage_
= STAGE_LOADED
;
1284 for (UserList::iterator ui
= users_
.begin(), ue
= users_
.end();
1286 GetUserImageManager((*ui
)->email())->LoadUserImage();
1290 void UserManagerImpl::RetrieveTrustedDevicePolicies() {
1291 ephemeral_users_enabled_
= false;
1294 // Schedule a callback if device policy has not yet been verified.
1295 if (CrosSettingsProvider::TRUSTED
!= cros_settings_
->PrepareTrustedValues(
1296 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies
,
1297 base::Unretained(this)))) {
1301 cros_settings_
->GetBoolean(kAccountsPrefEphemeralUsersEnabled
,
1302 &ephemeral_users_enabled_
);
1303 cros_settings_
->GetString(kDeviceOwner
, &owner_email_
);
1305 EnsureUsersLoaded();
1307 bool changed
= UpdateAndCleanUpPublicAccounts(
1308 policy::GetDeviceLocalAccounts(cros_settings_
));
1310 // If ephemeral users are enabled and we are on the login screen, take this
1311 // opportunity to clean up by removing all regular users except the owner.
1312 if (ephemeral_users_enabled_
&& !IsUserLoggedIn()) {
1313 ListPrefUpdate
prefs_users_update(g_browser_process
->local_state(),
1315 prefs_users_update
->Clear();
1316 for (UserList::iterator it
= users_
.begin(); it
!= users_
.end(); ) {
1317 const std::string user_email
= (*it
)->email();
1318 if ((*it
)->GetType() == User::USER_TYPE_REGULAR
&&
1319 user_email
!= owner_email_
) {
1320 RemoveNonCryptohomeData(user_email
);
1322 it
= users_
.erase(it
);
1325 if ((*it
)->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT
)
1326 prefs_users_update
->Append(new base::StringValue(user_email
));
1333 NotifyUserListChanged();
1336 bool UserManagerImpl::AreEphemeralUsersEnabled() const {
1337 policy::BrowserPolicyConnectorChromeOS
* connector
=
1338 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
1339 return ephemeral_users_enabled_
&&
1340 (connector
->IsEnterpriseManaged() || !owner_email_
.empty());
1343 UserList
& UserManagerImpl::GetUsersAndModify() {
1344 EnsureUsersLoaded();
1348 const User
* UserManagerImpl::FindUserInList(const std::string
& user_id
) const {
1349 const UserList
& users
= GetUsers();
1350 for (UserList::const_iterator it
= users
.begin(); it
!= users
.end(); ++it
) {
1351 if ((*it
)->email() == user_id
)
1357 const bool UserManagerImpl::UserExistsInList(const std::string
& user_id
) const {
1358 PrefService
* local_state
= g_browser_process
->local_state();
1359 const base::ListValue
* user_list
= local_state
->GetList(kRegularUsers
);
1360 for (size_t i
= 0; i
< user_list
->GetSize(); ++i
) {
1362 if (user_list
->GetString(i
, &email
) && (user_id
== email
))
1368 User
* UserManagerImpl::FindUserInListAndModify(const std::string
& user_id
) {
1369 UserList
& users
= GetUsersAndModify();
1370 for (UserList::iterator it
= users
.begin(); it
!= users
.end(); ++it
) {
1371 if ((*it
)->email() == user_id
)
1377 void UserManagerImpl::GuestUserLoggedIn() {
1378 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1379 active_user_
= User::CreateGuestUser();
1380 // TODO(nkostylev): Add support for passing guest session cryptohome
1381 // mount point. Legacy (--login-profile) value will be used for now.
1382 // http://crosbug.com/230859
1383 active_user_
->SetStubImage(User::kInvalidImageIndex
, false);
1384 // Initializes wallpaper after active_user_ is set.
1385 WallpaperManager::Get()->SetUserWallpaperNow(UserManager::kGuestUserName
);
1388 void UserManagerImpl::AddUserRecord(User
* user
) {
1389 // Add the user to the front of the user list.
1390 ListPrefUpdate
prefs_users_update(g_browser_process
->local_state(),
1392 prefs_users_update
->Insert(0, new base::StringValue(user
->email()));
1393 users_
.insert(users_
.begin(), user
);
1396 void UserManagerImpl::RegularUserLoggedIn(const std::string
& user_id
) {
1397 // Remove the user from the user list.
1398 active_user_
= RemoveRegularOrLocallyManagedUserFromList(user_id
);
1400 // If the user was not found on the user list, create a new user.
1401 is_current_user_new_
= !active_user_
;
1402 if (!active_user_
) {
1403 active_user_
= User::CreateRegularUser(user_id
);
1404 active_user_
->set_oauth_token_status(LoadUserOAuthStatus(user_id
));
1405 SaveUserDisplayName(active_user_
->email(),
1406 base::UTF8ToUTF16(active_user_
->GetAccountName(true)));
1407 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
1410 AddUserRecord(active_user_
);
1412 GetUserImageManager(user_id
)->UserLoggedIn(is_current_user_new_
, false);
1414 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1416 // Make sure that new data is persisted to Local State.
1417 g_browser_process
->local_state()->CommitPendingWrite();
1420 void UserManagerImpl::RegularUserLoggedInAsEphemeral(
1421 const std::string
& user_id
) {
1422 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1423 is_current_user_new_
= true;
1424 is_current_user_ephemeral_regular_user_
= true;
1425 active_user_
= User::CreateRegularUser(user_id
);
1426 GetUserImageManager(user_id
)->UserLoggedIn(is_current_user_new_
, false);
1427 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
1430 void UserManagerImpl::LocallyManagedUserLoggedIn(
1431 const std::string
& user_id
) {
1432 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
1434 // Remove the user from the user list.
1435 active_user_
= RemoveRegularOrLocallyManagedUserFromList(user_id
);
1436 // If the user was not found on the user list, create a new user.
1437 if (!active_user_
) {
1438 is_current_user_new_
= true;
1439 active_user_
= User::CreateLocallyManagedUser(user_id
);
1440 // Leaving OAuth token status at the default state = unknown.
1441 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
1443 if (supervised_user_manager_
->CheckForFirstRun(user_id
)) {
1444 is_current_user_new_
= true;
1445 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
1447 is_current_user_new_
= false;
1451 // Add the user to the front of the user list.
1452 ListPrefUpdate
prefs_users_update(g_browser_process
->local_state(),
1454 prefs_users_update
->Insert(0, new base::StringValue(user_id
));
1455 users_
.insert(users_
.begin(), active_user_
);
1457 // Now that user is in the list, save display name.
1458 if (is_current_user_new_
) {
1459 SaveUserDisplayName(active_user_
->email(),
1460 active_user_
->GetDisplayName());
1463 GetUserImageManager(user_id
)->UserLoggedIn(is_current_user_new_
, true);
1464 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1466 // Make sure that new data is persisted to Local State.
1467 g_browser_process
->local_state()->CommitPendingWrite();
1470 void UserManagerImpl::PublicAccountUserLoggedIn(User
* user
) {
1471 is_current_user_new_
= true;
1472 active_user_
= user
;
1473 // The UserImageManager chooses a random avatar picture when a user logs in
1474 // for the first time. Tell the UserImageManager that this user is not new to
1475 // prevent the avatar from getting changed.
1476 GetUserImageManager(user
->email())->UserLoggedIn(false, true);
1477 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1480 void UserManagerImpl::KioskAppLoggedIn(const std::string
& app_id
) {
1481 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1482 policy::DeviceLocalAccount::Type device_local_account_type
;
1483 DCHECK(policy::IsDeviceLocalAccountUser(app_id
,
1484 &device_local_account_type
));
1485 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP
,
1486 device_local_account_type
);
1488 active_user_
= User::CreateKioskAppUser(app_id
);
1489 active_user_
->SetStubImage(User::kInvalidImageIndex
, false);
1491 WallpaperManager::Get()->SetUserWallpaperNow(app_id
);
1493 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
1494 // the kiosk_app_id in these objects, removing the need to re-parse the
1495 // device-local account list here to extract the kiosk_app_id.
1496 const std::vector
<policy::DeviceLocalAccount
> device_local_accounts
=
1497 policy::GetDeviceLocalAccounts(cros_settings_
);
1498 const policy::DeviceLocalAccount
* account
= NULL
;
1499 for (std::vector
<policy::DeviceLocalAccount
>::const_iterator
1500 it
= device_local_accounts
.begin();
1501 it
!= device_local_accounts
.end(); ++it
) {
1502 if (it
->user_id
== app_id
) {
1507 std::string kiosk_app_id
;
1509 kiosk_app_id
= account
->kiosk_app_id
;
1511 LOG(ERROR
) << "Logged into nonexistent kiosk-app account: " << app_id
;
1515 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
1516 command_line
->AppendSwitch(::switches::kForceAppMode
);
1517 command_line
->AppendSwitchASCII(::switches::kAppId
, kiosk_app_id
);
1519 // Disable window animation since kiosk app runs in a single full screen
1520 // window and window animation causes start-up janks.
1521 command_line
->AppendSwitch(
1522 wm::switches::kWindowAnimationsDisabled
);
1525 void UserManagerImpl::DemoAccountLoggedIn() {
1526 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1527 active_user_
= User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName
);
1528 active_user_
->SetStubImage(User::kInvalidImageIndex
, false);
1529 WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName
);
1531 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
1532 command_line
->AppendSwitch(::switches::kForceAppMode
);
1533 command_line
->AppendSwitchASCII(::switches::kAppId
,
1534 DemoAppLauncher::kDemoAppId
);
1536 // Disable window animation since the demo app runs in a single full screen
1537 // window and window animation causes start-up janks.
1538 CommandLine::ForCurrentProcess()->AppendSwitch(
1539 wm::switches::kWindowAnimationsDisabled
);
1542 void UserManagerImpl::RetailModeUserLoggedIn() {
1543 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1544 is_current_user_new_
= true;
1545 active_user_
= User::CreateRetailModeUser();
1546 GetUserImageManager(UserManager::kRetailModeUserName
)->UserLoggedIn(
1547 is_current_user_new_
,
1549 WallpaperManager::Get()->SetUserWallpaperNow(
1550 UserManager::kRetailModeUserName
);
1553 void UserManagerImpl::NotifyOnLogin() {
1554 UpdateNumberOfUsers();
1555 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1556 NotifyActiveUserHashChanged(active_user_
->username_hash());
1557 NotifyActiveUserChanged(active_user_
);
1560 // TODO(nkostylev): Deprecate this notification in favor of
1561 // ActiveUserChanged() observer call.
1562 content::NotificationService::current()->Notify(
1563 chrome::NOTIFICATION_LOGIN_USER_CHANGED
,
1564 content::Source
<UserManager
>(this),
1565 content::Details
<const User
>(active_user_
));
1567 // Owner must be first user in session. DeviceSettingsService can't deal with
1568 // multiple user and will mix up ownership, crbug.com/230018.
1569 if (GetLoggedInUsers().size() == 1) {
1570 // Indicate to DeviceSettingsService that the owner key may have become
1572 DeviceSettingsService::Get()->SetUsername(active_user_
->email());
1576 User::OAuthTokenStatus
UserManagerImpl::LoadUserOAuthStatus(
1577 const std::string
& user_id
) const {
1578 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1580 PrefService
* local_state
= g_browser_process
->local_state();
1581 const base::DictionaryValue
* prefs_oauth_status
=
1582 local_state
->GetDictionary(kUserOAuthTokenStatus
);
1583 int oauth_token_status
= User::OAUTH_TOKEN_STATUS_UNKNOWN
;
1584 if (prefs_oauth_status
&&
1585 prefs_oauth_status
->GetIntegerWithoutPathExpansion(
1586 user_id
, &oauth_token_status
)) {
1587 User::OAuthTokenStatus result
=
1588 static_cast<User::OAuthTokenStatus
>(oauth_token_status
);
1589 if (result
== User::OAUTH2_TOKEN_STATUS_INVALID
)
1590 GetUserFlow(user_id
)->HandleOAuthTokenStatusChange(result
);
1593 return User::OAUTH_TOKEN_STATUS_UNKNOWN
;
1596 bool UserManagerImpl::LoadForceOnlineSignin(const std::string
& user_id
) const {
1597 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1599 PrefService
* local_state
= g_browser_process
->local_state();
1600 const base::DictionaryValue
* prefs_force_online
=
1601 local_state
->GetDictionary(kUserForceOnlineSignin
);
1602 bool force_online_signin
= false;
1603 if (prefs_force_online
) {
1604 prefs_force_online
->GetBooleanWithoutPathExpansion(user_id
,
1605 &force_online_signin
);
1607 return force_online_signin
;
1610 void UserManagerImpl::UpdateOwnership() {
1611 bool is_owner
= DeviceSettingsService::Get()->HasPrivateOwnerKey();
1612 VLOG(1) << "Current user " << (is_owner
? "is owner" : "is not owner");
1614 SetCurrentUserIsOwner(is_owner
);
1617 void UserManagerImpl::RemoveNonCryptohomeData(const std::string
& user_id
) {
1618 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id
);
1619 GetUserImageManager(user_id
)->DeleteUserImage();
1621 PrefService
* prefs
= g_browser_process
->local_state();
1622 DictionaryPrefUpdate
prefs_display_name_update(prefs
, kUserDisplayName
);
1623 prefs_display_name_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
1625 DictionaryPrefUpdate
prefs_given_name_update(prefs
, kUserGivenName
);
1626 prefs_given_name_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
1628 DictionaryPrefUpdate
prefs_display_email_update(prefs
, kUserDisplayEmail
);
1629 prefs_display_email_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
1631 DictionaryPrefUpdate
prefs_oauth_update(prefs
, kUserOAuthTokenStatus
);
1632 prefs_oauth_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
1634 DictionaryPrefUpdate
prefs_force_online_update(prefs
, kUserForceOnlineSignin
);
1635 prefs_force_online_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
1637 supervised_user_manager_
->RemoveNonCryptohomeData(user_id
);
1639 multi_profile_user_controller_
->RemoveCachedValues(user_id
);
1642 User
* UserManagerImpl::RemoveRegularOrLocallyManagedUserFromList(
1643 const std::string
& user_id
) {
1644 ListPrefUpdate
prefs_users_update(g_browser_process
->local_state(),
1646 prefs_users_update
->Clear();
1648 for (UserList::iterator it
= users_
.begin(); it
!= users_
.end(); ) {
1649 const std::string user_email
= (*it
)->email();
1650 if (user_email
== user_id
) {
1652 it
= users_
.erase(it
);
1654 if ((*it
)->GetType() == User::USER_TYPE_REGULAR
||
1655 (*it
)->GetType() == User::USER_TYPE_LOCALLY_MANAGED
) {
1656 prefs_users_update
->Append(new base::StringValue(user_email
));
1664 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
1665 PrefService
* local_state
= g_browser_process
->local_state();
1666 const std::string public_account_pending_data_removal
=
1667 local_state
->GetString(kPublicAccountPendingDataRemoval
);
1668 if (public_account_pending_data_removal
.empty() ||
1669 (IsUserLoggedIn() &&
1670 public_account_pending_data_removal
== GetActiveUser()->email())) {
1674 RemoveNonCryptohomeData(public_account_pending_data_removal
);
1675 local_state
->ClearPref(kPublicAccountPendingDataRemoval
);
1678 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
1679 const std::vector
<std::string
>& old_public_accounts
) {
1680 std::set
<std::string
> users
;
1681 for (UserList::const_iterator it
= users_
.begin(); it
!= users_
.end(); ++it
)
1682 users
.insert((*it
)->email());
1684 // If the user is logged into a public account that has been removed from the
1685 // user list, mark the account's data as pending removal after logout.
1686 if (IsLoggedInAsPublicAccount()) {
1687 const std::string active_user_id
= GetActiveUser()->email();
1688 if (users
.find(active_user_id
) == users
.end()) {
1689 g_browser_process
->local_state()->SetString(
1690 kPublicAccountPendingDataRemoval
, active_user_id
);
1691 users
.insert(active_user_id
);
1695 // Remove the data belonging to any other public accounts that are no longer
1696 // found on the user list.
1697 for (std::vector
<std::string
>::const_iterator
1698 it
= old_public_accounts
.begin();
1699 it
!= old_public_accounts
.end(); ++it
) {
1700 if (users
.find(*it
) == users
.end())
1701 RemoveNonCryptohomeData(*it
);
1705 bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
1706 const std::vector
<policy::DeviceLocalAccount
>& device_local_accounts
) {
1707 // Try to remove any public account data marked as pending removal.
1708 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
1710 // Get the current list of public accounts.
1711 std::vector
<std::string
> old_public_accounts
;
1712 for (UserList::const_iterator it
= users_
.begin(); it
!= users_
.end(); ++it
) {
1713 if ((*it
)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT
)
1714 old_public_accounts
.push_back((*it
)->email());
1717 // Get the new list of public accounts from policy.
1718 std::vector
<std::string
> new_public_accounts
;
1719 for (std::vector
<policy::DeviceLocalAccount
>::const_iterator it
=
1720 device_local_accounts
.begin();
1721 it
!= device_local_accounts
.end(); ++it
) {
1722 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
1723 // standard login framework: http://crbug.com/234694
1724 if (it
->type
== policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION
)
1725 new_public_accounts
.push_back(it
->user_id
);
1728 // If the list of public accounts has not changed, return.
1729 if (new_public_accounts
.size() == old_public_accounts
.size()) {
1730 bool changed
= false;
1731 for (size_t i
= 0; i
< new_public_accounts
.size(); ++i
) {
1732 if (new_public_accounts
[i
] != old_public_accounts
[i
]) {
1741 // Persist the new list of public accounts in a pref.
1742 ListPrefUpdate
prefs_public_accounts_update(g_browser_process
->local_state(),
1744 prefs_public_accounts_update
->Clear();
1745 for (std::vector
<std::string
>::const_iterator it
=
1746 new_public_accounts
.begin();
1747 it
!= new_public_accounts
.end(); ++it
) {
1748 prefs_public_accounts_update
->AppendString(*it
);
1751 // Remove the old public accounts from the user list.
1752 for (UserList::iterator it
= users_
.begin(); it
!= users_
.end();) {
1753 if ((*it
)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT
) {
1754 if (*it
!= GetLoggedInUser())
1756 it
= users_
.erase(it
);
1762 // Add the new public accounts to the front of the user list.
1763 for (std::vector
<std::string
>::const_reverse_iterator it
=
1764 new_public_accounts
.rbegin();
1765 it
!= new_public_accounts
.rend(); ++it
) {
1766 if (IsLoggedInAsPublicAccount() && *it
== GetActiveUser()->email())
1767 users_
.insert(users_
.begin(), GetLoggedInUser());
1769 users_
.insert(users_
.begin(), User::CreatePublicAccountUser(*it
));
1770 UpdatePublicAccountDisplayName(*it
);
1773 for (UserList::iterator ui
= users_
.begin(),
1774 ue
= users_
.begin() + new_public_accounts
.size();
1776 GetUserImageManager((*ui
)->email())->LoadUserImage();
1779 // Remove data belonging to public accounts that are no longer found on the
1781 CleanUpPublicAccountNonCryptohomeData(old_public_accounts
);
1786 void UserManagerImpl::UpdatePublicAccountDisplayName(
1787 const std::string
& user_id
) {
1788 std::string display_name
;
1790 if (device_local_account_policy_service_
) {
1791 policy::DeviceLocalAccountPolicyBroker
* broker
=
1792 device_local_account_policy_service_
->GetBrokerForUser(user_id
);
1794 display_name
= broker
->GetDisplayName();
1797 // Set or clear the display name.
1798 SaveUserDisplayName(user_id
, base::UTF8ToUTF16(display_name
));
1801 UserFlow
* UserManagerImpl::GetCurrentUserFlow() const {
1802 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1803 if (!IsUserLoggedIn())
1804 return GetDefaultUserFlow();
1805 return GetUserFlow(GetLoggedInUser()->email());
1808 UserFlow
* UserManagerImpl::GetUserFlow(const std::string
& user_id
) const {
1809 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1810 FlowMap::const_iterator it
= specific_flows_
.find(user_id
);
1811 if (it
!= specific_flows_
.end())
1813 return GetDefaultUserFlow();
1816 void UserManagerImpl::SetUserFlow(const std::string
& user_id
, UserFlow
* flow
) {
1817 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1818 ResetUserFlow(user_id
);
1819 specific_flows_
[user_id
] = flow
;
1822 void UserManagerImpl::ResetUserFlow(const std::string
& user_id
) {
1823 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1824 FlowMap::iterator it
= specific_flows_
.find(user_id
);
1825 if (it
!= specific_flows_
.end()) {
1827 specific_flows_
.erase(it
);
1831 bool UserManagerImpl::GetAppModeChromeClientOAuthInfo(
1832 std::string
* chrome_client_id
, std::string
* chrome_client_secret
) {
1833 if (!chrome::IsRunningInForcedAppMode() ||
1834 chrome_client_id_
.empty() ||
1835 chrome_client_secret_
.empty()) {
1839 *chrome_client_id
= chrome_client_id_
;
1840 *chrome_client_secret
= chrome_client_secret_
;
1844 void UserManagerImpl::SetAppModeChromeClientOAuthInfo(
1845 const std::string
& chrome_client_id
,
1846 const std::string
& chrome_client_secret
) {
1847 if (!chrome::IsRunningInForcedAppMode())
1850 chrome_client_id_
= chrome_client_id
;
1851 chrome_client_secret_
= chrome_client_secret
;
1854 bool UserManagerImpl::AreLocallyManagedUsersAllowed() const {
1855 bool locally_managed_users_allowed
= false;
1856 cros_settings_
->GetBoolean(kAccountsPrefSupervisedUsersEnabled
,
1857 &locally_managed_users_allowed
);
1858 policy::BrowserPolicyConnectorChromeOS
* connector
=
1859 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
1860 return locally_managed_users_allowed
|| !connector
->IsEnterpriseManaged();
1863 base::FilePath
UserManagerImpl::GetUserProfileDir(
1864 const std::string
& user_id
) const {
1865 // TODO(dpolukhin): Remove Chrome OS specific profile path logic from
1866 // ProfileManager and use only this function to construct profile path.
1867 // TODO(nkostylev): Cleanup profile dir related code paths crbug.com/294233
1868 base::FilePath profile_dir
;
1869 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
1870 if (command_line
.HasSwitch(::switches::kMultiProfiles
)) {
1871 const User
* user
= FindUser(user_id
);
1872 if (user
&& !user
->username_hash().empty())
1873 profile_dir
= ProfileHelper::GetUserProfileDir(user
->username_hash());
1874 } else if (command_line
.HasSwitch(chromeos::switches::kLoginProfile
)) {
1875 profile_dir
= ProfileHelper::GetProfileDirByLegacyLoginProfileSwitch();
1877 // We should never be logged in with no profile dir unless
1878 // multi-profiles are enabled.
1880 profile_dir
= base::FilePath();
1883 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
1884 profile_dir
= profile_manager
->user_data_dir().Append(profile_dir
);
1889 UserFlow
* UserManagerImpl::GetDefaultUserFlow() const {
1890 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1891 if (!default_flow_
.get())
1892 default_flow_
.reset(new DefaultUserFlow());
1893 return default_flow_
.get();
1896 void UserManagerImpl::NotifyUserListChanged() {
1897 content::NotificationService::current()->Notify(
1898 chrome::NOTIFICATION_USER_LIST_CHANGED
,
1899 content::Source
<UserManager
>(this),
1900 content::NotificationService::NoDetails());
1903 void UserManagerImpl::NotifyActiveUserChanged(const User
* active_user
) {
1904 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1905 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver
,
1906 session_state_observer_list_
,
1907 ActiveUserChanged(active_user
));
1910 void UserManagerImpl::NotifyUserAddedToSession(const User
* added_user
) {
1911 UpdateNumberOfUsers();
1912 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1913 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver
,
1914 session_state_observer_list_
,
1915 UserAddedToSession(added_user
));
1918 void UserManagerImpl::NotifyActiveUserHashChanged(const std::string
& hash
) {
1919 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1920 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver
,
1921 session_state_observer_list_
,
1922 ActiveUserHashChanged(hash
));
1925 void UserManagerImpl::NotifyPendingUserSessionsRestoreFinished() {
1926 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1927 user_sessions_restored_
= true;
1928 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver
,
1929 session_state_observer_list_
,
1930 PendingUserSessionsRestoreFinished());
1933 void UserManagerImpl::UpdateLoginState() {
1934 if (!LoginState::IsInitialized())
1935 return; // LoginState may not be intialized in tests.
1936 LoginState::LoggedInState logged_in_state
;
1937 logged_in_state
= active_user_
? LoginState::LOGGED_IN_ACTIVE
1938 : LoginState::LOGGED_IN_NONE
;
1940 LoginState::LoggedInUserType login_user_type
;
1941 if (logged_in_state
== LoginState::LOGGED_IN_NONE
)
1942 login_user_type
= LoginState::LOGGED_IN_USER_NONE
;
1943 else if (is_current_user_owner_
)
1944 login_user_type
= LoginState::LOGGED_IN_USER_OWNER
;
1945 else if (active_user_
->GetType() == User::USER_TYPE_GUEST
)
1946 login_user_type
= LoginState::LOGGED_IN_USER_GUEST
;
1947 else if (active_user_
->GetType() == User::USER_TYPE_RETAIL_MODE
)
1948 login_user_type
= LoginState::LOGGED_IN_USER_RETAIL_MODE
;
1949 else if (active_user_
->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT
)
1950 login_user_type
= LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT
;
1951 else if (active_user_
->GetType() == User::USER_TYPE_LOCALLY_MANAGED
)
1952 login_user_type
= LoginState::LOGGED_IN_USER_LOCALLY_MANAGED
;
1953 else if (active_user_
->GetType() == User::USER_TYPE_KIOSK_APP
)
1954 login_user_type
= LoginState::LOGGED_IN_USER_KIOSK_APP
;
1956 login_user_type
= LoginState::LOGGED_IN_USER_REGULAR
;
1958 LoginState::Get()->SetLoggedInState(logged_in_state
, login_user_type
);
1961 void UserManagerImpl::SetLRUUser(User
* user
) {
1962 UserList::iterator it
= std::find(lru_logged_in_users_
.begin(),
1963 lru_logged_in_users_
.end(),
1965 if (it
!= lru_logged_in_users_
.end())
1966 lru_logged_in_users_
.erase(it
);
1967 lru_logged_in_users_
.insert(lru_logged_in_users_
.begin(), user
);
1970 void UserManagerImpl::OnRestoreActiveSessions(
1971 const SessionManagerClient::ActiveSessionsMap
& sessions
,
1974 LOG(ERROR
) << "Could not get list of active user sessions after crash.";
1975 // If we could not get list of active user sessions it is safer to just
1976 // sign out so that we don't get in the inconsistent state.
1977 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
1981 // One profile has been already loaded on browser start.
1982 DCHECK(GetLoggedInUsers().size() == 1);
1983 DCHECK(GetActiveUser());
1984 std::string active_user_id
= GetActiveUser()->email();
1986 SessionManagerClient::ActiveSessionsMap::const_iterator it
;
1987 for (it
= sessions
.begin(); it
!= sessions
.end(); ++it
) {
1988 if (active_user_id
== it
->first
)
1990 pending_user_sessions_
[it
->first
] = it
->second
;
1992 RestorePendingUserSessions();
1995 void UserManagerImpl::RestorePendingUserSessions() {
1996 if (pending_user_sessions_
.empty()) {
1997 NotifyPendingUserSessionsRestoreFinished();
2001 // Get next user to restore sessions and delete it from list.
2002 SessionManagerClient::ActiveSessionsMap::const_iterator it
=
2003 pending_user_sessions_
.begin();
2004 std::string user_id
= it
->first
;
2005 std::string user_id_hash
= it
->second
;
2006 DCHECK(!user_id
.empty());
2007 DCHECK(!user_id_hash
.empty());
2008 pending_user_sessions_
.erase(user_id
);
2010 // Check that this user is not logged in yet.
2011 UserList logged_in_users
= GetLoggedInUsers();
2012 bool user_already_logged_in
= false;
2013 for (UserList::const_iterator it
= logged_in_users
.begin();
2014 it
!= logged_in_users
.end(); ++it
) {
2015 const User
* user
= (*it
);
2016 if (user
->email() == user_id
) {
2017 user_already_logged_in
= true;
2021 DCHECK(!user_already_logged_in
);
2023 if (!user_already_logged_in
) {
2024 // Will call OnProfilePrepared() once profile has been loaded.
2025 LoginUtils::Get()->PrepareProfile(
2026 UserContext(user_id
,
2027 std::string(), // password
2028 std::string(), // auth_code
2030 false, // using_oauth
2031 UserContext::AUTH_FLOW_OFFLINE
),
2032 std::string(), // display_email
2033 false, // has_cookies
2034 true, // has_active_session
2037 RestorePendingUserSessions();
2041 void UserManagerImpl::SendRegularUserLoginMetrics(const std::string
& user_id
) {
2042 // If this isn't the first time Chrome was run after the system booted,
2043 // assume that Chrome was restarted because a previous session ended.
2044 if (!CommandLine::ForCurrentProcess()->HasSwitch(
2045 switches::kFirstExecAfterBoot
)) {
2046 const std::string last_email
=
2047 g_browser_process
->local_state()->GetString(kLastLoggedInRegularUser
);
2048 const base::TimeDelta time_to_login
=
2049 base::TimeTicks::Now() - manager_creation_time_
;
2050 if (!last_email
.empty() && user_id
!= last_email
&&
2051 time_to_login
.InSeconds() <= kLogoutToLoginDelayMaxSec
) {
2052 UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay",
2053 time_to_login
.InSeconds(), 0, kLogoutToLoginDelayMaxSec
, 50);
2058 void UserManagerImpl::OnUserNotAllowed(const std::string
& user_email
) {
2059 LOG(ERROR
) << "Shutdown session because a user is not allowed to be in the "
2061 chromeos::ShowMultiprofilesSessionAbortedDialog(user_email
);
2064 void UserManagerImpl::UpdateUserAccountLocale(const std::string
& user_id
,
2065 const std::string
& locale
) {
2066 if (!locale
.empty() &&
2067 locale
!= g_browser_process
->GetApplicationLocale()) {
2068 BrowserThread::PostBlockingPoolTask(
2070 base::Bind(ResolveLocale
, locale
,
2071 base::Bind(&UserManagerImpl::DoUpdateAccountLocale
,
2072 base::Unretained(this),
2075 DoUpdateAccountLocale(user_id
, locale
);
2079 void UserManagerImpl::DoUpdateAccountLocale(
2080 const std::string
& user_id
,
2081 const std::string
& resolved_locale
) {
2082 if (User
* user
= FindUserAndModify(user_id
))
2083 user
->SetAccountLocale(resolved_locale
);
2086 void UserManagerImpl::UpdateNumberOfUsers() {
2087 size_t users
= GetLoggedInUsers().size();
2089 // Write the user number as UMA stat when a multi user session is possible.
2090 if ((users
+ GetUsersAdmittedForMultiProfile().size()) > 1)
2091 ash::MultiProfileUMA::RecordUserCount(users
);
2094 base::debug::SetCrashKeyValue(crash_keys::kNumberOfUsers
,
2095 base::StringPrintf("%" PRIuS
, GetLoggedInUsers().size()));
2098 void UserManagerImpl::DeleteUser(User
* user
) {
2099 const bool is_active_user
= (user
== active_user_
);
2102 active_user_
= NULL
;
2105 } // namespace chromeos