1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/login/users/chrome_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/format_macros.h"
16 #include "base/logging.h"
17 #include "base/metrics/histogram.h"
18 #include "base/prefs/pref_registry_simple.h"
19 #include "base/prefs/pref_service.h"
20 #include "base/prefs/scoped_user_pref_update.h"
21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h"
23 #include "base/strings/utf_string_conversions.h"
24 #include "base/thread_task_runner_handle.h"
25 #include "base/values.h"
26 #include "chrome/browser/browser_process.h"
27 #include "chrome/browser/chrome_notification_types.h"
28 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
29 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
30 #include "chrome/browser/chromeos/login/signin/auth_sync_observer.h"
31 #include "chrome/browser/chromeos/login/signin/auth_sync_observer_factory.h"
32 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h"
33 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
34 #include "chrome/browser/chromeos/login/users/supervised_user_manager_impl.h"
35 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
36 #include "chrome/browser/chromeos/policy/device_local_account.h"
37 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog.h"
38 #include "chrome/browser/chromeos/profiles/profile_helper.h"
39 #include "chrome/browser/chromeos/session_length_limiter.h"
40 #include "chrome/browser/profiles/profile.h"
41 #include "chrome/browser/signin/easy_unlock_service.h"
42 #include "chrome/browser/supervised_user/chromeos/manager_password_service_factory.h"
43 #include "chrome/browser/supervised_user/chromeos/supervised_user_password_service_factory.h"
44 #include "chrome/common/chrome_constants.h"
45 #include "chrome/common/chrome_switches.h"
46 #include "chrome/common/crash_keys.h"
47 #include "chrome/common/pref_names.h"
48 #include "chrome/grit/theme_resources.h"
49 #include "chromeos/chromeos_switches.h"
50 #include "chromeos/login/user_names.h"
51 #include "chromeos/settings/cros_settings_names.h"
52 #include "components/session_manager/core/session_manager.h"
53 #include "components/user_manager/remove_user_delegate.h"
54 #include "components/user_manager/user_image/user_image.h"
55 #include "components/user_manager/user_type.h"
56 #include "content/public/browser/browser_thread.h"
57 #include "content/public/browser/notification_service.h"
58 #include "policy/policy_constants.h"
59 #include "ui/base/resource/resource_bundle.h"
60 #include "ui/wm/core/wm_core_switches.h"
62 using content::BrowserThread
;
67 // A vector pref of the the regular users known on this device, arranged in LRU
69 const char kRegularUsers
[] = "LoggedInUsers";
71 // A vector pref of the public accounts defined on this device.
72 const char kPublicAccounts
[] = "PublicAccounts";
74 // A string pref that gets set when a public account is removed but a user is
75 // currently logged into that account, requiring the account's data to be
76 // removed after logout.
77 const char kPublicAccountPendingDataRemoval
[] =
78 "PublicAccountPendingDataRemoval";
83 void ChromeUserManagerImpl::RegisterPrefs(PrefRegistrySimple
* registry
) {
84 ChromeUserManager::RegisterPrefs(registry
);
86 registry
->RegisterListPref(kPublicAccounts
);
87 registry
->RegisterStringPref(kPublicAccountPendingDataRemoval
, std::string());
88 SupervisedUserManager::RegisterPrefs(registry
);
89 SessionLengthLimiter::RegisterPrefs(registry
);
93 scoped_ptr
<ChromeUserManager
> ChromeUserManagerImpl::CreateChromeUserManager() {
94 return scoped_ptr
<ChromeUserManager
>(new ChromeUserManagerImpl());
97 ChromeUserManagerImpl::ChromeUserManagerImpl()
98 : ChromeUserManager(base::ThreadTaskRunnerHandle::Get(),
99 BrowserThread::GetBlockingPool()),
100 cros_settings_(CrosSettings::Get()),
101 device_local_account_policy_service_(NULL
),
102 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
103 weak_factory_(this) {
104 UpdateNumberOfUsers();
106 // UserManager instance should be used only on UI thread.
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
109 chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED
,
110 content::NotificationService::AllSources());
112 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED
,
113 content::NotificationService::AllSources());
115 chrome::NOTIFICATION_PROFILE_CREATED
,
116 content::NotificationService::AllSources());
118 // Since we're in ctor postpone any actions till this is fully created.
119 if (base::MessageLoop::current()) {
120 base::MessageLoop::current()->PostTask(
122 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies
,
123 weak_factory_
.GetWeakPtr()));
126 local_accounts_subscription_
= cros_settings_
->AddSettingsObserver(
127 kAccountsPrefDeviceLocalAccounts
,
128 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies
,
129 weak_factory_
.GetWeakPtr()));
130 multi_profile_user_controller_
.reset(
131 new MultiProfileUserController(this, GetLocalState()));
133 policy::BrowserPolicyConnectorChromeOS
* connector
=
134 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
135 avatar_policy_observer_
.reset(new policy::CloudExternalDataPolicyObserver(
137 connector
->GetDeviceLocalAccountPolicyService(),
138 policy::key::kUserAvatarImage
,
140 avatar_policy_observer_
->Init();
142 wallpaper_policy_observer_
.reset(new policy::CloudExternalDataPolicyObserver(
144 connector
->GetDeviceLocalAccountPolicyService(),
145 policy::key::kWallpaperImage
,
147 wallpaper_policy_observer_
->Init();
150 ChromeUserManagerImpl::~ChromeUserManagerImpl() {
153 void ChromeUserManagerImpl::Shutdown() {
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
155 ChromeUserManager::Shutdown();
157 local_accounts_subscription_
.reset();
159 // Stop the session length limiter.
160 session_length_limiter_
.reset();
162 if (device_local_account_policy_service_
)
163 device_local_account_policy_service_
->RemoveObserver(this);
165 for (UserImageManagerMap::iterator it
= user_image_managers_
.begin(),
166 ie
= user_image_managers_
.end();
169 it
->second
->Shutdown();
171 multi_profile_user_controller_
.reset();
172 avatar_policy_observer_
.reset();
173 wallpaper_policy_observer_
.reset();
174 registrar_
.RemoveAll();
177 MultiProfileUserController
*
178 ChromeUserManagerImpl::GetMultiProfileUserController() {
179 return multi_profile_user_controller_
.get();
182 UserImageManager
* ChromeUserManagerImpl::GetUserImageManager(
183 const std::string
& user_id
) {
184 UserImageManagerMap::iterator ui
= user_image_managers_
.find(user_id
);
185 if (ui
!= user_image_managers_
.end())
186 return ui
->second
.get();
187 linked_ptr
<UserImageManagerImpl
> mgr(new UserImageManagerImpl(user_id
, this));
188 user_image_managers_
[user_id
] = mgr
;
192 SupervisedUserManager
* ChromeUserManagerImpl::GetSupervisedUserManager() {
193 return supervised_user_manager_
.get();
196 user_manager::UserList
ChromeUserManagerImpl::GetUsersAllowedForMultiProfile()
198 // Supervised users are not allowed to use multi-profiles.
199 if (GetLoggedInUsers().size() == 1 &&
200 GetPrimaryUser()->GetType() != user_manager::USER_TYPE_REGULAR
) {
201 return user_manager::UserList();
204 user_manager::UserList result
;
205 const user_manager::UserList
& users
= GetUsers();
206 for (user_manager::UserList::const_iterator it
= users
.begin();
209 if ((*it
)->GetType() == user_manager::USER_TYPE_REGULAR
&&
210 !(*it
)->is_logged_in()) {
211 MultiProfileUserController::UserAllowedInSessionReason check
;
212 multi_profile_user_controller_
->IsUserAllowedInSession((*it
)->email(),
215 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS
) {
216 return user_manager::UserList();
219 // Users with a policy that prevents them being added to a session will be
220 // shown in login UI but will be grayed out.
221 // Same applies to owner account (see http://crbug.com/385034).
222 result
.push_back(*it
);
229 user_manager::UserList
ChromeUserManagerImpl::GetUnlockUsers() const {
230 const user_manager::UserList
& logged_in_users
= GetLoggedInUsers();
231 if (logged_in_users
.empty())
232 return user_manager::UserList();
234 user_manager::UserList unlock_users
;
236 ProfileHelper::Get()->GetProfileByUserUnsafe(GetPrimaryUser());
237 std::string primary_behavior
=
238 profile
->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior
);
240 // Specific case: only one logged in user or
241 // primary user has primary-only multi-profile policy.
242 if (logged_in_users
.size() == 1 ||
243 primary_behavior
== MultiProfileUserController::kBehaviorPrimaryOnly
) {
244 if (GetPrimaryUser()->can_lock())
245 unlock_users
.push_back(primary_user_
);
247 // Fill list of potential unlock users based on multi-profile policy state.
248 for (user_manager::UserList::const_iterator it
= logged_in_users
.begin();
249 it
!= logged_in_users
.end();
251 user_manager::User
* user
= (*it
);
252 Profile
* profile
= ProfileHelper::Get()->GetProfileByUserUnsafe(user
);
253 const std::string behavior
=
254 profile
->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior
);
255 if (behavior
== MultiProfileUserController::kBehaviorUnrestricted
&&
257 unlock_users
.push_back(user
);
258 } else if (behavior
== MultiProfileUserController::kBehaviorPrimaryOnly
) {
260 << "Spotted primary-only multi-profile policy for non-primary user";
268 void ChromeUserManagerImpl::SessionStarted() {
269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
270 ChromeUserManager::SessionStarted();
272 content::NotificationService::current()->Notify(
273 chrome::NOTIFICATION_SESSION_STARTED
,
274 content::Source
<UserManager
>(this),
275 content::Details
<const user_manager::User
>(GetActiveUser()));
278 void ChromeUserManagerImpl::RemoveUserInternal(
279 const std::string
& user_email
,
280 user_manager::RemoveUserDelegate
* delegate
) {
281 CrosSettings
* cros_settings
= CrosSettings::Get();
283 const base::Closure
& callback
=
284 base::Bind(&ChromeUserManagerImpl::RemoveUserInternal
,
285 weak_factory_
.GetWeakPtr(),
289 // Ensure the value of owner email has been fetched.
290 if (CrosSettingsProvider::TRUSTED
!=
291 cros_settings
->PrepareTrustedValues(callback
)) {
292 // Value of owner email is not fetched yet. RemoveUserInternal will be
293 // called again after fetch completion.
297 cros_settings
->GetString(kDeviceOwner
, &owner
);
298 if (user_email
== owner
) {
299 // Owner is not allowed to be removed from the device.
302 RemoveNonOwnerUserInternal(user_email
, delegate
);
305 void ChromeUserManagerImpl::SaveUserOAuthStatus(
306 const std::string
& user_id
,
307 user_manager::User::OAuthTokenStatus oauth_token_status
) {
308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
309 ChromeUserManager::SaveUserOAuthStatus(user_id
, oauth_token_status
);
311 GetUserFlow(user_id
)->HandleOAuthTokenStatusChange(oauth_token_status
);
314 void ChromeUserManagerImpl::SaveUserDisplayName(
315 const std::string
& user_id
,
316 const base::string16
& display_name
) {
317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
318 ChromeUserManager::SaveUserDisplayName(user_id
, display_name
);
320 // Do not update local state if data stored or cached outside the user's
321 // cryptohome is to be treated as ephemeral.
322 if (!IsUserNonCryptohomeDataEphemeral(user_id
))
323 supervised_user_manager_
->UpdateManagerName(user_id
, display_name
);
326 void ChromeUserManagerImpl::StopPolicyObserverForTesting() {
327 avatar_policy_observer_
.reset();
328 wallpaper_policy_observer_
.reset();
331 void ChromeUserManagerImpl::Observe(
333 const content::NotificationSource
& source
,
334 const content::NotificationDetails
& details
) {
336 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED
:
337 if (!device_local_account_policy_service_
) {
338 policy::BrowserPolicyConnectorChromeOS
* connector
=
339 g_browser_process
->platform_part()
340 ->browser_policy_connector_chromeos();
341 device_local_account_policy_service_
=
342 connector
->GetDeviceLocalAccountPolicyService();
343 if (device_local_account_policy_service_
)
344 device_local_account_policy_service_
->AddObserver(this);
346 RetrieveTrustedDevicePolicies();
349 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED
: {
350 Profile
* profile
= content::Details
<Profile
>(details
).ptr();
351 if (IsUserLoggedIn() && !IsLoggedInAsGuest() && !IsLoggedInAsKioskApp()) {
352 if (IsLoggedInAsSupervisedUser())
353 SupervisedUserPasswordServiceFactory::GetForProfile(profile
);
354 if (IsLoggedInAsRegularUser())
355 ManagerPasswordServiceFactory::GetForProfile(profile
);
357 if (!profile
->IsOffTheRecord()) {
358 AuthSyncObserver
* sync_observer
=
359 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile
);
360 sync_observer
->StartObserving();
361 multi_profile_user_controller_
->StartObserving(profile
);
366 case chrome::NOTIFICATION_PROFILE_CREATED
: {
367 Profile
* profile
= content::Source
<Profile
>(source
).ptr();
368 user_manager::User
* user
=
369 ProfileHelper::Get()->GetUserByProfile(profile
);
371 user
->set_profile_is_created();
373 // If there is pending user switch, do it now.
374 if (!GetPendingUserSwitchID().empty()) {
375 // Call SwitchActiveUser async because otherwise it may cause
376 // ProfileManager::GetProfile before the profile gets registered
377 // in ProfileManager. It happens in case of sync profile load when
378 // NOTIFICATION_PROFILE_CREATED is called synchronously.
379 base::MessageLoop::current()->PostTask(
381 base::Bind(&ChromeUserManagerImpl::SwitchActiveUser
,
382 weak_factory_
.GetWeakPtr(),
383 GetPendingUserSwitchID()));
384 SetPendingUserSwitchID(std::string());
393 void ChromeUserManagerImpl::OnExternalDataSet(const std::string
& policy
,
394 const std::string
& user_id
) {
395 if (policy
== policy::key::kUserAvatarImage
)
396 GetUserImageManager(user_id
)->OnExternalDataSet(policy
);
397 else if (policy
== policy::key::kWallpaperImage
)
398 WallpaperManager::Get()->OnPolicySet(policy
, user_id
);
403 void ChromeUserManagerImpl::OnExternalDataCleared(const std::string
& policy
,
404 const std::string
& user_id
) {
405 if (policy
== policy::key::kUserAvatarImage
)
406 GetUserImageManager(user_id
)->OnExternalDataCleared(policy
);
407 else if (policy
== policy::key::kWallpaperImage
)
408 WallpaperManager::Get()->OnPolicyCleared(policy
, user_id
);
413 void ChromeUserManagerImpl::OnExternalDataFetched(
414 const std::string
& policy
,
415 const std::string
& user_id
,
416 scoped_ptr
<std::string
> data
) {
417 if (policy
== policy::key::kUserAvatarImage
)
418 GetUserImageManager(user_id
)->OnExternalDataFetched(policy
, data
.Pass());
419 else if (policy
== policy::key::kWallpaperImage
)
420 WallpaperManager::Get()->OnPolicyFetched(policy
, user_id
, data
.Pass());
425 void ChromeUserManagerImpl::OnPolicyUpdated(const std::string
& user_id
) {
426 const user_manager::User
* user
= FindUser(user_id
);
427 if (!user
|| user
->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT
)
429 UpdatePublicAccountDisplayName(user_id
);
432 void ChromeUserManagerImpl::OnDeviceLocalAccountsChanged() {
433 // No action needed here, changes to the list of device-local accounts get
434 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
437 bool ChromeUserManagerImpl::CanCurrentUserLock() const {
438 return ChromeUserManager::CanCurrentUserLock() &&
439 GetCurrentUserFlow()->CanLockScreen();
442 bool ChromeUserManagerImpl::IsUserNonCryptohomeDataEphemeral(
443 const std::string
& user_id
) const {
444 // Data belonging to the obsolete public accounts whose data has not been
445 // removed yet is not ephemeral.
446 bool is_obsolete_public_account
= IsPublicAccountMarkedForRemoval(user_id
);
448 return !is_obsolete_public_account
&&
449 ChromeUserManager::IsUserNonCryptohomeDataEphemeral(user_id
);
452 bool ChromeUserManagerImpl::AreEphemeralUsersEnabled() const {
453 policy::BrowserPolicyConnectorChromeOS
* connector
=
454 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
455 return GetEphemeralUsersEnabled() &&
456 (connector
->IsEnterpriseManaged() || !GetOwnerEmail().empty());
459 const std::string
& ChromeUserManagerImpl::GetApplicationLocale() const {
460 return g_browser_process
->GetApplicationLocale();
463 PrefService
* ChromeUserManagerImpl::GetLocalState() const {
464 return g_browser_process
? g_browser_process
->local_state() : NULL
;
467 void ChromeUserManagerImpl::HandleUserOAuthTokenStatusChange(
468 const std::string
& user_id
,
469 user_manager::User::OAuthTokenStatus status
) const {
470 GetUserFlow(user_id
)->HandleOAuthTokenStatusChange(status
);
473 bool ChromeUserManagerImpl::IsEnterpriseManaged() const {
474 policy::BrowserPolicyConnectorChromeOS
* connector
=
475 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
476 return connector
->IsEnterpriseManaged();
479 void ChromeUserManagerImpl::LoadPublicAccounts(
480 std::set
<std::string
>* public_sessions_set
) {
481 const base::ListValue
* prefs_public_sessions
=
482 GetLocalState()->GetList(kPublicAccounts
);
483 std::vector
<std::string
> public_sessions
;
484 ParseUserList(*prefs_public_sessions
,
485 std::set
<std::string
>(),
487 public_sessions_set
);
488 for (std::vector
<std::string
>::const_iterator it
= public_sessions
.begin();
489 it
!= public_sessions
.end();
491 users_
.push_back(user_manager::User::CreatePublicAccountUser(*it
));
492 UpdatePublicAccountDisplayName(*it
);
496 void ChromeUserManagerImpl::PerformPreUserListLoadingActions() {
497 // Clean up user list first. All code down the path should be synchronous,
498 // so that local state after transaction rollback is in consistent state.
499 // This process also should not trigger EnsureUsersLoaded again.
500 if (supervised_user_manager_
->HasFailedUserCreationTransaction())
501 supervised_user_manager_
->RollbackUserCreationTransaction();
504 void ChromeUserManagerImpl::PerformPostUserListLoadingActions() {
505 for (user_manager::UserList::iterator ui
= users_
.begin(), ue
= users_
.end();
508 GetUserImageManager((*ui
)->email())->LoadUserImage();
512 void ChromeUserManagerImpl::PerformPostUserLoggedInActions(
513 bool browser_restart
) {
514 // Initialize the session length limiter and start it only if
515 // session limit is defined by the policy.
516 session_length_limiter_
.reset(
517 new SessionLengthLimiter(NULL
, browser_restart
));
520 bool ChromeUserManagerImpl::IsDemoApp(const std::string
& user_id
) const {
521 return DemoAppLauncher::IsDemoAppSession(user_id
);
524 bool ChromeUserManagerImpl::IsKioskApp(const std::string
& user_id
) const {
525 policy::DeviceLocalAccount::Type device_local_account_type
;
526 return policy::IsDeviceLocalAccountUser(user_id
,
527 &device_local_account_type
) &&
528 device_local_account_type
==
529 policy::DeviceLocalAccount::TYPE_KIOSK_APP
;
532 bool ChromeUserManagerImpl::IsPublicAccountMarkedForRemoval(
533 const std::string
& user_id
) const {
535 GetLocalState()->GetString(kPublicAccountPendingDataRemoval
);
538 void ChromeUserManagerImpl::RetrieveTrustedDevicePolicies() {
539 // Local state may not be initialized in unit_tests.
540 if (!GetLocalState())
543 SetEphemeralUsersEnabled(false);
544 SetOwnerEmail(std::string());
546 // Schedule a callback if device policy has not yet been verified.
547 if (CrosSettingsProvider::TRUSTED
!=
548 cros_settings_
->PrepareTrustedValues(
549 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies
,
550 weak_factory_
.GetWeakPtr()))) {
554 bool ephemeral_users_enabled
= false;
555 cros_settings_
->GetBoolean(kAccountsPrefEphemeralUsersEnabled
,
556 &ephemeral_users_enabled
);
557 SetEphemeralUsersEnabled(ephemeral_users_enabled
);
559 std::string owner_email
;
560 cros_settings_
->GetString(kDeviceOwner
, &owner_email
);
561 SetOwnerEmail(owner_email
);
565 bool changed
= UpdateAndCleanUpPublicAccounts(
566 policy::GetDeviceLocalAccounts(cros_settings_
));
568 // If ephemeral users are enabled and we are on the login screen, take this
569 // opportunity to clean up by removing all regular users except the owner.
570 if (GetEphemeralUsersEnabled() && !IsUserLoggedIn()) {
571 ListPrefUpdate
prefs_users_update(GetLocalState(), kRegularUsers
);
572 prefs_users_update
->Clear();
573 for (user_manager::UserList::iterator it
= users_
.begin();
574 it
!= users_
.end();) {
575 const std::string user_email
= (*it
)->email();
576 if ((*it
)->GetType() == user_manager::USER_TYPE_REGULAR
&&
577 user_email
!= GetOwnerEmail()) {
578 RemoveNonCryptohomeData(user_email
);
580 it
= users_
.erase(it
);
583 if ((*it
)->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT
)
584 prefs_users_update
->Append(new base::StringValue(user_email
));
591 NotifyUserListChanged();
594 void ChromeUserManagerImpl::GuestUserLoggedIn() {
595 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
596 ChromeUserManager::GuestUserLoggedIn();
598 // TODO(nkostylev): Add support for passing guest session cryptohome
599 // mount point. Legacy (--login-profile) value will be used for now.
600 // http://crosbug.com/230859
601 active_user_
->SetStubImage(
602 user_manager::UserImage(
603 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
604 IDR_PROFILE_PICTURE_LOADING
)),
605 user_manager::User::USER_IMAGE_INVALID
,
608 // Initializes wallpaper after active_user_ is set.
609 WallpaperManager::Get()->SetUserWallpaperNow(chromeos::login::kGuestUserName
);
612 void ChromeUserManagerImpl::RegularUserLoggedIn(const std::string
& user_id
) {
613 ChromeUserManager::RegularUserLoggedIn(user_id
);
615 if (IsCurrentUserNew())
616 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
618 GetUserImageManager(user_id
)->UserLoggedIn(IsCurrentUserNew(), false);
620 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
622 // Make sure that new data is persisted to Local State.
623 GetLocalState()->CommitPendingWrite();
626 void ChromeUserManagerImpl::RegularUserLoggedInAsEphemeral(
627 const std::string
& user_id
) {
628 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
629 ChromeUserManager::RegularUserLoggedInAsEphemeral(user_id
);
631 GetUserImageManager(user_id
)->UserLoggedIn(IsCurrentUserNew(), false);
632 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
635 void ChromeUserManagerImpl::SupervisedUserLoggedIn(const std::string
& user_id
) {
636 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
638 // Remove the user from the user list.
639 active_user_
= RemoveRegularOrSupervisedUserFromList(user_id
);
641 // If the user was not found on the user list, create a new user.
642 if (!GetActiveUser()) {
643 SetIsCurrentUserNew(true);
644 active_user_
= user_manager::User::CreateSupervisedUser(user_id
);
645 // Leaving OAuth token status at the default state = unknown.
646 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
648 if (supervised_user_manager_
->CheckForFirstRun(user_id
)) {
649 SetIsCurrentUserNew(true);
650 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
652 SetIsCurrentUserNew(false);
656 // Add the user to the front of the user list.
657 ListPrefUpdate
prefs_users_update(GetLocalState(), kRegularUsers
);
658 prefs_users_update
->Insert(0, new base::StringValue(user_id
));
659 users_
.insert(users_
.begin(), active_user_
);
661 // Now that user is in the list, save display name.
662 if (IsCurrentUserNew()) {
663 SaveUserDisplayName(GetActiveUser()->email(),
664 GetActiveUser()->GetDisplayName());
667 GetUserImageManager(user_id
)->UserLoggedIn(IsCurrentUserNew(), true);
668 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
670 // Make sure that new data is persisted to Local State.
671 GetLocalState()->CommitPendingWrite();
674 void ChromeUserManagerImpl::PublicAccountUserLoggedIn(
675 user_manager::User
* user
) {
676 SetIsCurrentUserNew(true);
679 // The UserImageManager chooses a random avatar picture when a user logs in
680 // for the first time. Tell the UserImageManager that this user is not new to
681 // prevent the avatar from getting changed.
682 GetUserImageManager(user
->email())->UserLoggedIn(false, true);
683 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
686 void ChromeUserManagerImpl::KioskAppLoggedIn(const std::string
& app_id
) {
687 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
688 policy::DeviceLocalAccount::Type device_local_account_type
;
689 DCHECK(policy::IsDeviceLocalAccountUser(app_id
, &device_local_account_type
));
690 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP
,
691 device_local_account_type
);
693 active_user_
= user_manager::User::CreateKioskAppUser(app_id
);
694 active_user_
->SetStubImage(
695 user_manager::UserImage(
696 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
697 IDR_PROFILE_PICTURE_LOADING
)),
698 user_manager::User::USER_IMAGE_INVALID
,
701 WallpaperManager::Get()->SetUserWallpaperNow(app_id
);
703 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
704 // the kiosk_app_id in these objects, removing the need to re-parse the
705 // device-local account list here to extract the kiosk_app_id.
706 const std::vector
<policy::DeviceLocalAccount
> device_local_accounts
=
707 policy::GetDeviceLocalAccounts(cros_settings_
);
708 const policy::DeviceLocalAccount
* account
= NULL
;
709 for (std::vector
<policy::DeviceLocalAccount
>::const_iterator it
=
710 device_local_accounts
.begin();
711 it
!= device_local_accounts
.end();
713 if (it
->user_id
== app_id
) {
718 std::string kiosk_app_id
;
720 kiosk_app_id
= account
->kiosk_app_id
;
722 LOG(ERROR
) << "Logged into nonexistent kiosk-app account: " << app_id
;
726 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
727 command_line
->AppendSwitch(::switches::kForceAppMode
);
728 command_line
->AppendSwitchASCII(::switches::kAppId
, kiosk_app_id
);
730 // Disable window animation since kiosk app runs in a single full screen
731 // window and window animation causes start-up janks.
732 command_line
->AppendSwitch(wm::switches::kWindowAnimationsDisabled
);
735 void ChromeUserManagerImpl::DemoAccountLoggedIn() {
736 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
738 user_manager::User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName
);
739 active_user_
->SetStubImage(
740 user_manager::UserImage(
741 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
742 IDR_PROFILE_PICTURE_LOADING
)),
743 user_manager::User::USER_IMAGE_INVALID
,
745 WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName
);
747 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
748 command_line
->AppendSwitch(::switches::kForceAppMode
);
749 command_line
->AppendSwitchASCII(::switches::kAppId
,
750 DemoAppLauncher::kDemoAppId
);
752 // Disable window animation since the demo app runs in a single full screen
753 // window and window animation causes start-up janks.
754 CommandLine::ForCurrentProcess()->AppendSwitch(
755 wm::switches::kWindowAnimationsDisabled
);
758 void ChromeUserManagerImpl::RetailModeUserLoggedIn() {
759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
760 SetIsCurrentUserNew(true);
761 active_user_
= user_manager::User::CreateRetailModeUser();
762 GetUserImageManager(chromeos::login::kRetailModeUserName
)
763 ->UserLoggedIn(IsCurrentUserNew(), true);
764 WallpaperManager::Get()->SetUserWallpaperNow(
765 chromeos::login::kRetailModeUserName
);
768 void ChromeUserManagerImpl::NotifyOnLogin() {
769 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
771 UserSessionManager::OverrideHomedir();
772 UpdateNumberOfUsers();
774 ChromeUserManager::NotifyOnLogin();
776 // TODO(nkostylev): Deprecate this notification in favor of
777 // ActiveUserChanged() observer call.
778 content::NotificationService::current()->Notify(
779 chrome::NOTIFICATION_LOGIN_USER_CHANGED
,
780 content::Source
<UserManager
>(this),
781 content::Details
<const user_manager::User
>(GetActiveUser()));
783 UserSessionManager::GetInstance()->PerformPostUserLoggedInActions();
786 void ChromeUserManagerImpl::UpdateOwnership() {
787 bool is_owner
= DeviceSettingsService::Get()->HasPrivateOwnerKey();
788 VLOG(1) << "Current user " << (is_owner
? "is owner" : "is not owner");
790 SetCurrentUserIsOwner(is_owner
);
793 void ChromeUserManagerImpl::RemoveNonCryptohomeData(
794 const std::string
& user_id
) {
795 ChromeUserManager::RemoveNonCryptohomeData(user_id
);
797 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id
);
798 GetUserImageManager(user_id
)->DeleteUserImage();
800 supervised_user_manager_
->RemoveNonCryptohomeData(user_id
);
802 multi_profile_user_controller_
->RemoveCachedValues(user_id
);
804 EasyUnlockService::RemoveHardlockStateForUser(user_id
);
808 ChromeUserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
809 PrefService
* local_state
= GetLocalState();
810 const std::string public_account_pending_data_removal
=
811 local_state
->GetString(kPublicAccountPendingDataRemoval
);
812 if (public_account_pending_data_removal
.empty() ||
814 public_account_pending_data_removal
== GetActiveUser()->email())) {
818 RemoveNonCryptohomeData(public_account_pending_data_removal
);
819 local_state
->ClearPref(kPublicAccountPendingDataRemoval
);
822 void ChromeUserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
823 const std::vector
<std::string
>& old_public_accounts
) {
824 std::set
<std::string
> users
;
825 for (user_manager::UserList::const_iterator it
= users_
.begin();
828 users
.insert((*it
)->email());
830 // If the user is logged into a public account that has been removed from the
831 // user list, mark the account's data as pending removal after logout.
832 if (IsLoggedInAsPublicAccount()) {
833 const std::string active_user_id
= GetActiveUser()->email();
834 if (users
.find(active_user_id
) == users
.end()) {
835 GetLocalState()->SetString(kPublicAccountPendingDataRemoval
,
837 users
.insert(active_user_id
);
841 // Remove the data belonging to any other public accounts that are no longer
842 // found on the user list.
843 for (std::vector
<std::string
>::const_iterator it
=
844 old_public_accounts
.begin();
845 it
!= old_public_accounts
.end();
847 if (users
.find(*it
) == users
.end())
848 RemoveNonCryptohomeData(*it
);
852 bool ChromeUserManagerImpl::UpdateAndCleanUpPublicAccounts(
853 const std::vector
<policy::DeviceLocalAccount
>& device_local_accounts
) {
854 // Try to remove any public account data marked as pending removal.
855 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
857 // Get the current list of public accounts.
858 std::vector
<std::string
> old_public_accounts
;
859 for (user_manager::UserList::const_iterator it
= users_
.begin();
862 if ((*it
)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT
)
863 old_public_accounts
.push_back((*it
)->email());
866 // Get the new list of public accounts from policy.
867 std::vector
<std::string
> new_public_accounts
;
868 for (std::vector
<policy::DeviceLocalAccount
>::const_iterator it
=
869 device_local_accounts
.begin();
870 it
!= device_local_accounts
.end();
872 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
873 // standard login framework: http://crbug.com/234694
874 if (it
->type
== policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION
)
875 new_public_accounts
.push_back(it
->user_id
);
878 // If the list of public accounts has not changed, return.
879 if (new_public_accounts
.size() == old_public_accounts
.size()) {
880 bool changed
= false;
881 for (size_t i
= 0; i
< new_public_accounts
.size(); ++i
) {
882 if (new_public_accounts
[i
] != old_public_accounts
[i
]) {
891 // Persist the new list of public accounts in a pref.
892 ListPrefUpdate
prefs_public_accounts_update(GetLocalState(), kPublicAccounts
);
893 prefs_public_accounts_update
->Clear();
894 for (std::vector
<std::string
>::const_iterator it
=
895 new_public_accounts
.begin();
896 it
!= new_public_accounts
.end();
898 prefs_public_accounts_update
->AppendString(*it
);
901 // Remove the old public accounts from the user list.
902 for (user_manager::UserList::iterator it
= users_
.begin();
903 it
!= users_
.end();) {
904 if ((*it
)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT
) {
905 if (*it
!= GetLoggedInUser())
907 it
= users_
.erase(it
);
913 // Add the new public accounts to the front of the user list.
914 for (std::vector
<std::string
>::const_reverse_iterator it
=
915 new_public_accounts
.rbegin();
916 it
!= new_public_accounts
.rend();
918 if (IsLoggedInAsPublicAccount() && *it
== GetActiveUser()->email())
919 users_
.insert(users_
.begin(), GetLoggedInUser());
921 users_
.insert(users_
.begin(),
922 user_manager::User::CreatePublicAccountUser(*it
));
923 UpdatePublicAccountDisplayName(*it
);
926 for (user_manager::UserList::iterator
928 ue
= users_
.begin() + new_public_accounts
.size();
931 GetUserImageManager((*ui
)->email())->LoadUserImage();
934 // Remove data belonging to public accounts that are no longer found on the
936 CleanUpPublicAccountNonCryptohomeData(old_public_accounts
);
941 void ChromeUserManagerImpl::UpdatePublicAccountDisplayName(
942 const std::string
& user_id
) {
943 std::string display_name
;
945 if (device_local_account_policy_service_
) {
946 policy::DeviceLocalAccountPolicyBroker
* broker
=
947 device_local_account_policy_service_
->GetBrokerForUser(user_id
);
949 display_name
= broker
->GetDisplayName();
952 // Set or clear the display name.
953 SaveUserDisplayName(user_id
, base::UTF8ToUTF16(display_name
));
956 UserFlow
* ChromeUserManagerImpl::GetCurrentUserFlow() const {
957 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
958 if (!IsUserLoggedIn())
959 return GetDefaultUserFlow();
960 return GetUserFlow(GetLoggedInUser()->email());
963 UserFlow
* ChromeUserManagerImpl::GetUserFlow(const std::string
& user_id
) const {
964 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
965 FlowMap::const_iterator it
= specific_flows_
.find(user_id
);
966 if (it
!= specific_flows_
.end())
968 return GetDefaultUserFlow();
971 void ChromeUserManagerImpl::SetUserFlow(const std::string
& user_id
,
973 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
974 ResetUserFlow(user_id
);
975 specific_flows_
[user_id
] = flow
;
978 void ChromeUserManagerImpl::ResetUserFlow(const std::string
& user_id
) {
979 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
980 FlowMap::iterator it
= specific_flows_
.find(user_id
);
981 if (it
!= specific_flows_
.end()) {
983 specific_flows_
.erase(it
);
987 bool ChromeUserManagerImpl::AreSupervisedUsersAllowed() const {
988 bool supervised_users_allowed
= false;
989 cros_settings_
->GetBoolean(kAccountsPrefSupervisedUsersEnabled
,
990 &supervised_users_allowed
);
991 return supervised_users_allowed
;
994 UserFlow
* ChromeUserManagerImpl::GetDefaultUserFlow() const {
995 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
996 if (!default_flow_
.get())
997 default_flow_
.reset(new DefaultUserFlow());
998 return default_flow_
.get();
1001 void ChromeUserManagerImpl::NotifyUserListChanged() {
1002 content::NotificationService::current()->Notify(
1003 chrome::NOTIFICATION_USER_LIST_CHANGED
,
1004 content::Source
<UserManager
>(this),
1005 content::NotificationService::NoDetails());
1008 void ChromeUserManagerImpl::NotifyUserAddedToSession(
1009 const user_manager::User
* added_user
,
1010 bool user_switch_pending
) {
1011 // Special case for user session restoration after browser crash.
1012 // We don't switch to each user session that has been restored as once all
1013 // session will be restored we'll switch to the session that has been used
1014 // before the crash.
1015 if (user_switch_pending
&&
1016 !UserSessionManager::GetInstance()->UserSessionsRestoreInProgress()) {
1017 SetPendingUserSwitchID(added_user
->email());
1020 UpdateNumberOfUsers();
1021 ChromeUserManager::NotifyUserAddedToSession(added_user
, user_switch_pending
);
1024 void ChromeUserManagerImpl::OnUserNotAllowed(const std::string
& user_email
) {
1025 LOG(ERROR
) << "Shutdown session because a user is not allowed to be in the "
1027 chromeos::ShowMultiprofilesSessionAbortedDialog(user_email
);
1030 void ChromeUserManagerImpl::UpdateNumberOfUsers() {
1031 size_t users
= GetLoggedInUsers().size();
1033 // Write the user number as UMA stat when a multi user session is possible.
1034 if ((users
+ GetUsersAllowedForMultiProfile().size()) > 1)
1035 ash::MultiProfileUMA::RecordUserCount(users
);
1038 base::debug::SetCrashKeyValue(
1039 crash_keys::kNumberOfUsers
,
1040 base::StringPrintf("%" PRIuS
, GetLoggedInUsers().size()));
1043 } // namespace chromeos