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_first_run_notification.h"
39 #include "chrome/browser/chromeos/login/multi_profile_user_controller.h"
40 #include "chrome/browser/chromeos/login/remove_user_delegate.h"
41 #include "chrome/browser/chromeos/login/supervised_user_manager_impl.h"
42 #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
43 #include "chrome/browser/chromeos/login/wizard_controller.h"
44 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
45 #include "chrome/browser/chromeos/policy/device_local_account.h"
46 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog.h"
47 #include "chrome/browser/chromeos/profiles/profile_helper.h"
48 #include "chrome/browser/chromeos/session_length_limiter.h"
49 #include "chrome/browser/managed_mode/chromeos/managed_user_password_service_factory.h"
50 #include "chrome/browser/managed_mode/chromeos/manager_password_service_factory.h"
51 #include "chrome/browser/net/nss_context.h"
52 #include "chrome/browser/profiles/profile.h"
53 #include "chrome/browser/profiles/profile_manager.h"
54 #include "chrome/browser/sync/profile_sync_service.h"
55 #include "chrome/browser/sync/profile_sync_service_factory.h"
56 #include "chrome/common/chrome_constants.h"
57 #include "chrome/common/chrome_switches.h"
58 #include "chrome/common/crash_keys.h"
59 #include "chrome/common/pref_names.h"
60 #include "chromeos/cert_loader.h"
61 #include "chromeos/chromeos_switches.h"
62 #include "chromeos/cryptohome/async_method_caller.h"
63 #include "chromeos/dbus/dbus_thread_manager.h"
64 #include "chromeos/login/login_state.h"
65 #include "chromeos/settings/cros_settings_names.h"
66 #include "content/public/browser/browser_thread.h"
67 #include "content/public/browser/notification_service.h"
68 #include "google_apis/gaia/gaia_auth_util.h"
69 #include "google_apis/gaia/google_service_auth_error.h"
70 #include "policy/policy_constants.h"
71 #include "ui/base/l10n/l10n_util.h"
72 #include "ui/wm/core/wm_core_switches.h"
74 using content::BrowserThread
;
79 // A vector pref of the the regular users known on this device, arranged in LRU
81 const char kRegularUsers
[] = "LoggedInUsers";
83 // A vector pref of the public accounts defined on this device.
84 const char kPublicAccounts
[] = "PublicAccounts";
86 // A string pref that gets set when a public account is removed but a user is
87 // currently logged into that account, requiring the account's data to be
88 // removed after logout.
89 const char kPublicAccountPendingDataRemoval
[] =
90 "PublicAccountPendingDataRemoval";
92 // A dictionary that maps user IDs to the displayed name.
93 const char kUserDisplayName
[] = "UserDisplayName";
95 // A dictionary that maps user IDs to the user's given name.
96 const char kUserGivenName
[] = "UserGivenName";
98 // A dictionary that maps user IDs to the displayed (non-canonical) emails.
99 const char kUserDisplayEmail
[] = "UserDisplayEmail";
101 // A dictionary that maps user IDs to OAuth token presence flag.
102 const char kUserOAuthTokenStatus
[] = "OAuthTokenStatus";
104 // A dictionary that maps user IDs to a flag indicating whether online
105 // authentication against GAIA should be enforced during the next sign-in.
106 const char kUserForceOnlineSignin
[] = "UserForceOnlineSignin";
108 // A string pref containing the ID of the last user who logged in if it was
109 // a regular user or an empty string if it was another type of user (guest,
110 // kiosk, public account, etc.).
111 const char kLastLoggedInRegularUser
[] = "LastLoggedInRegularUser";
113 // Upper bound for a histogram metric reporting the amount of time between
114 // one regular user logging out and a different regular user logging in.
115 const int kLogoutToLoginDelayMaxSec
= 1800;
117 // Callback that is called after user removal is complete.
118 void OnRemoveUserComplete(const std::string
& user_email
,
120 cryptohome::MountError return_code
) {
121 // Log the error, but there's not much we can do.
123 LOG(ERROR
) << "Removal of cryptohome for " << user_email
124 << " failed, return code: " << return_code
;
128 // Helper function that copies users from |users_list| to |users_vector| and
129 // |users_set|. Duplicates and users already present in |existing_users| are
131 void ParseUserList(const base::ListValue
& users_list
,
132 const std::set
<std::string
>& existing_users
,
133 std::vector
<std::string
>* users_vector
,
134 std::set
<std::string
>* users_set
) {
135 users_vector
->clear();
137 for (size_t i
= 0; i
< users_list
.GetSize(); ++i
) {
139 if (!users_list
.GetString(i
, &email
) || email
.empty()) {
140 LOG(ERROR
) << "Corrupt entry in user list at index " << i
<< ".";
143 if (existing_users
.find(email
) != existing_users
.end() ||
144 !users_set
->insert(email
).second
) {
145 LOG(ERROR
) << "Duplicate user: " << email
;
148 users_vector
->push_back(email
);
152 class UserHashMatcher
{
154 explicit UserHashMatcher(const std::string
& h
) : username_hash(h
) {}
155 bool operator()(const User
* user
) const {
156 return user
->username_hash() == username_hash
;
160 const std::string
& username_hash
;
163 // Runs on SequencedWorkerPool thread. Passes resolved locale to
164 // |on_resolve_callback| on UI thread.
166 const std::string
& raw_locale
,
167 base::Callback
<void(const std::string
&)> on_resolve_callback
) {
168 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI
));
169 std::string resolved_locale
;
171 l10n_util::CheckAndResolveLocale(raw_locale
, &resolved_locale
);
172 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
173 base::Bind(on_resolve_callback
, resolved_locale
));
176 // Callback to GetNSSCertDatabaseForProfile. It starts CertLoader using the
177 // provided NSS database. It must be called for primary user only.
178 void OnGetNSSCertDatabaseForUser(net::NSSCertDatabase
* database
) {
179 if (!CertLoader::IsInitialized())
182 CertLoader::Get()->StartWithNSSDB(database
);
188 void UserManager::RegisterPrefs(PrefRegistrySimple
* registry
) {
189 registry
->RegisterListPref(kRegularUsers
);
190 registry
->RegisterListPref(kPublicAccounts
);
191 registry
->RegisterStringPref(kPublicAccountPendingDataRemoval
, "");
192 registry
->RegisterStringPref(kLastLoggedInRegularUser
, "");
193 registry
->RegisterDictionaryPref(kUserDisplayName
);
194 registry
->RegisterDictionaryPref(kUserGivenName
);
195 registry
->RegisterDictionaryPref(kUserDisplayEmail
);
196 registry
->RegisterDictionaryPref(kUserOAuthTokenStatus
);
197 registry
->RegisterDictionaryPref(kUserForceOnlineSignin
);
198 SupervisedUserManager::RegisterPrefs(registry
);
199 SessionLengthLimiter::RegisterPrefs(registry
);
202 UserManagerImpl::UserManagerImpl()
203 : cros_settings_(CrosSettings::Get()),
204 device_local_account_policy_service_(NULL
),
205 user_loading_stage_(STAGE_NOT_LOADED
),
208 session_started_(false),
209 user_sessions_restored_(false),
210 is_current_user_owner_(false),
211 is_current_user_new_(false),
212 is_current_user_ephemeral_regular_user_(false),
213 ephemeral_users_enabled_(false),
214 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
215 manager_creation_time_(base::TimeTicks::Now()),
216 multi_profile_first_run_notification_(
217 new MultiProfileFirstRunNotification
) {
218 UpdateNumberOfUsers();
219 // UserManager instance should be used only on UI thread.
220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
221 registrar_
.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED
,
222 content::NotificationService::AllSources());
223 registrar_
.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED
,
224 content::NotificationService::AllSources());
226 chrome::NOTIFICATION_PROFILE_CREATED
,
227 content::NotificationService::AllSources());
228 RetrieveTrustedDevicePolicies();
229 local_accounts_subscription_
= cros_settings_
->AddSettingsObserver(
230 kAccountsPrefDeviceLocalAccounts
,
231 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies
,
232 base::Unretained(this)));
233 supervised_users_subscription_
= cros_settings_
->AddSettingsObserver(
234 kAccountsPrefSupervisedUsersEnabled
,
235 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies
,
236 base::Unretained(this)));
237 multi_profile_user_controller_
.reset(new MultiProfileUserController(
238 this, g_browser_process
->local_state()));
240 policy::BrowserPolicyConnectorChromeOS
* connector
=
241 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
242 avatar_policy_observer_
.reset(new policy::CloudExternalDataPolicyObserver(
245 connector
->GetDeviceLocalAccountPolicyService(),
246 policy::key::kUserAvatarImage
,
248 avatar_policy_observer_
->Init();
250 wallpaper_policy_observer_
.reset(new policy::CloudExternalDataPolicyObserver(
253 connector
->GetDeviceLocalAccountPolicyService(),
254 policy::key::kWallpaperImage
,
256 wallpaper_policy_observer_
->Init();
261 UserManagerImpl::~UserManagerImpl() {
262 // Can't use STLDeleteElements because of the private destructor of User.
263 for (UserList::iterator it
= users_
.begin(); it
!= users_
.end();
264 it
= users_
.erase(it
)) {
267 // These are pointers to the same User instances that were in users_ list.
268 logged_in_users_
.clear();
269 lru_logged_in_users_
.clear();
271 DeleteUser(active_user_
);
274 void UserManagerImpl::Shutdown() {
275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
276 local_accounts_subscription_
.reset();
277 supervised_users_subscription_
.reset();
278 // Stop the session length limiter.
279 session_length_limiter_
.reset();
281 if (device_local_account_policy_service_
)
282 device_local_account_policy_service_
->RemoveObserver(this);
284 for (UserImageManagerMap::iterator it
= user_image_managers_
.begin(),
285 ie
= user_image_managers_
.end();
287 it
->second
->Shutdown();
289 multi_profile_user_controller_
.reset();
290 avatar_policy_observer_
.reset();
291 wallpaper_policy_observer_
.reset();
294 MultiProfileUserController
* UserManagerImpl::GetMultiProfileUserController() {
295 return multi_profile_user_controller_
.get();
298 UserImageManager
* UserManagerImpl::GetUserImageManager(
299 const std::string
& user_id
) {
300 UserImageManagerMap::iterator ui
= user_image_managers_
.find(user_id
);
301 if (ui
!= user_image_managers_
.end())
302 return ui
->second
.get();
303 linked_ptr
<UserImageManagerImpl
> mgr(new UserImageManagerImpl(user_id
, this));
304 user_image_managers_
[user_id
] = mgr
;
308 SupervisedUserManager
* UserManagerImpl::GetSupervisedUserManager() {
309 return supervised_user_manager_
.get();
312 const UserList
& UserManagerImpl::GetUsers() const {
313 const_cast<UserManagerImpl
*>(this)->EnsureUsersLoaded();
317 UserList
UserManagerImpl::GetUsersAdmittedForMultiProfile() const {
318 if (!UserManager::IsMultipleProfilesAllowed())
321 // Supervised users are not allowed to use multi profile.
322 if (logged_in_users_
.size() == 1 &&
323 GetPrimaryUser()->GetType() != User::USER_TYPE_REGULAR
)
327 int num_users_allowed
= 0;
328 const UserList
& users
= GetUsers();
329 for (UserList::const_iterator it
= users
.begin(); it
!= users
.end(); ++it
) {
330 if ((*it
)->GetType() == User::USER_TYPE_REGULAR
&& !(*it
)->is_logged_in()) {
331 MultiProfileUserController::UserAllowedInSessionResult check
=
332 multi_profile_user_controller_
->
333 IsUserAllowedInSession((*it
)->email());
334 if (check
== MultiProfileUserController::
335 NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS
) {
339 // Users with a policy that prevents them being added to a session will be
340 // shown in login UI but will be grayed out.
341 if (check
== MultiProfileUserController::ALLOWED
||
342 check
== MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS
) {
343 result
.push_back(*it
);
344 if (check
== MultiProfileUserController::ALLOWED
)
350 // We only show multi-profiles sign in UI if there's at least one user that
351 // is allowed to be added to the session.
352 if (!num_users_allowed
)
358 const UserList
& UserManagerImpl::GetLoggedInUsers() const {
359 return logged_in_users_
;
362 const UserList
& UserManagerImpl::GetLRULoggedInUsers() {
363 // If there is no user logged in, we return the active user as the only one.
364 if (lru_logged_in_users_
.empty() && active_user_
) {
365 temp_single_logged_in_users_
.clear();
366 temp_single_logged_in_users_
.insert(temp_single_logged_in_users_
.begin(),
368 return temp_single_logged_in_users_
;
370 return lru_logged_in_users_
;
373 UserList
UserManagerImpl::GetUnlockUsers() const {
374 const UserList
& logged_in_users
= GetLoggedInUsers();
375 if (logged_in_users
.empty())
378 UserList unlock_users
;
379 Profile
* profile
= GetProfileByUser(primary_user_
);
380 std::string primary_behavior
=
381 profile
->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior
);
383 // Specific case: only one logged in user or
384 // primary user has primary-only multi-profile policy.
385 if (logged_in_users
.size() == 1 ||
386 primary_behavior
== MultiProfileUserController::kBehaviorPrimaryOnly
) {
387 if (primary_user_
->can_lock())
388 unlock_users
.push_back(primary_user_
);
390 // Fill list of potential unlock users based on multi-profile policy state.
391 for (UserList::const_iterator it
= logged_in_users
.begin();
392 it
!= logged_in_users
.end(); ++it
) {
394 Profile
* profile
= GetProfileByUser(user
);
395 const std::string behavior
=
396 profile
->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior
);
397 if (behavior
== MultiProfileUserController::kBehaviorUnrestricted
&&
399 unlock_users
.push_back(user
);
400 } else if (behavior
== MultiProfileUserController::kBehaviorPrimaryOnly
) {
402 << "Spotted primary-only multi-profile policy for non-primary user";
410 const std::string
& UserManagerImpl::GetOwnerEmail() {
414 void UserManagerImpl::UserLoggedIn(const std::string
& user_id
,
415 const std::string
& username_hash
,
416 bool browser_restart
) {
417 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
419 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles
))
420 DCHECK(!IsUserLoggedIn());
422 User
* user
= FindUserInListAndModify(user_id
);
423 if (active_user_
&& user
) {
424 user
->set_is_logged_in(true);
425 user
->set_username_hash(username_hash
);
426 logged_in_users_
.push_back(user
);
427 lru_logged_in_users_
.push_back(user
);
428 // Reset the new user flag if the user already exists.
429 is_current_user_new_
= false;
430 // Set active user wallpaper back.
431 WallpaperManager::Get()->SetUserWallpaperNow(active_user_
->email());
432 NotifyUserAddedToSession(user
);
436 policy::DeviceLocalAccount::Type device_local_account_type
;
437 if (user_id
== UserManager::kGuestUserName
) {
439 } else if (user_id
== UserManager::kRetailModeUserName
) {
440 RetailModeUserLoggedIn();
441 } else if (policy::IsDeviceLocalAccountUser(user_id
,
442 &device_local_account_type
) &&
443 device_local_account_type
==
444 policy::DeviceLocalAccount::TYPE_KIOSK_APP
) {
445 KioskAppLoggedIn(user_id
);
446 } else if (DemoAppLauncher::IsDemoAppSession(user_id
)) {
447 DemoAccountLoggedIn();
451 if (user
&& user
->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT
) {
452 PublicAccountUserLoggedIn(user
);
453 } else if ((user
&& user
->GetType() == User::USER_TYPE_LOCALLY_MANAGED
) ||
454 (!user
&& gaia::ExtractDomainName(user_id
) ==
455 UserManager::kLocallyManagedUserDomain
)) {
456 LocallyManagedUserLoggedIn(user_id
);
457 } else if (browser_restart
&& user_id
== g_browser_process
->local_state()->
458 GetString(kPublicAccountPendingDataRemoval
)) {
459 PublicAccountUserLoggedIn(User::CreatePublicAccountUser(user_id
));
460 } else if (user_id
!= owner_email_
&& !user
&&
461 (AreEphemeralUsersEnabled() || browser_restart
)) {
462 RegularUserLoggedInAsEphemeral(user_id
);
464 RegularUserLoggedIn(user_id
);
467 // Initialize the session length limiter and start it only if
468 // session limit is defined by the policy.
469 session_length_limiter_
.reset(new SessionLengthLimiter(NULL
,
472 DCHECK(active_user_
);
473 active_user_
->set_is_logged_in(true);
474 active_user_
->set_is_active(true);
475 active_user_
->set_username_hash(username_hash
);
477 // Place user who just signed in to the top of the logged in users.
478 logged_in_users_
.insert(logged_in_users_
.begin(), active_user_
);
479 SetLRUUser(active_user_
);
481 if (!primary_user_
) {
482 primary_user_
= active_user_
;
483 if (primary_user_
->GetType() == User::USER_TYPE_REGULAR
)
484 SendRegularUserLoginMetrics(user_id
);
487 UMA_HISTOGRAM_ENUMERATION("UserManager.LoginUserType",
488 active_user_
->GetType(), User::NUM_USER_TYPES
);
490 g_browser_process
->local_state()->SetString(kLastLoggedInRegularUser
,
491 (active_user_
->GetType() == User::USER_TYPE_REGULAR
) ? user_id
: "");
496 void UserManagerImpl::SwitchActiveUser(const std::string
& user_id
) {
497 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles
))
500 User
* user
= FindUserAndModify(user_id
);
502 NOTREACHED() << "Switching to a non-existing user";
505 if (user
== active_user_
) {
506 NOTREACHED() << "Switching to a user who is already active";
509 if (!user
->is_logged_in()) {
510 NOTREACHED() << "Switching to a user that is not logged in";
513 if (user
->GetType() != User::USER_TYPE_REGULAR
) {
514 NOTREACHED() << "Switching to a non-regular user";
517 if (user
->username_hash().empty()) {
518 NOTREACHED() << "Switching to a user that doesn't have username_hash set";
522 DCHECK(active_user_
);
523 active_user_
->set_is_active(false);
524 user
->set_is_active(true);
527 // Move the user to the front.
528 SetLRUUser(active_user_
);
530 NotifyActiveUserHashChanged(active_user_
->username_hash());
531 NotifyActiveUserChanged(active_user_
);
534 void UserManagerImpl::RestoreActiveSessions() {
535 DBusThreadManager::Get()->GetSessionManagerClient()->RetrieveActiveSessions(
536 base::Bind(&UserManagerImpl::OnRestoreActiveSessions
,
537 base::Unretained(this)));
540 void UserManagerImpl::SessionStarted() {
541 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
542 session_started_
= true;
544 content::NotificationService::current()->Notify(
545 chrome::NOTIFICATION_SESSION_STARTED
,
546 content::Source
<UserManager
>(this),
547 content::Details
<const User
>(active_user_
));
548 if (is_current_user_new_
) {
549 // Make sure that the new user's data is persisted to Local State.
550 g_browser_process
->local_state()->CommitPendingWrite();
554 void UserManagerImpl::RemoveUser(const std::string
& user_id
,
555 RemoveUserDelegate
* delegate
) {
556 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
558 const User
* user
= FindUser(user_id
);
559 if (!user
|| (user
->GetType() != User::USER_TYPE_REGULAR
&&
560 user
->GetType() != User::USER_TYPE_LOCALLY_MANAGED
))
563 // Sanity check: we must not remove single user unless it's an enterprise
564 // device. This check may seem redundant at a first sight because
565 // this single user must be an owner and we perform special check later
566 // in order not to remove an owner. However due to non-instant nature of
567 // ownership assignment this later check may sometimes fail.
568 // See http://crosbug.com/12723
569 policy::BrowserPolicyConnectorChromeOS
* connector
=
570 g_browser_process
->platform_part()
571 ->browser_policy_connector_chromeos();
572 if (users_
.size() < 2 && !connector
->IsEnterpriseManaged())
575 // Sanity check: do not allow any of the the logged in users to be removed.
576 for (UserList::const_iterator it
= logged_in_users_
.begin();
577 it
!= logged_in_users_
.end(); ++it
) {
578 if ((*it
)->email() == user_id
)
582 RemoveUserInternal(user_id
, delegate
);
585 void UserManagerImpl::RemoveUserInternal(const std::string
& user_email
,
586 RemoveUserDelegate
* delegate
) {
587 CrosSettings
* cros_settings
= CrosSettings::Get();
589 // Ensure the value of owner email has been fetched.
590 if (CrosSettingsProvider::TRUSTED
!= cros_settings
->PrepareTrustedValues(
591 base::Bind(&UserManagerImpl::RemoveUserInternal
,
592 base::Unretained(this),
593 user_email
, delegate
))) {
594 // Value of owner email is not fetched yet. RemoveUserInternal will be
595 // called again after fetch completion.
599 cros_settings
->GetString(kDeviceOwner
, &owner
);
600 if (user_email
== owner
) {
601 // Owner is not allowed to be removed from the device.
604 RemoveNonOwnerUserInternal(user_email
, delegate
);
607 void UserManagerImpl::RemoveNonOwnerUserInternal(const std::string
& user_email
,
608 RemoveUserDelegate
* delegate
) {
610 delegate
->OnBeforeUserRemoved(user_email
);
611 RemoveUserFromList(user_email
);
612 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
613 user_email
, base::Bind(&OnRemoveUserComplete
, user_email
));
616 delegate
->OnUserRemoved(user_email
);
619 void UserManagerImpl::RemoveUserFromList(const std::string
& user_id
) {
620 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
621 RemoveNonCryptohomeData(user_id
);
622 if (user_loading_stage_
== STAGE_LOADED
) {
623 DeleteUser(RemoveRegularOrLocallyManagedUserFromList(user_id
));
624 } else if (user_loading_stage_
== STAGE_LOADING
) {
625 DCHECK(gaia::ExtractDomainName(user_id
) ==
626 UserManager::kLocallyManagedUserDomain
);
627 // Special case, removing partially-constructed supervised user during user
629 ListPrefUpdate
users_update(g_browser_process
->local_state(),
631 users_update
->Remove(base::StringValue(user_id
), NULL
);
633 NOTREACHED() << "Users are not loaded yet.";
636 // Make sure that new data is persisted to Local State.
637 g_browser_process
->local_state()->CommitPendingWrite();
640 bool UserManagerImpl::IsKnownUser(const std::string
& user_id
) const {
641 return FindUser(user_id
) != NULL
;
644 const User
* UserManagerImpl::FindUser(const std::string
& user_id
) const {
645 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
646 if (active_user_
&& active_user_
->email() == user_id
)
648 return FindUserInList(user_id
);
651 User
* UserManagerImpl::FindUserAndModify(const std::string
& user_id
) {
652 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
653 if (active_user_
&& active_user_
->email() == user_id
)
655 return FindUserInListAndModify(user_id
);
658 const User
* UserManagerImpl::GetLoggedInUser() const {
659 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
663 User
* UserManagerImpl::GetLoggedInUser() {
664 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
668 const User
* UserManagerImpl::GetActiveUser() const {
669 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
673 User
* UserManagerImpl::GetActiveUser() {
674 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
678 const User
* UserManagerImpl::GetPrimaryUser() const {
679 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
680 return primary_user_
;
683 User
* UserManagerImpl::GetUserByProfile(Profile
* profile
) const {
684 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
685 if (ProfileHelper::IsSigninProfile(profile
))
688 if (IsMultipleProfilesAllowed()) {
689 const std::string username_hash
=
690 ProfileHelper::GetUserIdHashFromProfile(profile
);
691 const UserList
& users
= GetUsers();
692 const UserList::const_iterator pos
= std::find_if(
693 users
.begin(), users
.end(), UserHashMatcher(username_hash
));
694 if (pos
!= users
.end())
697 // Many tests do not have their users registered with UserManager and
698 // runs here. If |active_user_| matches |profile|, returns it.
699 return active_user_
&&
700 ProfileHelper::GetProfilePathByUserIdHash(
701 active_user_
->username_hash()) == profile
->GetPath()
708 Profile
* UserManagerImpl::GetProfileByUser(const User
* user
) const {
709 Profile
* profile
= NULL
;
710 if (IsMultipleProfilesAllowed() && user
->is_profile_created())
711 profile
= ProfileHelper::GetProfileByUserIdHash(user
->username_hash());
713 profile
= ProfileManager::GetActiveUserProfile();
715 // GetActiveUserProfile() or GetProfileByUserIdHash() returns a new instance
716 // of ProfileImpl(), but actually its OffTheRecordProfile() should be used.
717 if (profile
&& IsLoggedInAsGuest())
718 profile
= profile
->GetOffTheRecordProfile();
722 void UserManagerImpl::SaveUserOAuthStatus(
723 const std::string
& user_id
,
724 User::OAuthTokenStatus oauth_token_status
) {
725 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
727 DVLOG(1) << "Saving user OAuth token status in Local State";
728 User
* user
= FindUserAndModify(user_id
);
730 user
->set_oauth_token_status(oauth_token_status
);
732 GetUserFlow(user_id
)->HandleOAuthTokenStatusChange(oauth_token_status
);
734 // Do not update local state if data stored or cached outside the user's
735 // cryptohome is to be treated as ephemeral.
736 if (IsUserNonCryptohomeDataEphemeral(user_id
))
739 PrefService
* local_state
= g_browser_process
->local_state();
741 DictionaryPrefUpdate
oauth_status_update(local_state
, kUserOAuthTokenStatus
);
742 oauth_status_update
->SetWithoutPathExpansion(user_id
,
743 new base::FundamentalValue(static_cast<int>(oauth_token_status
)));
746 void UserManagerImpl::SaveForceOnlineSignin(const std::string
& user_id
,
747 bool force_online_signin
) {
748 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
750 // Do not update local state if data stored or cached outside the user's
751 // cryptohome is to be treated as ephemeral.
752 if (IsUserNonCryptohomeDataEphemeral(user_id
))
755 DictionaryPrefUpdate
force_online_update(g_browser_process
->local_state(),
756 kUserForceOnlineSignin
);
757 force_online_update
->SetBooleanWithoutPathExpansion(user_id
,
758 force_online_signin
);
761 void UserManagerImpl::SaveUserDisplayName(const std::string
& user_id
,
762 const base::string16
& display_name
) {
763 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
765 if (User
* user
= FindUserAndModify(user_id
)) {
766 user
->set_display_name(display_name
);
768 // Do not update local state if data stored or cached outside the user's
769 // cryptohome is to be treated as ephemeral.
770 if (!IsUserNonCryptohomeDataEphemeral(user_id
)) {
771 PrefService
* local_state
= g_browser_process
->local_state();
773 DictionaryPrefUpdate
display_name_update(local_state
, kUserDisplayName
);
774 display_name_update
->SetWithoutPathExpansion(
776 new base::StringValue(display_name
));
778 supervised_user_manager_
->UpdateManagerName(user_id
, display_name
);
783 base::string16
UserManagerImpl::GetUserDisplayName(
784 const std::string
& user_id
) const {
785 const User
* user
= FindUser(user_id
);
786 return user
? user
->display_name() : base::string16();
789 void UserManagerImpl::SaveUserDisplayEmail(const std::string
& user_id
,
790 const std::string
& display_email
) {
791 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
793 User
* user
= FindUserAndModify(user_id
);
795 return; // Ignore if there is no such user.
797 user
->set_display_email(display_email
);
799 // Do not update local state if data stored or cached outside the user's
800 // cryptohome is to be treated as ephemeral.
801 if (IsUserNonCryptohomeDataEphemeral(user_id
))
804 PrefService
* local_state
= g_browser_process
->local_state();
806 DictionaryPrefUpdate
display_email_update(local_state
, kUserDisplayEmail
);
807 display_email_update
->SetWithoutPathExpansion(
809 new base::StringValue(display_email
));
812 std::string
UserManagerImpl::GetUserDisplayEmail(
813 const std::string
& user_id
) const {
814 const User
* user
= FindUser(user_id
);
815 return user
? user
->display_email() : user_id
;
818 void UserManagerImpl::UpdateUserAccountData(
819 const std::string
& user_id
,
820 const UserAccountData
& account_data
) {
821 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
823 SaveUserDisplayName(user_id
, account_data
.display_name());
825 if (User
* user
= FindUserAndModify(user_id
)) {
826 base::string16 given_name
= account_data
.given_name();
827 user
->set_given_name(given_name
);
828 if (!IsUserNonCryptohomeDataEphemeral(user_id
)) {
829 PrefService
* local_state
= g_browser_process
->local_state();
831 DictionaryPrefUpdate
given_name_update(local_state
, kUserGivenName
);
832 given_name_update
->SetWithoutPathExpansion(
834 new base::StringValue(given_name
));
838 UpdateUserAccountLocale(user_id
, account_data
.locale());
841 // TODO(alemate): http://crbug.com/288941 : Respect preferred language list in
842 // the Google user profile.
844 // Returns true if callback will be called.
845 bool UserManagerImpl::RespectLocalePreference(
848 scoped_ptr
<locale_util::SwitchLanguageCallback
> callback
) const {
849 if (g_browser_process
== NULL
)
851 if ((user
== NULL
) || (user
!= GetPrimaryUser()) ||
852 (!user
->is_profile_created()))
855 // In case of Multi Profile mode we don't apply profile locale because it is
857 if (GetLoggedInUsers().size() != 1)
859 const PrefService
* prefs
= profile
->GetPrefs();
863 std::string pref_locale
;
864 const std::string pref_app_locale
=
865 prefs
->GetString(prefs::kApplicationLocale
);
866 const std::string pref_bkup_locale
=
867 prefs
->GetString(prefs::kApplicationLocaleBackup
);
869 pref_locale
= pref_app_locale
;
870 if (pref_locale
.empty())
871 pref_locale
= pref_bkup_locale
;
873 const std::string
* account_locale
= NULL
;
874 if (pref_locale
.empty() && user
->has_gaia_account()) {
875 if (user
->GetAccountLocale() == NULL
)
876 return false; // wait until Account profile is loaded.
877 account_locale
= user
->GetAccountLocale();
878 pref_locale
= *account_locale
;
880 const std::string global_app_locale
=
881 g_browser_process
->GetApplicationLocale();
882 if (pref_locale
.empty())
883 pref_locale
= global_app_locale
;
884 DCHECK(!pref_locale
.empty());
885 LOG(WARNING
) << "RespectLocalePreference: "
886 << "app_locale='" << pref_app_locale
<< "', "
887 << "bkup_locale='" << pref_bkup_locale
<< "', "
888 << (account_locale
!= NULL
889 ? (std::string("account_locale='") + (*account_locale
) +
891 : (std::string("account_locale - unused. ")))
892 << " Selected '" << pref_locale
<< "'";
893 profile
->ChangeAppLocale(pref_locale
, Profile::APP_LOCALE_CHANGED_VIA_LOGIN
);
895 // Here we don't enable keyboard layouts for normal users. Input methods
896 // are set up when the user first logs in. Then the user may customize the
897 // input methods. Hence changing input methods here, just because the user's
898 // UI language is different from the login screen UI language, is not
899 // desirable. Note that input method preferences are synced, so users can use
900 // their farovite input methods as soon as the preferences are synced.
902 // For Guest mode, user locale preferences will never get initialized.
903 // So input methods should be enabled somewhere.
904 const bool enable_layouts
= UserManager::Get()->IsLoggedInAsGuest();
905 locale_util::SwitchLanguage(pref_locale
,
907 false /* login_layouts_only */,
913 void UserManagerImpl::StopPolicyObserverForTesting() {
914 avatar_policy_observer_
.reset();
915 wallpaper_policy_observer_
.reset();
918 void UserManagerImpl::Observe(int type
,
919 const content::NotificationSource
& source
,
920 const content::NotificationDetails
& details
) {
922 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED
:
923 if (!device_local_account_policy_service_
) {
924 policy::BrowserPolicyConnectorChromeOS
* connector
=
925 g_browser_process
->platform_part()
926 ->browser_policy_connector_chromeos();
927 device_local_account_policy_service_
=
928 connector
->GetDeviceLocalAccountPolicyService();
929 if (device_local_account_policy_service_
)
930 device_local_account_policy_service_
->AddObserver(this);
932 RetrieveTrustedDevicePolicies();
935 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED
: {
936 Profile
* profile
= content::Details
<Profile
>(details
).ptr();
937 if (IsUserLoggedIn() &&
938 !IsLoggedInAsGuest() &&
939 !IsLoggedInAsKioskApp()) {
940 if (IsLoggedInAsLocallyManagedUser())
941 ManagedUserPasswordServiceFactory::GetForProfile(profile
);
942 if (IsLoggedInAsRegularUser())
943 ManagerPasswordServiceFactory::GetForProfile(profile
);
945 if (!profile
->IsOffTheRecord()) {
946 AuthSyncObserver
* sync_observer
=
947 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile
);
948 sync_observer
->StartObserving();
949 multi_profile_user_controller_
->StartObserving(profile
);
950 multi_profile_first_run_notification_
->UserProfilePrepared(profile
);
954 // Now that the user profile has been initialized and
955 // |GetNSSCertDatabaseForProfile| is safe to be used, get the NSS cert
956 // database for the primary user and start certificate loader with it.
957 if (IsUserLoggedIn() &&
959 profile
== GetProfileByUser(GetPrimaryUser()) &&
960 CertLoader::IsInitialized() &&
961 base::SysInfo::IsRunningOnChromeOS()) {
962 GetNSSCertDatabaseForProfile(profile
,
963 base::Bind(&OnGetNSSCertDatabaseForUser
));
967 case chrome::NOTIFICATION_PROFILE_CREATED
: {
968 Profile
* profile
= content::Source
<Profile
>(source
).ptr();
969 User
* user
= GetUserByProfile(profile
);
971 user
->set_profile_is_created();
980 void UserManagerImpl::OnExternalDataSet(const std::string
& policy
,
981 const std::string
& user_id
) {
982 if (policy
== policy::key::kUserAvatarImage
)
983 GetUserImageManager(user_id
)->OnExternalDataSet(policy
);
984 else if (policy
== policy::key::kWallpaperImage
)
985 WallpaperManager::Get()->OnPolicySet(policy
, user_id
);
990 void UserManagerImpl::OnExternalDataCleared(const std::string
& policy
,
991 const std::string
& user_id
) {
992 if (policy
== policy::key::kUserAvatarImage
)
993 GetUserImageManager(user_id
)->OnExternalDataCleared(policy
);
994 else if (policy
== policy::key::kWallpaperImage
)
995 WallpaperManager::Get()->OnPolicyCleared(policy
, user_id
);
1000 void UserManagerImpl::OnExternalDataFetched(const std::string
& policy
,
1001 const std::string
& user_id
,
1002 scoped_ptr
<std::string
> data
) {
1003 if (policy
== policy::key::kUserAvatarImage
)
1004 GetUserImageManager(user_id
)->OnExternalDataFetched(policy
, data
.Pass());
1005 else if (policy
== policy::key::kWallpaperImage
)
1006 WallpaperManager::Get()->OnPolicyFetched(policy
, user_id
, data
.Pass());
1011 void UserManagerImpl::OnPolicyUpdated(const std::string
& user_id
) {
1012 UpdatePublicAccountDisplayName(user_id
);
1013 NotifyUserListChanged();
1016 void UserManagerImpl::OnDeviceLocalAccountsChanged() {
1017 // No action needed here, changes to the list of device-local accounts get
1018 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
1021 bool UserManagerImpl::IsCurrentUserOwner() const {
1022 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1023 base::AutoLock
lk(is_current_user_owner_lock_
);
1024 return is_current_user_owner_
;
1027 void UserManagerImpl::SetCurrentUserIsOwner(bool is_current_user_owner
) {
1028 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1030 base::AutoLock
lk(is_current_user_owner_lock_
);
1031 is_current_user_owner_
= is_current_user_owner
;
1036 bool UserManagerImpl::IsCurrentUserNew() const {
1037 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1038 return is_current_user_new_
;
1041 bool UserManagerImpl::IsCurrentUserNonCryptohomeDataEphemeral() const {
1042 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1043 return IsUserLoggedIn() &&
1044 IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email());
1047 bool UserManagerImpl::CanCurrentUserLock() const {
1048 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1049 return IsUserLoggedIn() && active_user_
->can_lock() &&
1050 GetCurrentUserFlow()->CanLockScreen();
1053 bool UserManagerImpl::IsUserLoggedIn() const {
1054 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1055 return active_user_
;
1058 bool UserManagerImpl::IsLoggedInAsRegularUser() const {
1059 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1060 return IsUserLoggedIn() &&
1061 active_user_
->GetType() == User::USER_TYPE_REGULAR
;
1064 bool UserManagerImpl::IsLoggedInAsDemoUser() const {
1065 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1066 return IsUserLoggedIn() &&
1067 active_user_
->GetType() == User::USER_TYPE_RETAIL_MODE
;
1070 bool UserManagerImpl::IsLoggedInAsPublicAccount() const {
1071 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1072 return IsUserLoggedIn() &&
1073 active_user_
->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT
;
1076 bool UserManagerImpl::IsLoggedInAsGuest() const {
1077 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1078 return IsUserLoggedIn() &&
1079 active_user_
->GetType() == User::USER_TYPE_GUEST
;
1082 bool UserManagerImpl::IsLoggedInAsLocallyManagedUser() const {
1083 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1084 return IsUserLoggedIn() &&
1085 active_user_
->GetType() == User::USER_TYPE_LOCALLY_MANAGED
;
1088 bool UserManagerImpl::IsLoggedInAsKioskApp() const {
1089 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1090 return IsUserLoggedIn() &&
1091 active_user_
->GetType() == User::USER_TYPE_KIOSK_APP
;
1094 bool UserManagerImpl::IsLoggedInAsStub() const {
1095 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1096 return IsUserLoggedIn() && active_user_
->email() == kStubUser
;
1099 bool UserManagerImpl::IsSessionStarted() const {
1100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1101 return session_started_
;
1104 bool UserManagerImpl::UserSessionsRestored() const {
1105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1106 return user_sessions_restored_
;
1109 bool UserManagerImpl::HasBrowserRestarted() const {
1110 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
1111 return base::SysInfo::IsRunningOnChromeOS() &&
1112 command_line
->HasSwitch(switches::kLoginUser
) &&
1113 !command_line
->HasSwitch(switches::kLoginPassword
);
1116 bool UserManagerImpl::IsUserNonCryptohomeDataEphemeral(
1117 const std::string
& user_id
) const {
1118 // Data belonging to the guest, retail mode and stub users is always
1120 if (user_id
== UserManager::kGuestUserName
||
1121 user_id
== UserManager::kRetailModeUserName
||
1122 user_id
== kStubUser
) {
1126 // Data belonging to the owner, anyone found on the user list and obsolete
1127 // public accounts whose data has not been removed yet is not ephemeral.
1128 if (user_id
== owner_email_
|| UserExistsInList(user_id
) ||
1129 user_id
== g_browser_process
->local_state()->
1130 GetString(kPublicAccountPendingDataRemoval
)) {
1134 // Data belonging to the currently logged-in user is ephemeral when:
1135 // a) The user logged into a regular account while the ephemeral users policy
1138 // b) The user logged into any other account type.
1139 if (IsUserLoggedIn() && (user_id
== GetLoggedInUser()->email()) &&
1140 (is_current_user_ephemeral_regular_user_
|| !IsLoggedInAsRegularUser())) {
1144 // Data belonging to any other user is ephemeral when:
1145 // a) Going through the regular login flow and the ephemeral users policy is
1148 // b) The browser is restarting after a crash.
1149 return AreEphemeralUsersEnabled() || HasBrowserRestarted();
1152 void UserManagerImpl::AddObserver(UserManager::Observer
* obs
) {
1153 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1154 observer_list_
.AddObserver(obs
);
1157 void UserManagerImpl::RemoveObserver(UserManager::Observer
* obs
) {
1158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1159 observer_list_
.RemoveObserver(obs
);
1162 void UserManagerImpl::AddSessionStateObserver(
1163 UserManager::UserSessionStateObserver
* obs
) {
1164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1165 session_state_observer_list_
.AddObserver(obs
);
1168 void UserManagerImpl::RemoveSessionStateObserver(
1169 UserManager::UserSessionStateObserver
* obs
) {
1170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1171 session_state_observer_list_
.RemoveObserver(obs
);
1174 void UserManagerImpl::NotifyLocalStateChanged() {
1175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1176 FOR_EACH_OBSERVER(UserManager::Observer
, observer_list_
,
1177 LocalStateChanged(this));
1180 void UserManagerImpl::OnProfilePrepared(Profile
* profile
) {
1181 LoginUtils::Get()->DoBrowserLaunch(profile
,
1182 NULL
); // host_, not needed here
1184 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName
)) {
1185 // Did not log in (we crashed or are debugging), need to restore Sync.
1186 // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
1187 // users once it is fully multi-profile aware. http://crbug.com/238987
1188 // For now if we have other user pending sessions they'll override OAuth
1189 // session restore for previous users.
1190 LoginUtils::Get()->RestoreAuthenticationSession(profile
);
1193 // Restore other user sessions if any.
1194 RestorePendingUserSessions();
1197 void UserManagerImpl::EnsureUsersLoaded() {
1198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1199 if (!g_browser_process
|| !g_browser_process
->local_state())
1202 if (user_loading_stage_
!= STAGE_NOT_LOADED
)
1204 user_loading_stage_
= STAGE_LOADING
;
1205 // Clean up user list first. All code down the path should be synchronous,
1206 // so that local state after transaction rollback is in consistent state.
1207 // This process also should not trigger EnsureUsersLoaded again.
1208 if (supervised_user_manager_
->HasFailedUserCreationTransaction())
1209 supervised_user_manager_
->RollbackUserCreationTransaction();
1211 PrefService
* local_state
= g_browser_process
->local_state();
1212 const base::ListValue
* prefs_regular_users
=
1213 local_state
->GetList(kRegularUsers
);
1214 const base::ListValue
* prefs_public_sessions
=
1215 local_state
->GetList(kPublicAccounts
);
1216 const base::DictionaryValue
* prefs_display_names
=
1217 local_state
->GetDictionary(kUserDisplayName
);
1218 const base::DictionaryValue
* prefs_given_names
=
1219 local_state
->GetDictionary(kUserGivenName
);
1220 const base::DictionaryValue
* prefs_display_emails
=
1221 local_state
->GetDictionary(kUserDisplayEmail
);
1223 // Load public sessions first.
1224 std::vector
<std::string
> public_sessions
;
1225 std::set
<std::string
> public_sessions_set
;
1226 ParseUserList(*prefs_public_sessions
, std::set
<std::string
>(),
1227 &public_sessions
, &public_sessions_set
);
1228 for (std::vector
<std::string
>::const_iterator it
= public_sessions
.begin();
1229 it
!= public_sessions
.end(); ++it
) {
1230 users_
.push_back(User::CreatePublicAccountUser(*it
));
1231 UpdatePublicAccountDisplayName(*it
);
1234 // Load regular users and locally managed users.
1235 std::vector
<std::string
> regular_users
;
1236 std::set
<std::string
> regular_users_set
;
1237 ParseUserList(*prefs_regular_users
, public_sessions_set
,
1238 ®ular_users
, ®ular_users_set
);
1239 for (std::vector
<std::string
>::const_iterator it
= regular_users
.begin();
1240 it
!= regular_users
.end(); ++it
) {
1242 const std::string domain
= gaia::ExtractDomainName(*it
);
1243 if (domain
== UserManager::kLocallyManagedUserDomain
)
1244 user
= User::CreateLocallyManagedUser(*it
);
1246 user
= User::CreateRegularUser(*it
);
1247 user
->set_oauth_token_status(LoadUserOAuthStatus(*it
));
1248 user
->set_force_online_signin(LoadForceOnlineSignin(*it
));
1249 users_
.push_back(user
);
1251 base::string16 display_name
;
1252 if (prefs_display_names
->GetStringWithoutPathExpansion(*it
,
1254 user
->set_display_name(display_name
);
1257 base::string16 given_name
;
1258 if (prefs_given_names
->GetStringWithoutPathExpansion(*it
, &given_name
)) {
1259 user
->set_given_name(given_name
);
1262 std::string display_email
;
1263 if (prefs_display_emails
->GetStringWithoutPathExpansion(*it
,
1265 user
->set_display_email(display_email
);
1269 user_loading_stage_
= STAGE_LOADED
;
1271 for (UserList::iterator ui
= users_
.begin(), ue
= users_
.end();
1273 GetUserImageManager((*ui
)->email())->LoadUserImage();
1277 void UserManagerImpl::RetrieveTrustedDevicePolicies() {
1278 ephemeral_users_enabled_
= false;
1281 // Schedule a callback if device policy has not yet been verified.
1282 if (CrosSettingsProvider::TRUSTED
!= cros_settings_
->PrepareTrustedValues(
1283 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies
,
1284 base::Unretained(this)))) {
1288 cros_settings_
->GetBoolean(kAccountsPrefEphemeralUsersEnabled
,
1289 &ephemeral_users_enabled_
);
1290 cros_settings_
->GetString(kDeviceOwner
, &owner_email_
);
1292 EnsureUsersLoaded();
1294 bool changed
= UpdateAndCleanUpPublicAccounts(
1295 policy::GetDeviceLocalAccounts(cros_settings_
));
1297 // If ephemeral users are enabled and we are on the login screen, take this
1298 // opportunity to clean up by removing all regular users except the owner.
1299 if (ephemeral_users_enabled_
&& !IsUserLoggedIn()) {
1300 ListPrefUpdate
prefs_users_update(g_browser_process
->local_state(),
1302 prefs_users_update
->Clear();
1303 for (UserList::iterator it
= users_
.begin(); it
!= users_
.end(); ) {
1304 const std::string user_email
= (*it
)->email();
1305 if ((*it
)->GetType() == User::USER_TYPE_REGULAR
&&
1306 user_email
!= owner_email_
) {
1307 RemoveNonCryptohomeData(user_email
);
1309 it
= users_
.erase(it
);
1312 if ((*it
)->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT
)
1313 prefs_users_update
->Append(new base::StringValue(user_email
));
1320 NotifyUserListChanged();
1323 bool UserManagerImpl::AreEphemeralUsersEnabled() const {
1324 policy::BrowserPolicyConnectorChromeOS
* connector
=
1325 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
1326 return ephemeral_users_enabled_
&&
1327 (connector
->IsEnterpriseManaged() || !owner_email_
.empty());
1330 UserList
& UserManagerImpl::GetUsersAndModify() {
1331 EnsureUsersLoaded();
1335 const User
* UserManagerImpl::FindUserInList(const std::string
& user_id
) const {
1336 const UserList
& users
= GetUsers();
1337 for (UserList::const_iterator it
= users
.begin(); it
!= users
.end(); ++it
) {
1338 if ((*it
)->email() == user_id
)
1344 const bool UserManagerImpl::UserExistsInList(const std::string
& user_id
) const {
1345 PrefService
* local_state
= g_browser_process
->local_state();
1346 const base::ListValue
* user_list
= local_state
->GetList(kRegularUsers
);
1347 for (size_t i
= 0; i
< user_list
->GetSize(); ++i
) {
1349 if (user_list
->GetString(i
, &email
) && (user_id
== email
))
1355 User
* UserManagerImpl::FindUserInListAndModify(const std::string
& user_id
) {
1356 UserList
& users
= GetUsersAndModify();
1357 for (UserList::iterator it
= users
.begin(); it
!= users
.end(); ++it
) {
1358 if ((*it
)->email() == user_id
)
1364 void UserManagerImpl::GuestUserLoggedIn() {
1365 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1366 active_user_
= User::CreateGuestUser();
1367 // TODO(nkostylev): Add support for passing guest session cryptohome
1368 // mount point. Legacy (--login-profile) value will be used for now.
1369 // http://crosbug.com/230859
1370 active_user_
->SetStubImage(User::kInvalidImageIndex
, false);
1371 // Initializes wallpaper after active_user_ is set.
1372 WallpaperManager::Get()->SetUserWallpaperNow(UserManager::kGuestUserName
);
1375 void UserManagerImpl::AddUserRecord(User
* user
) {
1376 // Add the user to the front of the user list.
1377 ListPrefUpdate
prefs_users_update(g_browser_process
->local_state(),
1379 prefs_users_update
->Insert(0, new base::StringValue(user
->email()));
1380 users_
.insert(users_
.begin(), user
);
1383 void UserManagerImpl::RegularUserLoggedIn(const std::string
& user_id
) {
1384 // Remove the user from the user list.
1385 active_user_
= RemoveRegularOrLocallyManagedUserFromList(user_id
);
1387 // If the user was not found on the user list, create a new user.
1388 is_current_user_new_
= !active_user_
;
1389 if (!active_user_
) {
1390 active_user_
= User::CreateRegularUser(user_id
);
1391 active_user_
->set_oauth_token_status(LoadUserOAuthStatus(user_id
));
1392 SaveUserDisplayName(active_user_
->email(),
1393 base::UTF8ToUTF16(active_user_
->GetAccountName(true)));
1394 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
1397 AddUserRecord(active_user_
);
1399 GetUserImageManager(user_id
)->UserLoggedIn(is_current_user_new_
, false);
1401 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1403 // Make sure that new data is persisted to Local State.
1404 g_browser_process
->local_state()->CommitPendingWrite();
1407 void UserManagerImpl::RegularUserLoggedInAsEphemeral(
1408 const std::string
& user_id
) {
1409 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1410 is_current_user_new_
= true;
1411 is_current_user_ephemeral_regular_user_
= true;
1412 active_user_
= User::CreateRegularUser(user_id
);
1413 GetUserImageManager(user_id
)->UserLoggedIn(is_current_user_new_
, false);
1414 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
1417 void UserManagerImpl::LocallyManagedUserLoggedIn(
1418 const std::string
& user_id
) {
1419 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
1421 // Remove the user from the user list.
1422 active_user_
= RemoveRegularOrLocallyManagedUserFromList(user_id
);
1423 // If the user was not found on the user list, create a new user.
1424 if (!active_user_
) {
1425 is_current_user_new_
= true;
1426 active_user_
= User::CreateLocallyManagedUser(user_id
);
1427 // Leaving OAuth token status at the default state = unknown.
1428 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
1430 if (supervised_user_manager_
->CheckForFirstRun(user_id
)) {
1431 is_current_user_new_
= true;
1432 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
1434 is_current_user_new_
= false;
1438 // Add the user to the front of the user list.
1439 ListPrefUpdate
prefs_users_update(g_browser_process
->local_state(),
1441 prefs_users_update
->Insert(0, new base::StringValue(user_id
));
1442 users_
.insert(users_
.begin(), active_user_
);
1444 // Now that user is in the list, save display name.
1445 if (is_current_user_new_
) {
1446 SaveUserDisplayName(active_user_
->email(),
1447 active_user_
->GetDisplayName());
1450 GetUserImageManager(user_id
)->UserLoggedIn(is_current_user_new_
, true);
1451 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1453 // Make sure that new data is persisted to Local State.
1454 g_browser_process
->local_state()->CommitPendingWrite();
1457 void UserManagerImpl::PublicAccountUserLoggedIn(User
* user
) {
1458 is_current_user_new_
= true;
1459 active_user_
= user
;
1460 // The UserImageManager chooses a random avatar picture when a user logs in
1461 // for the first time. Tell the UserImageManager that this user is not new to
1462 // prevent the avatar from getting changed.
1463 GetUserImageManager(user
->email())->UserLoggedIn(false, true);
1464 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1467 void UserManagerImpl::KioskAppLoggedIn(const std::string
& app_id
) {
1468 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1469 policy::DeviceLocalAccount::Type device_local_account_type
;
1470 DCHECK(policy::IsDeviceLocalAccountUser(app_id
,
1471 &device_local_account_type
));
1472 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP
,
1473 device_local_account_type
);
1475 active_user_
= User::CreateKioskAppUser(app_id
);
1476 active_user_
->SetStubImage(User::kInvalidImageIndex
, false);
1478 WallpaperManager::Get()->SetUserWallpaperNow(app_id
);
1480 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
1481 // the kiosk_app_id in these objects, removing the need to re-parse the
1482 // device-local account list here to extract the kiosk_app_id.
1483 const std::vector
<policy::DeviceLocalAccount
> device_local_accounts
=
1484 policy::GetDeviceLocalAccounts(cros_settings_
);
1485 const policy::DeviceLocalAccount
* account
= NULL
;
1486 for (std::vector
<policy::DeviceLocalAccount
>::const_iterator
1487 it
= device_local_accounts
.begin();
1488 it
!= device_local_accounts
.end(); ++it
) {
1489 if (it
->user_id
== app_id
) {
1494 std::string kiosk_app_id
;
1496 kiosk_app_id
= account
->kiosk_app_id
;
1498 LOG(ERROR
) << "Logged into nonexistent kiosk-app account: " << app_id
;
1502 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
1503 command_line
->AppendSwitch(::switches::kForceAppMode
);
1504 command_line
->AppendSwitchASCII(::switches::kAppId
, kiosk_app_id
);
1506 // Disable window animation since kiosk app runs in a single full screen
1507 // window and window animation causes start-up janks.
1508 command_line
->AppendSwitch(
1509 wm::switches::kWindowAnimationsDisabled
);
1512 void UserManagerImpl::DemoAccountLoggedIn() {
1513 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1514 active_user_
= User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName
);
1515 active_user_
->SetStubImage(User::kInvalidImageIndex
, false);
1516 WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName
);
1518 // Disable window animation since the demo app runs in a single full screen
1519 // window and window animation causes start-up janks.
1520 CommandLine::ForCurrentProcess()->AppendSwitch(
1521 wm::switches::kWindowAnimationsDisabled
);
1524 void UserManagerImpl::RetailModeUserLoggedIn() {
1525 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1526 is_current_user_new_
= true;
1527 active_user_
= User::CreateRetailModeUser();
1528 GetUserImageManager(UserManager::kRetailModeUserName
)->UserLoggedIn(
1529 is_current_user_new_
,
1531 WallpaperManager::Get()->SetUserWallpaperNow(
1532 UserManager::kRetailModeUserName
);
1535 void UserManagerImpl::NotifyOnLogin() {
1536 UpdateNumberOfUsers();
1537 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1538 NotifyActiveUserHashChanged(active_user_
->username_hash());
1539 NotifyActiveUserChanged(active_user_
);
1542 // TODO(nkostylev): Deprecate this notification in favor of
1543 // ActiveUserChanged() observer call.
1544 content::NotificationService::current()->Notify(
1545 chrome::NOTIFICATION_LOGIN_USER_CHANGED
,
1546 content::Source
<UserManager
>(this),
1547 content::Details
<const User
>(active_user_
));
1549 // Owner must be first user in session. DeviceSettingsService can't deal with
1550 // multiple user and will mix up ownership, crbug.com/230018.
1551 if (GetLoggedInUsers().size() == 1) {
1552 // Indicate to DeviceSettingsService that the owner key may have become
1554 DeviceSettingsService::Get()->SetUsername(active_user_
->email());
1558 User::OAuthTokenStatus
UserManagerImpl::LoadUserOAuthStatus(
1559 const std::string
& user_id
) const {
1560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1562 PrefService
* local_state
= g_browser_process
->local_state();
1563 const base::DictionaryValue
* prefs_oauth_status
=
1564 local_state
->GetDictionary(kUserOAuthTokenStatus
);
1565 int oauth_token_status
= User::OAUTH_TOKEN_STATUS_UNKNOWN
;
1566 if (prefs_oauth_status
&&
1567 prefs_oauth_status
->GetIntegerWithoutPathExpansion(
1568 user_id
, &oauth_token_status
)) {
1569 User::OAuthTokenStatus result
=
1570 static_cast<User::OAuthTokenStatus
>(oauth_token_status
);
1571 if (result
== User::OAUTH2_TOKEN_STATUS_INVALID
)
1572 GetUserFlow(user_id
)->HandleOAuthTokenStatusChange(result
);
1575 return User::OAUTH_TOKEN_STATUS_UNKNOWN
;
1578 bool UserManagerImpl::LoadForceOnlineSignin(const std::string
& user_id
) const {
1579 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1581 PrefService
* local_state
= g_browser_process
->local_state();
1582 const base::DictionaryValue
* prefs_force_online
=
1583 local_state
->GetDictionary(kUserForceOnlineSignin
);
1584 bool force_online_signin
= false;
1585 if (prefs_force_online
) {
1586 prefs_force_online
->GetBooleanWithoutPathExpansion(user_id
,
1587 &force_online_signin
);
1589 return force_online_signin
;
1592 void UserManagerImpl::UpdateOwnership() {
1593 bool is_owner
= DeviceSettingsService::Get()->HasPrivateOwnerKey();
1594 VLOG(1) << "Current user " << (is_owner
? "is owner" : "is not owner");
1596 SetCurrentUserIsOwner(is_owner
);
1599 void UserManagerImpl::RemoveNonCryptohomeData(const std::string
& user_id
) {
1600 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id
);
1601 GetUserImageManager(user_id
)->DeleteUserImage();
1603 PrefService
* prefs
= g_browser_process
->local_state();
1604 DictionaryPrefUpdate
prefs_display_name_update(prefs
, kUserDisplayName
);
1605 prefs_display_name_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
1607 DictionaryPrefUpdate
prefs_given_name_update(prefs
, kUserGivenName
);
1608 prefs_given_name_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
1610 DictionaryPrefUpdate
prefs_display_email_update(prefs
, kUserDisplayEmail
);
1611 prefs_display_email_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
1613 DictionaryPrefUpdate
prefs_oauth_update(prefs
, kUserOAuthTokenStatus
);
1614 prefs_oauth_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
1616 DictionaryPrefUpdate
prefs_force_online_update(prefs
, kUserForceOnlineSignin
);
1617 prefs_force_online_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
1619 supervised_user_manager_
->RemoveNonCryptohomeData(user_id
);
1621 multi_profile_user_controller_
->RemoveCachedValues(user_id
);
1624 User
* UserManagerImpl::RemoveRegularOrLocallyManagedUserFromList(
1625 const std::string
& user_id
) {
1626 ListPrefUpdate
prefs_users_update(g_browser_process
->local_state(),
1628 prefs_users_update
->Clear();
1630 for (UserList::iterator it
= users_
.begin(); it
!= users_
.end(); ) {
1631 const std::string user_email
= (*it
)->email();
1632 if (user_email
== user_id
) {
1634 it
= users_
.erase(it
);
1636 if ((*it
)->GetType() == User::USER_TYPE_REGULAR
||
1637 (*it
)->GetType() == User::USER_TYPE_LOCALLY_MANAGED
) {
1638 prefs_users_update
->Append(new base::StringValue(user_email
));
1646 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
1647 PrefService
* local_state
= g_browser_process
->local_state();
1648 const std::string public_account_pending_data_removal
=
1649 local_state
->GetString(kPublicAccountPendingDataRemoval
);
1650 if (public_account_pending_data_removal
.empty() ||
1651 (IsUserLoggedIn() &&
1652 public_account_pending_data_removal
== GetActiveUser()->email())) {
1656 RemoveNonCryptohomeData(public_account_pending_data_removal
);
1657 local_state
->ClearPref(kPublicAccountPendingDataRemoval
);
1660 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
1661 const std::vector
<std::string
>& old_public_accounts
) {
1662 std::set
<std::string
> users
;
1663 for (UserList::const_iterator it
= users_
.begin(); it
!= users_
.end(); ++it
)
1664 users
.insert((*it
)->email());
1666 // If the user is logged into a public account that has been removed from the
1667 // user list, mark the account's data as pending removal after logout.
1668 if (IsLoggedInAsPublicAccount()) {
1669 const std::string active_user_id
= GetActiveUser()->email();
1670 if (users
.find(active_user_id
) == users
.end()) {
1671 g_browser_process
->local_state()->SetString(
1672 kPublicAccountPendingDataRemoval
, active_user_id
);
1673 users
.insert(active_user_id
);
1677 // Remove the data belonging to any other public accounts that are no longer
1678 // found on the user list.
1679 for (std::vector
<std::string
>::const_iterator
1680 it
= old_public_accounts
.begin();
1681 it
!= old_public_accounts
.end(); ++it
) {
1682 if (users
.find(*it
) == users
.end())
1683 RemoveNonCryptohomeData(*it
);
1687 bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
1688 const std::vector
<policy::DeviceLocalAccount
>& device_local_accounts
) {
1689 // Try to remove any public account data marked as pending removal.
1690 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
1692 // Get the current list of public accounts.
1693 std::vector
<std::string
> old_public_accounts
;
1694 for (UserList::const_iterator it
= users_
.begin(); it
!= users_
.end(); ++it
) {
1695 if ((*it
)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT
)
1696 old_public_accounts
.push_back((*it
)->email());
1699 // Get the new list of public accounts from policy.
1700 std::vector
<std::string
> new_public_accounts
;
1701 for (std::vector
<policy::DeviceLocalAccount
>::const_iterator it
=
1702 device_local_accounts
.begin();
1703 it
!= device_local_accounts
.end(); ++it
) {
1704 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
1705 // standard login framework: http://crbug.com/234694
1706 if (it
->type
== policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION
)
1707 new_public_accounts
.push_back(it
->user_id
);
1710 // If the list of public accounts has not changed, return.
1711 if (new_public_accounts
.size() == old_public_accounts
.size()) {
1712 bool changed
= false;
1713 for (size_t i
= 0; i
< new_public_accounts
.size(); ++i
) {
1714 if (new_public_accounts
[i
] != old_public_accounts
[i
]) {
1723 // Persist the new list of public accounts in a pref.
1724 ListPrefUpdate
prefs_public_accounts_update(g_browser_process
->local_state(),
1726 prefs_public_accounts_update
->Clear();
1727 for (std::vector
<std::string
>::const_iterator it
=
1728 new_public_accounts
.begin();
1729 it
!= new_public_accounts
.end(); ++it
) {
1730 prefs_public_accounts_update
->AppendString(*it
);
1733 // Remove the old public accounts from the user list.
1734 for (UserList::iterator it
= users_
.begin(); it
!= users_
.end();) {
1735 if ((*it
)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT
) {
1736 if (*it
!= GetLoggedInUser())
1738 it
= users_
.erase(it
);
1744 // Add the new public accounts to the front of the user list.
1745 for (std::vector
<std::string
>::const_reverse_iterator it
=
1746 new_public_accounts
.rbegin();
1747 it
!= new_public_accounts
.rend(); ++it
) {
1748 if (IsLoggedInAsPublicAccount() && *it
== GetActiveUser()->email())
1749 users_
.insert(users_
.begin(), GetLoggedInUser());
1751 users_
.insert(users_
.begin(), User::CreatePublicAccountUser(*it
));
1752 UpdatePublicAccountDisplayName(*it
);
1755 for (UserList::iterator ui
= users_
.begin(),
1756 ue
= users_
.begin() + new_public_accounts
.size();
1758 GetUserImageManager((*ui
)->email())->LoadUserImage();
1761 // Remove data belonging to public accounts that are no longer found on the
1763 CleanUpPublicAccountNonCryptohomeData(old_public_accounts
);
1768 void UserManagerImpl::UpdatePublicAccountDisplayName(
1769 const std::string
& user_id
) {
1770 std::string display_name
;
1772 if (device_local_account_policy_service_
) {
1773 policy::DeviceLocalAccountPolicyBroker
* broker
=
1774 device_local_account_policy_service_
->GetBrokerForUser(user_id
);
1776 display_name
= broker
->GetDisplayName();
1779 // Set or clear the display name.
1780 SaveUserDisplayName(user_id
, base::UTF8ToUTF16(display_name
));
1783 UserFlow
* UserManagerImpl::GetCurrentUserFlow() const {
1784 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1785 if (!IsUserLoggedIn())
1786 return GetDefaultUserFlow();
1787 return GetUserFlow(GetLoggedInUser()->email());
1790 UserFlow
* UserManagerImpl::GetUserFlow(const std::string
& user_id
) const {
1791 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1792 FlowMap::const_iterator it
= specific_flows_
.find(user_id
);
1793 if (it
!= specific_flows_
.end())
1795 return GetDefaultUserFlow();
1798 void UserManagerImpl::SetUserFlow(const std::string
& user_id
, UserFlow
* flow
) {
1799 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1800 ResetUserFlow(user_id
);
1801 specific_flows_
[user_id
] = flow
;
1804 void UserManagerImpl::ResetUserFlow(const std::string
& user_id
) {
1805 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1806 FlowMap::iterator it
= specific_flows_
.find(user_id
);
1807 if (it
!= specific_flows_
.end()) {
1809 specific_flows_
.erase(it
);
1813 bool UserManagerImpl::GetAppModeChromeClientOAuthInfo(
1814 std::string
* chrome_client_id
, std::string
* chrome_client_secret
) {
1815 if (!chrome::IsRunningInForcedAppMode() ||
1816 chrome_client_id_
.empty() ||
1817 chrome_client_secret_
.empty()) {
1821 *chrome_client_id
= chrome_client_id_
;
1822 *chrome_client_secret
= chrome_client_secret_
;
1826 void UserManagerImpl::SetAppModeChromeClientOAuthInfo(
1827 const std::string
& chrome_client_id
,
1828 const std::string
& chrome_client_secret
) {
1829 if (!chrome::IsRunningInForcedAppMode())
1832 chrome_client_id_
= chrome_client_id
;
1833 chrome_client_secret_
= chrome_client_secret
;
1836 bool UserManagerImpl::AreLocallyManagedUsersAllowed() const {
1837 bool locally_managed_users_allowed
= false;
1838 cros_settings_
->GetBoolean(kAccountsPrefSupervisedUsersEnabled
,
1839 &locally_managed_users_allowed
);
1840 policy::BrowserPolicyConnectorChromeOS
* connector
=
1841 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
1842 return locally_managed_users_allowed
|| !connector
->IsEnterpriseManaged();
1845 base::FilePath
UserManagerImpl::GetUserProfileDir(
1846 const std::string
& user_id
) const {
1847 // TODO(dpolukhin): Remove Chrome OS specific profile path logic from
1848 // ProfileManager and use only this function to construct profile path.
1849 // TODO(nkostylev): Cleanup profile dir related code paths crbug.com/294233
1850 base::FilePath profile_dir
;
1851 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
1852 if (command_line
.HasSwitch(::switches::kMultiProfiles
)) {
1853 const User
* user
= FindUser(user_id
);
1854 if (user
&& !user
->username_hash().empty())
1855 profile_dir
= ProfileHelper::GetUserProfileDir(user
->username_hash());
1856 } else if (command_line
.HasSwitch(chromeos::switches::kLoginProfile
)) {
1857 profile_dir
= ProfileHelper::GetProfileDirByLegacyLoginProfileSwitch();
1859 // We should never be logged in with no profile dir unless
1860 // multi-profiles are enabled.
1862 profile_dir
= base::FilePath();
1865 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
1866 profile_dir
= profile_manager
->user_data_dir().Append(profile_dir
);
1871 UserFlow
* UserManagerImpl::GetDefaultUserFlow() const {
1872 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1873 if (!default_flow_
.get())
1874 default_flow_
.reset(new DefaultUserFlow());
1875 return default_flow_
.get();
1878 void UserManagerImpl::NotifyUserListChanged() {
1879 content::NotificationService::current()->Notify(
1880 chrome::NOTIFICATION_USER_LIST_CHANGED
,
1881 content::Source
<UserManager
>(this),
1882 content::NotificationService::NoDetails());
1885 void UserManagerImpl::NotifyActiveUserChanged(const User
* active_user
) {
1886 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1887 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver
,
1888 session_state_observer_list_
,
1889 ActiveUserChanged(active_user
));
1892 void UserManagerImpl::NotifyUserAddedToSession(const User
* added_user
) {
1893 UpdateNumberOfUsers();
1894 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1895 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver
,
1896 session_state_observer_list_
,
1897 UserAddedToSession(added_user
));
1900 void UserManagerImpl::NotifyActiveUserHashChanged(const std::string
& hash
) {
1901 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1902 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver
,
1903 session_state_observer_list_
,
1904 ActiveUserHashChanged(hash
));
1907 void UserManagerImpl::NotifyPendingUserSessionsRestoreFinished() {
1908 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1909 user_sessions_restored_
= true;
1910 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver
,
1911 session_state_observer_list_
,
1912 PendingUserSessionsRestoreFinished());
1915 void UserManagerImpl::UpdateLoginState() {
1916 if (!LoginState::IsInitialized())
1917 return; // LoginState may not be intialized in tests.
1918 LoginState::LoggedInState logged_in_state
;
1919 logged_in_state
= active_user_
? LoginState::LOGGED_IN_ACTIVE
1920 : LoginState::LOGGED_IN_NONE
;
1922 LoginState::LoggedInUserType login_user_type
;
1923 if (logged_in_state
== LoginState::LOGGED_IN_NONE
)
1924 login_user_type
= LoginState::LOGGED_IN_USER_NONE
;
1925 else if (is_current_user_owner_
)
1926 login_user_type
= LoginState::LOGGED_IN_USER_OWNER
;
1927 else if (active_user_
->GetType() == User::USER_TYPE_GUEST
)
1928 login_user_type
= LoginState::LOGGED_IN_USER_GUEST
;
1929 else if (active_user_
->GetType() == User::USER_TYPE_RETAIL_MODE
)
1930 login_user_type
= LoginState::LOGGED_IN_USER_RETAIL_MODE
;
1931 else if (active_user_
->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT
)
1932 login_user_type
= LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT
;
1933 else if (active_user_
->GetType() == User::USER_TYPE_LOCALLY_MANAGED
)
1934 login_user_type
= LoginState::LOGGED_IN_USER_LOCALLY_MANAGED
;
1935 else if (active_user_
->GetType() == User::USER_TYPE_KIOSK_APP
)
1936 login_user_type
= LoginState::LOGGED_IN_USER_KIOSK_APP
;
1938 login_user_type
= LoginState::LOGGED_IN_USER_REGULAR
;
1940 LoginState::Get()->SetLoggedInState(logged_in_state
, login_user_type
);
1943 void UserManagerImpl::SetLRUUser(User
* user
) {
1944 UserList::iterator it
= std::find(lru_logged_in_users_
.begin(),
1945 lru_logged_in_users_
.end(),
1947 if (it
!= lru_logged_in_users_
.end())
1948 lru_logged_in_users_
.erase(it
);
1949 lru_logged_in_users_
.insert(lru_logged_in_users_
.begin(), user
);
1952 void UserManagerImpl::OnRestoreActiveSessions(
1953 const SessionManagerClient::ActiveSessionsMap
& sessions
,
1956 LOG(ERROR
) << "Could not get list of active user sessions after crash.";
1957 // If we could not get list of active user sessions it is safer to just
1958 // sign out so that we don't get in the inconsistent state.
1959 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
1963 // One profile has been already loaded on browser start.
1964 DCHECK(GetLoggedInUsers().size() == 1);
1965 DCHECK(GetActiveUser());
1966 std::string active_user_id
= GetActiveUser()->email();
1968 SessionManagerClient::ActiveSessionsMap::const_iterator it
;
1969 for (it
= sessions
.begin(); it
!= sessions
.end(); ++it
) {
1970 if (active_user_id
== it
->first
)
1972 pending_user_sessions_
[it
->first
] = it
->second
;
1974 RestorePendingUserSessions();
1977 void UserManagerImpl::RestorePendingUserSessions() {
1978 if (pending_user_sessions_
.empty()) {
1979 NotifyPendingUserSessionsRestoreFinished();
1983 // Get next user to restore sessions and delete it from list.
1984 SessionManagerClient::ActiveSessionsMap::const_iterator it
=
1985 pending_user_sessions_
.begin();
1986 std::string user_id
= it
->first
;
1987 std::string user_id_hash
= it
->second
;
1988 DCHECK(!user_id
.empty());
1989 DCHECK(!user_id_hash
.empty());
1990 pending_user_sessions_
.erase(user_id
);
1992 // Check that this user is not logged in yet.
1993 UserList logged_in_users
= GetLoggedInUsers();
1994 bool user_already_logged_in
= false;
1995 for (UserList::const_iterator it
= logged_in_users
.begin();
1996 it
!= logged_in_users
.end(); ++it
) {
1997 const User
* user
= (*it
);
1998 if (user
->email() == user_id
) {
1999 user_already_logged_in
= true;
2003 DCHECK(!user_already_logged_in
);
2005 if (!user_already_logged_in
) {
2006 // Will call OnProfilePrepared() once profile has been loaded.
2007 LoginUtils::Get()->PrepareProfile(
2008 UserContext(user_id
,
2009 std::string(), // password
2010 std::string(), // auth_code
2012 false, // using_oauth
2013 UserContext::AUTH_FLOW_OFFLINE
),
2014 std::string(), // display_email
2015 false, // has_cookies
2016 true, // has_active_session
2019 RestorePendingUserSessions();
2023 void UserManagerImpl::SendRegularUserLoginMetrics(const std::string
& user_id
) {
2024 // If this isn't the first time Chrome was run after the system booted,
2025 // assume that Chrome was restarted because a previous session ended.
2026 if (!CommandLine::ForCurrentProcess()->HasSwitch(
2027 switches::kFirstExecAfterBoot
)) {
2028 const std::string last_email
=
2029 g_browser_process
->local_state()->GetString(kLastLoggedInRegularUser
);
2030 const base::TimeDelta time_to_login
=
2031 base::TimeTicks::Now() - manager_creation_time_
;
2032 if (!last_email
.empty() && user_id
!= last_email
&&
2033 time_to_login
.InSeconds() <= kLogoutToLoginDelayMaxSec
) {
2034 UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay",
2035 time_to_login
.InSeconds(), 0, kLogoutToLoginDelayMaxSec
, 50);
2040 void UserManagerImpl::OnUserNotAllowed(const std::string
& user_email
) {
2041 LOG(ERROR
) << "Shutdown session because a user is not allowed to be in the "
2043 chromeos::ShowMultiprofilesSessionAbortedDialog(user_email
);
2046 void UserManagerImpl::UpdateUserAccountLocale(const std::string
& user_id
,
2047 const std::string
& locale
) {
2048 if (!locale
.empty() &&
2049 locale
!= g_browser_process
->GetApplicationLocale()) {
2050 BrowserThread::PostBlockingPoolTask(
2052 base::Bind(ResolveLocale
, locale
,
2053 base::Bind(&UserManagerImpl::DoUpdateAccountLocale
,
2054 base::Unretained(this),
2057 DoUpdateAccountLocale(user_id
, locale
);
2061 void UserManagerImpl::DoUpdateAccountLocale(
2062 const std::string
& user_id
,
2063 const std::string
& resolved_locale
) {
2064 if (User
* user
= FindUserAndModify(user_id
))
2065 user
->SetAccountLocale(resolved_locale
);
2068 void UserManagerImpl::UpdateNumberOfUsers() {
2069 size_t users
= GetLoggedInUsers().size();
2071 // Write the user number as UMA stat when a multi user session is possible.
2072 if ((users
+ GetUsersAdmittedForMultiProfile().size()) > 1)
2073 ash::MultiProfileUMA::RecordUserCount(users
);
2076 base::debug::SetCrashKeyValue(crash_keys::kNumberOfUsers
,
2077 base::StringPrintf("%" PRIuS
, GetLoggedInUsers().size()));
2080 void UserManagerImpl::DeleteUser(User
* user
) {
2081 const bool is_active_user
= (user
== active_user_
);
2084 active_user_
= NULL
;
2087 } // namespace chromeos