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/login/users/wallpaper/wallpaper_manager.h"
36 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
37 #include "chrome/browser/chromeos/policy/device_local_account.h"
38 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog.h"
39 #include "chrome/browser/chromeos/profiles/profile_helper.h"
40 #include "chrome/browser/chromeos/session_length_limiter.h"
41 #include "chrome/browser/chromeos/system/timezone_util.h"
42 #include "chrome/browser/profiles/profile.h"
43 #include "chrome/browser/signin/easy_unlock_service.h"
44 #include "chrome/browser/supervised_user/chromeos/manager_password_service_factory.h"
45 #include "chrome/browser/supervised_user/chromeos/supervised_user_password_service_factory.h"
46 #include "chrome/common/chrome_constants.h"
47 #include "chrome/common/chrome_switches.h"
48 #include "chrome/common/crash_keys.h"
49 #include "chrome/common/pref_names.h"
50 #include "chrome/grit/theme_resources.h"
51 #include "chromeos/chromeos_switches.h"
52 #include "chromeos/login/user_names.h"
53 #include "chromeos/settings/cros_settings_names.h"
54 #include "chromeos/timezone/timezone_resolver.h"
55 #include "components/session_manager/core/session_manager.h"
56 #include "components/user_manager/remove_user_delegate.h"
57 #include "components/user_manager/user_image/user_image.h"
58 #include "components/user_manager/user_type.h"
59 #include "content/public/browser/browser_thread.h"
60 #include "content/public/browser/notification_service.h"
61 #include "policy/policy_constants.h"
62 #include "ui/base/resource/resource_bundle.h"
63 #include "ui/wm/core/wm_core_switches.h"
65 using content::BrowserThread
;
70 // A vector pref of the the regular users known on this device, arranged in LRU
72 const char kRegularUsers
[] = "LoggedInUsers";
74 // A vector pref of the public accounts defined on this device.
75 const char kPublicAccounts
[] = "PublicAccounts";
77 // A string pref that gets set when a public account is removed but a user is
78 // currently logged into that account, requiring the account's data to be
79 // removed after logout.
80 const char kPublicAccountPendingDataRemoval
[] =
81 "PublicAccountPendingDataRemoval";
86 void ChromeUserManagerImpl::RegisterPrefs(PrefRegistrySimple
* registry
) {
87 ChromeUserManager::RegisterPrefs(registry
);
89 registry
->RegisterListPref(kPublicAccounts
);
90 registry
->RegisterStringPref(kPublicAccountPendingDataRemoval
, std::string());
91 SupervisedUserManager::RegisterPrefs(registry
);
92 SessionLengthLimiter::RegisterPrefs(registry
);
96 scoped_ptr
<ChromeUserManager
> ChromeUserManagerImpl::CreateChromeUserManager() {
97 return scoped_ptr
<ChromeUserManager
>(new ChromeUserManagerImpl());
100 ChromeUserManagerImpl::ChromeUserManagerImpl()
101 : ChromeUserManager(base::ThreadTaskRunnerHandle::Get(),
102 BrowserThread::GetBlockingPool()),
103 cros_settings_(CrosSettings::Get()),
104 device_local_account_policy_service_(NULL
),
105 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
106 weak_factory_(this) {
107 UpdateNumberOfUsers();
109 // UserManager instance should be used only on UI thread.
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
112 chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED
,
113 content::NotificationService::AllSources());
115 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED
,
116 content::NotificationService::AllSources());
118 chrome::NOTIFICATION_PROFILE_CREATED
,
119 content::NotificationService::AllSources());
121 // Since we're in ctor postpone any actions till this is fully created.
122 if (base::MessageLoop::current()) {
123 base::MessageLoop::current()->PostTask(
125 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies
,
126 weak_factory_
.GetWeakPtr()));
129 local_accounts_subscription_
= cros_settings_
->AddSettingsObserver(
130 kAccountsPrefDeviceLocalAccounts
,
131 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies
,
132 weak_factory_
.GetWeakPtr()));
133 multi_profile_user_controller_
.reset(
134 new MultiProfileUserController(this, GetLocalState()));
136 policy::BrowserPolicyConnectorChromeOS
* connector
=
137 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
138 avatar_policy_observer_
.reset(new policy::CloudExternalDataPolicyObserver(
140 connector
->GetDeviceLocalAccountPolicyService(),
141 policy::key::kUserAvatarImage
,
143 avatar_policy_observer_
->Init();
145 wallpaper_policy_observer_
.reset(new policy::CloudExternalDataPolicyObserver(
147 connector
->GetDeviceLocalAccountPolicyService(),
148 policy::key::kWallpaperImage
,
150 wallpaper_policy_observer_
->Init();
153 ChromeUserManagerImpl::~ChromeUserManagerImpl() {
156 void ChromeUserManagerImpl::Shutdown() {
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
158 ChromeUserManager::Shutdown();
160 local_accounts_subscription_
.reset();
162 // Stop the session length limiter.
163 session_length_limiter_
.reset();
165 if (device_local_account_policy_service_
)
166 device_local_account_policy_service_
->RemoveObserver(this);
168 for (UserImageManagerMap::iterator it
= user_image_managers_
.begin(),
169 ie
= user_image_managers_
.end();
172 it
->second
->Shutdown();
174 multi_profile_user_controller_
.reset();
175 avatar_policy_observer_
.reset();
176 wallpaper_policy_observer_
.reset();
177 registrar_
.RemoveAll();
180 MultiProfileUserController
*
181 ChromeUserManagerImpl::GetMultiProfileUserController() {
182 return multi_profile_user_controller_
.get();
185 UserImageManager
* ChromeUserManagerImpl::GetUserImageManager(
186 const std::string
& user_id
) {
187 UserImageManagerMap::iterator ui
= user_image_managers_
.find(user_id
);
188 if (ui
!= user_image_managers_
.end())
189 return ui
->second
.get();
190 linked_ptr
<UserImageManagerImpl
> mgr(new UserImageManagerImpl(user_id
, this));
191 user_image_managers_
[user_id
] = mgr
;
195 SupervisedUserManager
* ChromeUserManagerImpl::GetSupervisedUserManager() {
196 return supervised_user_manager_
.get();
199 user_manager::UserList
ChromeUserManagerImpl::GetUsersAllowedForMultiProfile()
201 // Supervised users are not allowed to use multi-profiles.
202 if (GetLoggedInUsers().size() == 1 &&
203 GetPrimaryUser()->GetType() != user_manager::USER_TYPE_REGULAR
) {
204 return user_manager::UserList();
207 user_manager::UserList result
;
208 const user_manager::UserList
& users
= GetUsers();
209 for (user_manager::UserList::const_iterator it
= users
.begin();
212 if ((*it
)->GetType() == user_manager::USER_TYPE_REGULAR
&&
213 !(*it
)->is_logged_in()) {
214 MultiProfileUserController::UserAllowedInSessionReason check
;
215 multi_profile_user_controller_
->IsUserAllowedInSession((*it
)->email(),
218 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS
) {
219 return user_manager::UserList();
222 // Users with a policy that prevents them being added to a session will be
223 // shown in login UI but will be grayed out.
224 // Same applies to owner account (see http://crbug.com/385034).
225 result
.push_back(*it
);
232 user_manager::UserList
233 ChromeUserManagerImpl::GetUsersAllowedForSupervisedUsersCreation() const {
234 CrosSettings
* cros_settings
= CrosSettings::Get();
235 bool allow_new_user
= true;
236 cros_settings
->GetBoolean(kAccountsPrefAllowNewUser
, &allow_new_user
);
237 bool supervised_users_allowed
= AreSupervisedUsersAllowed();
239 // Restricted either by policy or by owner.
240 if (!allow_new_user
|| !supervised_users_allowed
)
241 return user_manager::UserList();
243 return GetUsersAllowedAsSupervisedUserManagers(GetUsers());
246 user_manager::UserList
ChromeUserManagerImpl::GetUnlockUsers() const {
247 const user_manager::UserList
& logged_in_users
= GetLoggedInUsers();
248 if (logged_in_users
.empty())
249 return user_manager::UserList();
251 user_manager::UserList unlock_users
;
253 ProfileHelper::Get()->GetProfileByUserUnsafe(GetPrimaryUser());
254 std::string primary_behavior
=
255 profile
->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior
);
257 // Specific case: only one logged in user or
258 // primary user has primary-only multi-profile policy.
259 if (logged_in_users
.size() == 1 ||
260 primary_behavior
== MultiProfileUserController::kBehaviorPrimaryOnly
) {
261 if (GetPrimaryUser()->can_lock())
262 unlock_users
.push_back(primary_user_
);
264 // Fill list of potential unlock users based on multi-profile policy state.
265 for (user_manager::UserList::const_iterator it
= logged_in_users
.begin();
266 it
!= logged_in_users
.end();
268 user_manager::User
* user
= (*it
);
269 Profile
* profile
= ProfileHelper::Get()->GetProfileByUserUnsafe(user
);
270 const std::string behavior
=
271 profile
->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior
);
272 if (behavior
== MultiProfileUserController::kBehaviorUnrestricted
&&
274 unlock_users
.push_back(user
);
275 } else if (behavior
== MultiProfileUserController::kBehaviorPrimaryOnly
) {
277 << "Spotted primary-only multi-profile policy for non-primary user";
285 void ChromeUserManagerImpl::SessionStarted() {
286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
287 ChromeUserManager::SessionStarted();
289 content::NotificationService::current()->Notify(
290 chrome::NOTIFICATION_SESSION_STARTED
,
291 content::Source
<UserManager
>(this),
292 content::Details
<const user_manager::User
>(GetActiveUser()));
295 void ChromeUserManagerImpl::RemoveUserInternal(
296 const std::string
& user_email
,
297 user_manager::RemoveUserDelegate
* delegate
) {
298 CrosSettings
* cros_settings
= CrosSettings::Get();
300 const base::Closure
& callback
=
301 base::Bind(&ChromeUserManagerImpl::RemoveUserInternal
,
302 weak_factory_
.GetWeakPtr(),
306 // Ensure the value of owner email has been fetched.
307 if (CrosSettingsProvider::TRUSTED
!=
308 cros_settings
->PrepareTrustedValues(callback
)) {
309 // Value of owner email is not fetched yet. RemoveUserInternal will be
310 // called again after fetch completion.
314 cros_settings
->GetString(kDeviceOwner
, &owner
);
315 if (user_email
== owner
) {
316 // Owner is not allowed to be removed from the device.
319 RemoveNonOwnerUserInternal(user_email
, delegate
);
322 void ChromeUserManagerImpl::SaveUserOAuthStatus(
323 const std::string
& user_id
,
324 user_manager::User::OAuthTokenStatus oauth_token_status
) {
325 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
326 ChromeUserManager::SaveUserOAuthStatus(user_id
, oauth_token_status
);
328 GetUserFlow(user_id
)->HandleOAuthTokenStatusChange(oauth_token_status
);
331 void ChromeUserManagerImpl::SaveUserDisplayName(
332 const std::string
& user_id
,
333 const base::string16
& display_name
) {
334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
335 ChromeUserManager::SaveUserDisplayName(user_id
, display_name
);
337 // Do not update local state if data stored or cached outside the user's
338 // cryptohome is to be treated as ephemeral.
339 if (!IsUserNonCryptohomeDataEphemeral(user_id
))
340 supervised_user_manager_
->UpdateManagerName(user_id
, display_name
);
343 void ChromeUserManagerImpl::StopPolicyObserverForTesting() {
344 avatar_policy_observer_
.reset();
345 wallpaper_policy_observer_
.reset();
348 void ChromeUserManagerImpl::Observe(
350 const content::NotificationSource
& source
,
351 const content::NotificationDetails
& details
) {
353 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED
:
354 if (!device_local_account_policy_service_
) {
355 policy::BrowserPolicyConnectorChromeOS
* connector
=
356 g_browser_process
->platform_part()
357 ->browser_policy_connector_chromeos();
358 device_local_account_policy_service_
=
359 connector
->GetDeviceLocalAccountPolicyService();
360 if (device_local_account_policy_service_
)
361 device_local_account_policy_service_
->AddObserver(this);
363 RetrieveTrustedDevicePolicies();
366 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED
: {
367 Profile
* profile
= content::Details
<Profile
>(details
).ptr();
368 if (IsUserLoggedIn() && !IsLoggedInAsGuest() && !IsLoggedInAsKioskApp()) {
369 if (IsLoggedInAsSupervisedUser())
370 SupervisedUserPasswordServiceFactory::GetForProfile(profile
);
371 if (IsLoggedInAsUserWithGaiaAccount())
372 ManagerPasswordServiceFactory::GetForProfile(profile
);
374 if (!profile
->IsOffTheRecord()) {
375 AuthSyncObserver
* sync_observer
=
376 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile
);
377 sync_observer
->StartObserving();
378 multi_profile_user_controller_
->StartObserving(profile
);
381 UpdateUserTimeZoneRefresher(profile
);
384 case chrome::NOTIFICATION_PROFILE_CREATED
: {
385 Profile
* profile
= content::Source
<Profile
>(source
).ptr();
386 user_manager::User
* user
=
387 ProfileHelper::Get()->GetUserByProfile(profile
);
389 user
->set_profile_is_created();
391 if (user
->HasGaiaAccount()) {
392 UserImageManager
* image_manager
= GetUserImageManager(user
->email());
393 image_manager
->UserProfileCreated();
397 // If there is pending user switch, do it now.
398 if (!GetPendingUserSwitchID().empty()) {
399 // Call SwitchActiveUser async because otherwise it may cause
400 // ProfileManager::GetProfile before the profile gets registered
401 // in ProfileManager. It happens in case of sync profile load when
402 // NOTIFICATION_PROFILE_CREATED is called synchronously.
403 base::MessageLoop::current()->PostTask(
405 base::Bind(&ChromeUserManagerImpl::SwitchActiveUser
,
406 weak_factory_
.GetWeakPtr(),
407 GetPendingUserSwitchID()));
408 SetPendingUserSwitchID(std::string());
417 void ChromeUserManagerImpl::OnExternalDataSet(const std::string
& policy
,
418 const std::string
& user_id
) {
419 if (policy
== policy::key::kUserAvatarImage
)
420 GetUserImageManager(user_id
)->OnExternalDataSet(policy
);
421 else if (policy
== policy::key::kWallpaperImage
)
422 WallpaperManager::Get()->OnPolicySet(policy
, user_id
);
427 void ChromeUserManagerImpl::OnExternalDataCleared(const std::string
& policy
,
428 const std::string
& user_id
) {
429 if (policy
== policy::key::kUserAvatarImage
)
430 GetUserImageManager(user_id
)->OnExternalDataCleared(policy
);
431 else if (policy
== policy::key::kWallpaperImage
)
432 WallpaperManager::Get()->OnPolicyCleared(policy
, user_id
);
437 void ChromeUserManagerImpl::OnExternalDataFetched(
438 const std::string
& policy
,
439 const std::string
& user_id
,
440 scoped_ptr
<std::string
> data
) {
441 if (policy
== policy::key::kUserAvatarImage
)
442 GetUserImageManager(user_id
)->OnExternalDataFetched(policy
, data
.Pass());
443 else if (policy
== policy::key::kWallpaperImage
)
444 WallpaperManager::Get()->OnPolicyFetched(policy
, user_id
, data
.Pass());
449 void ChromeUserManagerImpl::OnPolicyUpdated(const std::string
& user_id
) {
450 const user_manager::User
* user
= FindUser(user_id
);
451 if (!user
|| user
->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT
)
453 UpdatePublicAccountDisplayName(user_id
);
456 void ChromeUserManagerImpl::OnDeviceLocalAccountsChanged() {
457 // No action needed here, changes to the list of device-local accounts get
458 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
461 bool ChromeUserManagerImpl::CanCurrentUserLock() const {
462 return ChromeUserManager::CanCurrentUserLock() &&
463 GetCurrentUserFlow()->CanLockScreen();
466 bool ChromeUserManagerImpl::IsUserNonCryptohomeDataEphemeral(
467 const std::string
& user_id
) const {
468 // Data belonging to the obsolete public accounts whose data has not been
469 // removed yet is not ephemeral.
470 bool is_obsolete_public_account
= IsPublicAccountMarkedForRemoval(user_id
);
472 return !is_obsolete_public_account
&&
473 ChromeUserManager::IsUserNonCryptohomeDataEphemeral(user_id
);
476 bool ChromeUserManagerImpl::AreEphemeralUsersEnabled() const {
477 policy::BrowserPolicyConnectorChromeOS
* connector
=
478 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
479 return GetEphemeralUsersEnabled() &&
480 (connector
->IsEnterpriseManaged() || !GetOwnerEmail().empty());
483 const std::string
& ChromeUserManagerImpl::GetApplicationLocale() const {
484 return g_browser_process
->GetApplicationLocale();
487 PrefService
* ChromeUserManagerImpl::GetLocalState() const {
488 return g_browser_process
? g_browser_process
->local_state() : NULL
;
491 void ChromeUserManagerImpl::HandleUserOAuthTokenStatusChange(
492 const std::string
& user_id
,
493 user_manager::User::OAuthTokenStatus status
) const {
494 GetUserFlow(user_id
)->HandleOAuthTokenStatusChange(status
);
497 bool ChromeUserManagerImpl::IsEnterpriseManaged() const {
498 policy::BrowserPolicyConnectorChromeOS
* connector
=
499 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
500 return connector
->IsEnterpriseManaged();
503 void ChromeUserManagerImpl::LoadPublicAccounts(
504 std::set
<std::string
>* public_sessions_set
) {
505 const base::ListValue
* prefs_public_sessions
=
506 GetLocalState()->GetList(kPublicAccounts
);
507 std::vector
<std::string
> public_sessions
;
508 ParseUserList(*prefs_public_sessions
,
509 std::set
<std::string
>(),
511 public_sessions_set
);
512 for (std::vector
<std::string
>::const_iterator it
= public_sessions
.begin();
513 it
!= public_sessions
.end();
515 users_
.push_back(user_manager::User::CreatePublicAccountUser(*it
));
516 UpdatePublicAccountDisplayName(*it
);
520 void ChromeUserManagerImpl::PerformPreUserListLoadingActions() {
521 // Clean up user list first. All code down the path should be synchronous,
522 // so that local state after transaction rollback is in consistent state.
523 // This process also should not trigger EnsureUsersLoaded again.
524 if (supervised_user_manager_
->HasFailedUserCreationTransaction())
525 supervised_user_manager_
->RollbackUserCreationTransaction();
528 void ChromeUserManagerImpl::PerformPostUserListLoadingActions() {
529 for (user_manager::UserList::iterator ui
= users_
.begin(), ue
= users_
.end();
532 GetUserImageManager((*ui
)->email())->LoadUserImage();
536 void ChromeUserManagerImpl::PerformPostUserLoggedInActions(
537 bool browser_restart
) {
538 // Initialize the session length limiter and start it only if
539 // session limit is defined by the policy.
540 session_length_limiter_
.reset(
541 new SessionLengthLimiter(NULL
, browser_restart
));
544 bool ChromeUserManagerImpl::IsDemoApp(const std::string
& user_id
) const {
545 return DemoAppLauncher::IsDemoAppSession(user_id
);
548 bool ChromeUserManagerImpl::IsKioskApp(const std::string
& user_id
) const {
549 policy::DeviceLocalAccount::Type device_local_account_type
;
550 return policy::IsDeviceLocalAccountUser(user_id
,
551 &device_local_account_type
) &&
552 device_local_account_type
==
553 policy::DeviceLocalAccount::TYPE_KIOSK_APP
;
556 bool ChromeUserManagerImpl::IsPublicAccountMarkedForRemoval(
557 const std::string
& user_id
) const {
559 GetLocalState()->GetString(kPublicAccountPendingDataRemoval
);
562 void ChromeUserManagerImpl::RetrieveTrustedDevicePolicies() {
563 // Local state may not be initialized in unit_tests.
564 if (!GetLocalState())
567 SetEphemeralUsersEnabled(false);
568 SetOwnerEmail(std::string());
570 // Schedule a callback if device policy has not yet been verified.
571 if (CrosSettingsProvider::TRUSTED
!=
572 cros_settings_
->PrepareTrustedValues(
573 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies
,
574 weak_factory_
.GetWeakPtr()))) {
578 bool ephemeral_users_enabled
= false;
579 cros_settings_
->GetBoolean(kAccountsPrefEphemeralUsersEnabled
,
580 &ephemeral_users_enabled
);
581 SetEphemeralUsersEnabled(ephemeral_users_enabled
);
583 std::string owner_email
;
584 cros_settings_
->GetString(kDeviceOwner
, &owner_email
);
585 SetOwnerEmail(owner_email
);
589 bool changed
= UpdateAndCleanUpPublicAccounts(
590 policy::GetDeviceLocalAccounts(cros_settings_
));
592 // If ephemeral users are enabled and we are on the login screen, take this
593 // opportunity to clean up by removing all regular users except the owner.
594 if (GetEphemeralUsersEnabled() && !IsUserLoggedIn()) {
595 ListPrefUpdate
prefs_users_update(GetLocalState(), kRegularUsers
);
596 prefs_users_update
->Clear();
597 for (user_manager::UserList::iterator it
= users_
.begin();
598 it
!= users_
.end();) {
599 const std::string user_email
= (*it
)->email();
600 if ((*it
)->HasGaiaAccount() && user_email
!= GetOwnerEmail()) {
601 RemoveNonCryptohomeData(user_email
);
603 it
= users_
.erase(it
);
606 if ((*it
)->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT
)
607 prefs_users_update
->Append(new base::StringValue(user_email
));
614 NotifyUserListChanged();
617 void ChromeUserManagerImpl::GuestUserLoggedIn() {
618 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
619 ChromeUserManager::GuestUserLoggedIn();
621 // TODO(nkostylev): Add support for passing guest session cryptohome
622 // mount point. Legacy (--login-profile) value will be used for now.
623 // http://crosbug.com/230859
624 active_user_
->SetStubImage(
625 user_manager::UserImage(
626 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
627 IDR_PROFILE_PICTURE_LOADING
)),
628 user_manager::User::USER_IMAGE_INVALID
,
631 // Initializes wallpaper after active_user_ is set.
632 WallpaperManager::Get()->SetUserWallpaperNow(chromeos::login::kGuestUserName
);
635 void ChromeUserManagerImpl::RegularUserLoggedIn(const std::string
& user_id
) {
636 ChromeUserManager::RegularUserLoggedIn(user_id
);
638 if (IsCurrentUserNew())
639 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
641 GetUserImageManager(user_id
)->UserLoggedIn(IsCurrentUserNew(), false);
643 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
645 // Make sure that new data is persisted to Local State.
646 GetLocalState()->CommitPendingWrite();
649 void ChromeUserManagerImpl::RegularUserLoggedInAsEphemeral(
650 const std::string
& user_id
) {
651 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
652 ChromeUserManager::RegularUserLoggedInAsEphemeral(user_id
);
654 GetUserImageManager(user_id
)->UserLoggedIn(IsCurrentUserNew(), false);
655 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
658 void ChromeUserManagerImpl::SupervisedUserLoggedIn(const std::string
& user_id
) {
659 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
661 // Remove the user from the user list.
662 active_user_
= RemoveRegularOrSupervisedUserFromList(user_id
);
664 // If the user was not found on the user list, create a new user.
665 if (!GetActiveUser()) {
666 SetIsCurrentUserNew(true);
667 active_user_
= user_manager::User::CreateSupervisedUser(user_id
);
668 // Leaving OAuth token status at the default state = unknown.
669 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
671 if (supervised_user_manager_
->CheckForFirstRun(user_id
)) {
672 SetIsCurrentUserNew(true);
673 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
675 SetIsCurrentUserNew(false);
679 // Add the user to the front of the user list.
680 ListPrefUpdate
prefs_users_update(GetLocalState(), kRegularUsers
);
681 prefs_users_update
->Insert(0, new base::StringValue(user_id
));
682 users_
.insert(users_
.begin(), active_user_
);
684 // Now that user is in the list, save display name.
685 if (IsCurrentUserNew()) {
686 SaveUserDisplayName(GetActiveUser()->email(),
687 GetActiveUser()->GetDisplayName());
690 GetUserImageManager(user_id
)->UserLoggedIn(IsCurrentUserNew(), true);
691 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
693 // Make sure that new data is persisted to Local State.
694 GetLocalState()->CommitPendingWrite();
697 void ChromeUserManagerImpl::PublicAccountUserLoggedIn(
698 user_manager::User
* user
) {
699 SetIsCurrentUserNew(true);
702 // The UserImageManager chooses a random avatar picture when a user logs in
703 // for the first time. Tell the UserImageManager that this user is not new to
704 // prevent the avatar from getting changed.
705 GetUserImageManager(user
->email())->UserLoggedIn(false, true);
706 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
709 void ChromeUserManagerImpl::KioskAppLoggedIn(const std::string
& app_id
) {
710 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
711 policy::DeviceLocalAccount::Type device_local_account_type
;
712 DCHECK(policy::IsDeviceLocalAccountUser(app_id
, &device_local_account_type
));
713 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP
,
714 device_local_account_type
);
716 active_user_
= user_manager::User::CreateKioskAppUser(app_id
);
717 active_user_
->SetStubImage(
718 user_manager::UserImage(
719 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
720 IDR_PROFILE_PICTURE_LOADING
)),
721 user_manager::User::USER_IMAGE_INVALID
,
724 WallpaperManager::Get()->SetUserWallpaperNow(app_id
);
726 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
727 // the kiosk_app_id in these objects, removing the need to re-parse the
728 // device-local account list here to extract the kiosk_app_id.
729 const std::vector
<policy::DeviceLocalAccount
> device_local_accounts
=
730 policy::GetDeviceLocalAccounts(cros_settings_
);
731 const policy::DeviceLocalAccount
* account
= NULL
;
732 for (std::vector
<policy::DeviceLocalAccount
>::const_iterator it
=
733 device_local_accounts
.begin();
734 it
!= device_local_accounts
.end();
736 if (it
->user_id
== app_id
) {
741 std::string kiosk_app_id
;
743 kiosk_app_id
= account
->kiosk_app_id
;
745 LOG(ERROR
) << "Logged into nonexistent kiosk-app account: " << app_id
;
749 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
750 command_line
->AppendSwitch(::switches::kForceAppMode
);
751 command_line
->AppendSwitchASCII(::switches::kAppId
, kiosk_app_id
);
753 // Disable window animation since kiosk app runs in a single full screen
754 // window and window animation causes start-up janks.
755 command_line
->AppendSwitch(wm::switches::kWindowAnimationsDisabled
);
758 void ChromeUserManagerImpl::DemoAccountLoggedIn() {
759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
761 user_manager::User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName
);
762 active_user_
->SetStubImage(
763 user_manager::UserImage(
764 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
765 IDR_PROFILE_PICTURE_LOADING
)),
766 user_manager::User::USER_IMAGE_INVALID
,
768 WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName
);
770 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
771 command_line
->AppendSwitch(::switches::kForceAppMode
);
772 command_line
->AppendSwitchASCII(::switches::kAppId
,
773 DemoAppLauncher::kDemoAppId
);
775 // Disable window animation since the demo app runs in a single full screen
776 // window and window animation causes start-up janks.
777 base::CommandLine::ForCurrentProcess()->AppendSwitch(
778 wm::switches::kWindowAnimationsDisabled
);
781 void ChromeUserManagerImpl::NotifyOnLogin() {
782 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
784 UserSessionManager::OverrideHomedir();
785 UpdateNumberOfUsers();
787 ChromeUserManager::NotifyOnLogin();
789 // TODO(nkostylev): Deprecate this notification in favor of
790 // ActiveUserChanged() observer call.
791 content::NotificationService::current()->Notify(
792 chrome::NOTIFICATION_LOGIN_USER_CHANGED
,
793 content::Source
<UserManager
>(this),
794 content::Details
<const user_manager::User
>(GetActiveUser()));
796 UserSessionManager::GetInstance()->PerformPostUserLoggedInActions();
799 void ChromeUserManagerImpl::UpdateOwnership() {
800 bool is_owner
= DeviceSettingsService::Get()->HasPrivateOwnerKey();
801 VLOG(1) << "Current user " << (is_owner
? "is owner" : "is not owner");
803 SetCurrentUserIsOwner(is_owner
);
806 void ChromeUserManagerImpl::RemoveNonCryptohomeData(
807 const std::string
& user_id
) {
808 ChromeUserManager::RemoveNonCryptohomeData(user_id
);
810 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id
);
811 GetUserImageManager(user_id
)->DeleteUserImage();
813 supervised_user_manager_
->RemoveNonCryptohomeData(user_id
);
815 multi_profile_user_controller_
->RemoveCachedValues(user_id
);
817 EasyUnlockService::ResetLocalStateForUser(user_id
);
821 ChromeUserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
822 PrefService
* local_state
= GetLocalState();
823 const std::string public_account_pending_data_removal
=
824 local_state
->GetString(kPublicAccountPendingDataRemoval
);
825 if (public_account_pending_data_removal
.empty() ||
827 public_account_pending_data_removal
== GetActiveUser()->email())) {
831 RemoveNonCryptohomeData(public_account_pending_data_removal
);
832 local_state
->ClearPref(kPublicAccountPendingDataRemoval
);
835 void ChromeUserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
836 const std::vector
<std::string
>& old_public_accounts
) {
837 std::set
<std::string
> users
;
838 for (user_manager::UserList::const_iterator it
= users_
.begin();
841 users
.insert((*it
)->email());
843 // If the user is logged into a public account that has been removed from the
844 // user list, mark the account's data as pending removal after logout.
845 if (IsLoggedInAsPublicAccount()) {
846 const std::string active_user_id
= GetActiveUser()->email();
847 if (users
.find(active_user_id
) == users
.end()) {
848 GetLocalState()->SetString(kPublicAccountPendingDataRemoval
,
850 users
.insert(active_user_id
);
854 // Remove the data belonging to any other public accounts that are no longer
855 // found on the user list.
856 for (std::vector
<std::string
>::const_iterator it
=
857 old_public_accounts
.begin();
858 it
!= old_public_accounts
.end();
860 if (users
.find(*it
) == users
.end())
861 RemoveNonCryptohomeData(*it
);
865 bool ChromeUserManagerImpl::UpdateAndCleanUpPublicAccounts(
866 const std::vector
<policy::DeviceLocalAccount
>& device_local_accounts
) {
867 // Try to remove any public account data marked as pending removal.
868 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
870 // Get the current list of public accounts.
871 std::vector
<std::string
> old_public_accounts
;
872 for (user_manager::UserList::const_iterator it
= users_
.begin();
875 if ((*it
)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT
)
876 old_public_accounts
.push_back((*it
)->email());
879 // Get the new list of public accounts from policy.
880 std::vector
<std::string
> new_public_accounts
;
881 for (std::vector
<policy::DeviceLocalAccount
>::const_iterator it
=
882 device_local_accounts
.begin();
883 it
!= device_local_accounts
.end();
885 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
886 // standard login framework: http://crbug.com/234694
887 if (it
->type
== policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION
)
888 new_public_accounts
.push_back(it
->user_id
);
891 // If the list of public accounts has not changed, return.
892 if (new_public_accounts
.size() == old_public_accounts
.size()) {
893 bool changed
= false;
894 for (size_t i
= 0; i
< new_public_accounts
.size(); ++i
) {
895 if (new_public_accounts
[i
] != old_public_accounts
[i
]) {
904 // Persist the new list of public accounts in a pref.
905 ListPrefUpdate
prefs_public_accounts_update(GetLocalState(), kPublicAccounts
);
906 prefs_public_accounts_update
->Clear();
907 for (std::vector
<std::string
>::const_iterator it
=
908 new_public_accounts
.begin();
909 it
!= new_public_accounts
.end();
911 prefs_public_accounts_update
->AppendString(*it
);
914 // Remove the old public accounts from the user list.
915 for (user_manager::UserList::iterator it
= users_
.begin();
916 it
!= users_
.end();) {
917 if ((*it
)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT
) {
918 if (*it
!= GetLoggedInUser())
920 it
= users_
.erase(it
);
926 // Add the new public accounts to the front of the user list.
927 for (std::vector
<std::string
>::const_reverse_iterator it
=
928 new_public_accounts
.rbegin();
929 it
!= new_public_accounts
.rend();
931 if (IsLoggedInAsPublicAccount() && *it
== GetActiveUser()->email())
932 users_
.insert(users_
.begin(), GetLoggedInUser());
934 users_
.insert(users_
.begin(),
935 user_manager::User::CreatePublicAccountUser(*it
));
936 UpdatePublicAccountDisplayName(*it
);
939 for (user_manager::UserList::iterator
941 ue
= users_
.begin() + new_public_accounts
.size();
944 GetUserImageManager((*ui
)->email())->LoadUserImage();
947 // Remove data belonging to public accounts that are no longer found on the
949 CleanUpPublicAccountNonCryptohomeData(old_public_accounts
);
954 void ChromeUserManagerImpl::UpdatePublicAccountDisplayName(
955 const std::string
& user_id
) {
956 std::string display_name
;
958 if (device_local_account_policy_service_
) {
959 policy::DeviceLocalAccountPolicyBroker
* broker
=
960 device_local_account_policy_service_
->GetBrokerForUser(user_id
);
962 display_name
= broker
->GetDisplayName();
965 // Set or clear the display name.
966 SaveUserDisplayName(user_id
, base::UTF8ToUTF16(display_name
));
969 UserFlow
* ChromeUserManagerImpl::GetCurrentUserFlow() const {
970 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
971 if (!IsUserLoggedIn())
972 return GetDefaultUserFlow();
973 return GetUserFlow(GetLoggedInUser()->email());
976 UserFlow
* ChromeUserManagerImpl::GetUserFlow(const std::string
& user_id
) const {
977 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
978 FlowMap::const_iterator it
= specific_flows_
.find(user_id
);
979 if (it
!= specific_flows_
.end())
981 return GetDefaultUserFlow();
984 void ChromeUserManagerImpl::SetUserFlow(const std::string
& user_id
,
986 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
987 ResetUserFlow(user_id
);
988 specific_flows_
[user_id
] = flow
;
991 void ChromeUserManagerImpl::ResetUserFlow(const std::string
& user_id
) {
992 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
993 FlowMap::iterator it
= specific_flows_
.find(user_id
);
994 if (it
!= specific_flows_
.end()) {
996 specific_flows_
.erase(it
);
1000 bool ChromeUserManagerImpl::AreSupervisedUsersAllowed() const {
1001 bool supervised_users_allowed
= false;
1002 cros_settings_
->GetBoolean(kAccountsPrefSupervisedUsersEnabled
,
1003 &supervised_users_allowed
);
1004 return supervised_users_allowed
;
1007 UserFlow
* ChromeUserManagerImpl::GetDefaultUserFlow() const {
1008 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1009 if (!default_flow_
.get())
1010 default_flow_
.reset(new DefaultUserFlow());
1011 return default_flow_
.get();
1014 void ChromeUserManagerImpl::NotifyUserListChanged() {
1015 content::NotificationService::current()->Notify(
1016 chrome::NOTIFICATION_USER_LIST_CHANGED
,
1017 content::Source
<UserManager
>(this),
1018 content::NotificationService::NoDetails());
1021 void ChromeUserManagerImpl::NotifyUserAddedToSession(
1022 const user_manager::User
* added_user
,
1023 bool user_switch_pending
) {
1024 // Special case for user session restoration after browser crash.
1025 // We don't switch to each user session that has been restored as once all
1026 // session will be restored we'll switch to the session that has been used
1027 // before the crash.
1028 if (user_switch_pending
&&
1029 !UserSessionManager::GetInstance()->UserSessionsRestoreInProgress()) {
1030 SetPendingUserSwitchID(added_user
->email());
1033 UpdateNumberOfUsers();
1034 ChromeUserManager::NotifyUserAddedToSession(added_user
, user_switch_pending
);
1037 void ChromeUserManagerImpl::OnUserNotAllowed(const std::string
& user_email
) {
1038 LOG(ERROR
) << "Shutdown session because a user is not allowed to be in the "
1040 chromeos::ShowMultiprofilesSessionAbortedDialog(user_email
);
1043 void ChromeUserManagerImpl::UpdateNumberOfUsers() {
1044 size_t users
= GetLoggedInUsers().size();
1046 // Write the user number as UMA stat when a multi user session is possible.
1047 if ((users
+ GetUsersAllowedForMultiProfile().size()) > 1)
1048 ash::MultiProfileUMA::RecordUserCount(users
);
1051 base::debug::SetCrashKeyValue(
1052 crash_keys::kNumberOfUsers
,
1053 base::StringPrintf("%" PRIuS
, GetLoggedInUsers().size()));
1056 void ChromeUserManagerImpl::UpdateUserTimeZoneRefresher(Profile
* profile
) {
1057 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1058 chromeos::switches::kDisableTimeZoneTrackingOption
)) {
1062 const user_manager::User
* user
=
1063 ProfileHelper::Get()->GetUserByProfile(profile
);
1067 // In Multi-Profile mode only primary user settings are in effect.
1068 if (user
!= user_manager::UserManager::Get()->GetPrimaryUser())
1071 if (!IsUserLoggedIn())
1074 // Timezone auto refresh is disabled for Guest, Supervized and OffTheRecord
1075 // users, but enabled for Kiosk mode.
1076 if (IsLoggedInAsGuest() || IsLoggedInAsSupervisedUser() ||
1077 profile
->IsOffTheRecord()) {
1078 g_browser_process
->platform_part()->GetTimezoneResolver()->Stop();
1082 if (profile
->GetPrefs()->GetBoolean(prefs::kResolveTimezoneByGeolocation
) &&
1083 !system::HasSystemTimezonePolicy()) {
1084 g_browser_process
->platform_part()->GetTimezoneResolver()->Start();
1086 g_browser_process
->platform_part()->GetTimezoneResolver()->Stop();
1090 } // namespace chromeos