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/affiliation.h"
33 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h"
34 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
35 #include "chrome/browser/chromeos/login/users/supervised_user_manager_impl.h"
36 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
37 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
38 #include "chrome/browser/chromeos/policy/device_local_account.h"
39 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog.h"
40 #include "chrome/browser/chromeos/profiles/profile_helper.h"
41 #include "chrome/browser/chromeos/session_length_limiter.h"
42 #include "chrome/browser/chromeos/settings/cros_settings.h"
43 #include "chrome/browser/chromeos/system/timezone_util.h"
44 #include "chrome/browser/profiles/profile.h"
45 #include "chrome/browser/signin/easy_unlock_service.h"
46 #include "chrome/browser/supervised_user/chromeos/manager_password_service_factory.h"
47 #include "chrome/browser/supervised_user/chromeos/supervised_user_password_service_factory.h"
48 #include "chrome/common/chrome_constants.h"
49 #include "chrome/common/chrome_switches.h"
50 #include "chrome/common/crash_keys.h"
51 #include "chrome/common/pref_names.h"
52 #include "chrome/grit/theme_resources.h"
53 #include "chromeos/chromeos_switches.h"
54 #include "chromeos/login/user_names.h"
55 #include "chromeos/settings/cros_settings_names.h"
56 #include "chromeos/timezone/timezone_resolver.h"
57 #include "components/session_manager/core/session_manager.h"
58 #include "components/user_manager/remove_user_delegate.h"
59 #include "components/user_manager/user_image/user_image.h"
60 #include "components/user_manager/user_type.h"
61 #include "content/public/browser/browser_thread.h"
62 #include "content/public/browser/notification_service.h"
63 #include "policy/policy_constants.h"
64 #include "ui/base/resource/resource_bundle.h"
65 #include "ui/wm/core/wm_core_switches.h"
67 using content::BrowserThread
;
72 // A vector pref of the the regular users known on this device, arranged in LRU
74 const char kRegularUsers
[] = "LoggedInUsers";
76 // A vector pref of the public accounts defined on this device.
77 const char kPublicAccounts
[] = "PublicAccounts";
79 // Key for list of users that should be reported.
80 const char kReportingUsers
[] = "reporting_users";
82 // A string pref that gets set when a public account is removed but a user is
83 // currently logged into that account, requiring the account's data to be
84 // removed after logout.
85 const char kPublicAccountPendingDataRemoval
[] =
86 "PublicAccountPendingDataRemoval";
88 bool FakeOwnership() {
89 return base::CommandLine::ForCurrentProcess()->HasSwitch(
90 switches::kStubCrosSettings
);
93 std::string
FullyCanonicalize(const std::string
& email
) {
94 return gaia::CanonicalizeEmail(gaia::SanitizeEmail(email
));
100 void ChromeUserManagerImpl::RegisterPrefs(PrefRegistrySimple
* registry
) {
101 ChromeUserManager::RegisterPrefs(registry
);
103 registry
->RegisterListPref(kPublicAccounts
);
104 registry
->RegisterStringPref(kPublicAccountPendingDataRemoval
, std::string());
105 registry
->RegisterListPref(kReportingUsers
);
107 SupervisedUserManager::RegisterPrefs(registry
);
108 SessionLengthLimiter::RegisterPrefs(registry
);
109 BootstrapManager::RegisterPrefs(registry
);
113 scoped_ptr
<ChromeUserManager
> ChromeUserManagerImpl::CreateChromeUserManager() {
114 return scoped_ptr
<ChromeUserManager
>(new ChromeUserManagerImpl());
117 ChromeUserManagerImpl::ChromeUserManagerImpl()
118 : ChromeUserManager(base::ThreadTaskRunnerHandle::Get(),
119 BrowserThread::GetBlockingPool()),
120 cros_settings_(CrosSettings::Get()),
121 device_local_account_policy_service_(NULL
),
122 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
123 bootstrap_manager_(new BootstrapManager(this)),
124 weak_factory_(this) {
125 UpdateNumberOfUsers();
127 // UserManager instance should be used only on UI thread.
128 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
130 chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED
,
131 content::NotificationService::AllSources());
133 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED
,
134 content::NotificationService::AllSources());
136 chrome::NOTIFICATION_PROFILE_CREATED
,
137 content::NotificationService::AllSources());
139 // Since we're in ctor postpone any actions till this is fully created.
140 if (base::MessageLoop::current()) {
141 base::MessageLoop::current()->PostTask(
143 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies
,
144 weak_factory_
.GetWeakPtr()));
147 local_accounts_subscription_
= cros_settings_
->AddSettingsObserver(
148 kAccountsPrefDeviceLocalAccounts
,
149 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies
,
150 weak_factory_
.GetWeakPtr()));
151 multi_profile_user_controller_
.reset(
152 new MultiProfileUserController(this, GetLocalState()));
154 policy::BrowserPolicyConnectorChromeOS
* connector
=
155 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
156 avatar_policy_observer_
.reset(new policy::CloudExternalDataPolicyObserver(
158 connector
->GetDeviceLocalAccountPolicyService(),
159 policy::key::kUserAvatarImage
,
161 avatar_policy_observer_
->Init();
163 wallpaper_policy_observer_
.reset(new policy::CloudExternalDataPolicyObserver(
165 connector
->GetDeviceLocalAccountPolicyService(),
166 policy::key::kWallpaperImage
,
168 wallpaper_policy_observer_
->Init();
171 ChromeUserManagerImpl::~ChromeUserManagerImpl() {
174 void ChromeUserManagerImpl::Shutdown() {
175 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
176 ChromeUserManager::Shutdown();
178 local_accounts_subscription_
.reset();
180 // Stop the session length limiter.
181 session_length_limiter_
.reset();
183 if (device_local_account_policy_service_
)
184 device_local_account_policy_service_
->RemoveObserver(this);
186 for (UserImageManagerMap::iterator it
= user_image_managers_
.begin(),
187 ie
= user_image_managers_
.end();
190 it
->second
->Shutdown();
192 multi_profile_user_controller_
.reset();
193 avatar_policy_observer_
.reset();
194 wallpaper_policy_observer_
.reset();
195 registrar_
.RemoveAll();
198 BootstrapManager
* ChromeUserManagerImpl::GetBootstrapManager() {
199 return bootstrap_manager_
.get();
202 MultiProfileUserController
*
203 ChromeUserManagerImpl::GetMultiProfileUserController() {
204 return multi_profile_user_controller_
.get();
207 UserImageManager
* ChromeUserManagerImpl::GetUserImageManager(
208 const std::string
& user_id
) {
209 UserImageManagerMap::iterator ui
= user_image_managers_
.find(user_id
);
210 if (ui
!= user_image_managers_
.end())
211 return ui
->second
.get();
212 linked_ptr
<UserImageManagerImpl
> mgr(new UserImageManagerImpl(user_id
, this));
213 user_image_managers_
[user_id
] = mgr
;
217 SupervisedUserManager
* ChromeUserManagerImpl::GetSupervisedUserManager() {
218 return supervised_user_manager_
.get();
221 user_manager::UserList
ChromeUserManagerImpl::GetUsersAllowedForMultiProfile()
223 // Supervised users are not allowed to use multi-profiles.
224 if (GetLoggedInUsers().size() == 1 &&
225 GetPrimaryUser()->GetType() != user_manager::USER_TYPE_REGULAR
) {
226 return user_manager::UserList();
229 user_manager::UserList result
;
230 const user_manager::UserList
& users
= GetUsers();
231 for (user_manager::UserList::const_iterator it
= users
.begin();
234 if ((*it
)->GetType() == user_manager::USER_TYPE_REGULAR
&&
235 !(*it
)->is_logged_in()) {
236 MultiProfileUserController::UserAllowedInSessionReason check
;
237 multi_profile_user_controller_
->IsUserAllowedInSession((*it
)->email(),
240 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS
) {
241 return user_manager::UserList();
244 // Users with a policy that prevents them being added to a session will be
245 // shown in login UI but will be grayed out.
246 // Same applies to owner account (see http://crbug.com/385034).
247 result
.push_back(*it
);
254 user_manager::UserList
255 ChromeUserManagerImpl::GetUsersAllowedForSupervisedUsersCreation() const {
256 CrosSettings
* cros_settings
= CrosSettings::Get();
257 bool allow_new_user
= true;
258 cros_settings
->GetBoolean(kAccountsPrefAllowNewUser
, &allow_new_user
);
259 bool supervised_users_allowed
= AreSupervisedUsersAllowed();
261 // Restricted either by policy or by owner.
262 if (!allow_new_user
|| !supervised_users_allowed
)
263 return user_manager::UserList();
265 return GetUsersAllowedAsSupervisedUserManagers(GetUsers());
268 user_manager::UserList
ChromeUserManagerImpl::GetUnlockUsers() const {
269 const user_manager::UserList
& logged_in_users
= GetLoggedInUsers();
270 if (logged_in_users
.empty())
271 return user_manager::UserList();
273 user_manager::UserList unlock_users
;
275 ProfileHelper::Get()->GetProfileByUserUnsafe(GetPrimaryUser());
276 std::string primary_behavior
=
277 profile
->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior
);
279 // Specific case: only one logged in user or
280 // primary user has primary-only multi-profile policy.
281 if (logged_in_users
.size() == 1 ||
282 primary_behavior
== MultiProfileUserController::kBehaviorPrimaryOnly
) {
283 if (GetPrimaryUser()->can_lock())
284 unlock_users
.push_back(primary_user_
);
286 // Fill list of potential unlock users based on multi-profile policy state.
287 for (user_manager::UserList::const_iterator it
= logged_in_users
.begin();
288 it
!= logged_in_users
.end();
290 user_manager::User
* user
= (*it
);
291 Profile
* profile
= ProfileHelper::Get()->GetProfileByUserUnsafe(user
);
292 const std::string behavior
=
293 profile
->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior
);
294 if (behavior
== MultiProfileUserController::kBehaviorUnrestricted
&&
296 unlock_users
.push_back(user
);
297 } else if (behavior
== MultiProfileUserController::kBehaviorPrimaryOnly
) {
299 << "Spotted primary-only multi-profile policy for non-primary user";
307 void ChromeUserManagerImpl::SessionStarted() {
308 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
309 ChromeUserManager::SessionStarted();
311 content::NotificationService::current()->Notify(
312 chrome::NOTIFICATION_SESSION_STARTED
,
313 content::Source
<UserManager
>(this),
314 content::Details
<const user_manager::User
>(GetActiveUser()));
317 void ChromeUserManagerImpl::RemoveUserInternal(
318 const std::string
& user_email
,
319 user_manager::RemoveUserDelegate
* delegate
) {
320 CrosSettings
* cros_settings
= CrosSettings::Get();
322 const base::Closure
& callback
=
323 base::Bind(&ChromeUserManagerImpl::RemoveUserInternal
,
324 weak_factory_
.GetWeakPtr(),
328 // Ensure the value of owner email has been fetched.
329 if (CrosSettingsProvider::TRUSTED
!=
330 cros_settings
->PrepareTrustedValues(callback
)) {
331 // Value of owner email is not fetched yet. RemoveUserInternal will be
332 // called again after fetch completion.
336 cros_settings
->GetString(kDeviceOwner
, &owner
);
337 if (user_email
== owner
) {
338 // Owner is not allowed to be removed from the device.
341 RemoveNonOwnerUserInternal(user_email
, delegate
);
344 void ChromeUserManagerImpl::SaveUserOAuthStatus(
345 const std::string
& user_id
,
346 user_manager::User::OAuthTokenStatus oauth_token_status
) {
347 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
348 ChromeUserManager::SaveUserOAuthStatus(user_id
, oauth_token_status
);
350 GetUserFlow(user_id
)->HandleOAuthTokenStatusChange(oauth_token_status
);
353 void ChromeUserManagerImpl::SaveUserDisplayName(
354 const std::string
& user_id
,
355 const base::string16
& display_name
) {
356 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
357 ChromeUserManager::SaveUserDisplayName(user_id
, display_name
);
359 // Do not update local state if data stored or cached outside the user's
360 // cryptohome is to be treated as ephemeral.
361 if (!IsUserNonCryptohomeDataEphemeral(user_id
))
362 supervised_user_manager_
->UpdateManagerName(user_id
, display_name
);
365 void ChromeUserManagerImpl::StopPolicyObserverForTesting() {
366 avatar_policy_observer_
.reset();
367 wallpaper_policy_observer_
.reset();
370 void ChromeUserManagerImpl::Observe(
372 const content::NotificationSource
& source
,
373 const content::NotificationDetails
& details
) {
375 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED
:
376 if (!device_local_account_policy_service_
) {
377 policy::BrowserPolicyConnectorChromeOS
* connector
=
378 g_browser_process
->platform_part()
379 ->browser_policy_connector_chromeos();
380 device_local_account_policy_service_
=
381 connector
->GetDeviceLocalAccountPolicyService();
382 if (device_local_account_policy_service_
)
383 device_local_account_policy_service_
->AddObserver(this);
385 RetrieveTrustedDevicePolicies();
388 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED
: {
389 Profile
* profile
= content::Details
<Profile
>(details
).ptr();
390 if (IsUserLoggedIn() && !IsLoggedInAsGuest() && !IsLoggedInAsKioskApp()) {
391 if (IsLoggedInAsSupervisedUser())
392 SupervisedUserPasswordServiceFactory::GetForProfile(profile
);
393 if (IsLoggedInAsUserWithGaiaAccount())
394 ManagerPasswordServiceFactory::GetForProfile(profile
);
396 if (!profile
->IsOffTheRecord()) {
397 AuthSyncObserver
* sync_observer
=
398 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile
);
399 sync_observer
->StartObserving();
400 multi_profile_user_controller_
->StartObserving(profile
);
403 UpdateUserTimeZoneRefresher(profile
);
406 case chrome::NOTIFICATION_PROFILE_CREATED
: {
407 Profile
* profile
= content::Source
<Profile
>(source
).ptr();
408 user_manager::User
* user
=
409 ProfileHelper::Get()->GetUserByProfile(profile
);
411 user
->set_profile_is_created();
413 if (user
->HasGaiaAccount()) {
414 UserImageManager
* image_manager
= GetUserImageManager(user
->email());
415 image_manager
->UserProfileCreated();
419 // If there is pending user switch, do it now.
420 if (!GetPendingUserSwitchID().empty()) {
421 // Call SwitchActiveUser async because otherwise it may cause
422 // ProfileManager::GetProfile before the profile gets registered
423 // in ProfileManager. It happens in case of sync profile load when
424 // NOTIFICATION_PROFILE_CREATED is called synchronously.
425 base::MessageLoop::current()->PostTask(
427 base::Bind(&ChromeUserManagerImpl::SwitchActiveUser
,
428 weak_factory_
.GetWeakPtr(),
429 GetPendingUserSwitchID()));
430 SetPendingUserSwitchID(std::string());
439 void ChromeUserManagerImpl::OnExternalDataSet(const std::string
& policy
,
440 const std::string
& user_id
) {
441 if (policy
== policy::key::kUserAvatarImage
)
442 GetUserImageManager(user_id
)->OnExternalDataSet(policy
);
443 else if (policy
== policy::key::kWallpaperImage
)
444 WallpaperManager::Get()->OnPolicySet(policy
, user_id
);
449 void ChromeUserManagerImpl::OnExternalDataCleared(const std::string
& policy
,
450 const std::string
& user_id
) {
451 if (policy
== policy::key::kUserAvatarImage
)
452 GetUserImageManager(user_id
)->OnExternalDataCleared(policy
);
453 else if (policy
== policy::key::kWallpaperImage
)
454 WallpaperManager::Get()->OnPolicyCleared(policy
, user_id
);
459 void ChromeUserManagerImpl::OnExternalDataFetched(
460 const std::string
& policy
,
461 const std::string
& user_id
,
462 scoped_ptr
<std::string
> data
) {
463 if (policy
== policy::key::kUserAvatarImage
)
464 GetUserImageManager(user_id
)->OnExternalDataFetched(policy
, data
.Pass());
465 else if (policy
== policy::key::kWallpaperImage
)
466 WallpaperManager::Get()->OnPolicyFetched(policy
, user_id
, data
.Pass());
471 void ChromeUserManagerImpl::OnPolicyUpdated(const std::string
& user_id
) {
472 const user_manager::User
* user
= FindUser(user_id
);
473 if (!user
|| user
->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT
)
475 UpdatePublicAccountDisplayName(user_id
);
478 void ChromeUserManagerImpl::OnDeviceLocalAccountsChanged() {
479 // No action needed here, changes to the list of device-local accounts get
480 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
483 bool ChromeUserManagerImpl::CanCurrentUserLock() const {
484 return ChromeUserManager::CanCurrentUserLock() &&
485 GetCurrentUserFlow()->CanLockScreen();
488 bool ChromeUserManagerImpl::IsUserNonCryptohomeDataEphemeral(
489 const std::string
& user_id
) const {
490 // Data belonging to the obsolete public accounts whose data has not been
491 // removed yet is not ephemeral.
492 bool is_obsolete_public_account
= IsPublicAccountMarkedForRemoval(user_id
);
494 return !is_obsolete_public_account
&&
495 ChromeUserManager::IsUserNonCryptohomeDataEphemeral(user_id
);
498 bool ChromeUserManagerImpl::AreEphemeralUsersEnabled() const {
499 policy::BrowserPolicyConnectorChromeOS
* connector
=
500 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
501 return GetEphemeralUsersEnabled() &&
502 (connector
->IsEnterpriseManaged() || !GetOwnerEmail().empty());
505 void ChromeUserManagerImpl::OnUserRemoved(const std::string
& user_id
) {
506 RemoveReportingUser(FullyCanonicalize(user_id
));
509 const std::string
& ChromeUserManagerImpl::GetApplicationLocale() const {
510 return g_browser_process
->GetApplicationLocale();
513 PrefService
* ChromeUserManagerImpl::GetLocalState() const {
514 return g_browser_process
? g_browser_process
->local_state() : NULL
;
517 void ChromeUserManagerImpl::HandleUserOAuthTokenStatusChange(
518 const std::string
& user_id
,
519 user_manager::User::OAuthTokenStatus status
) const {
520 GetUserFlow(user_id
)->HandleOAuthTokenStatusChange(status
);
523 bool ChromeUserManagerImpl::IsEnterpriseManaged() const {
524 policy::BrowserPolicyConnectorChromeOS
* connector
=
525 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
526 return connector
->IsEnterpriseManaged();
529 void ChromeUserManagerImpl::LoadPublicAccounts(
530 std::set
<std::string
>* public_sessions_set
) {
531 const base::ListValue
* prefs_public_sessions
=
532 GetLocalState()->GetList(kPublicAccounts
);
533 std::vector
<std::string
> public_sessions
;
534 ParseUserList(*prefs_public_sessions
,
535 std::set
<std::string
>(),
537 public_sessions_set
);
538 for (std::vector
<std::string
>::const_iterator it
= public_sessions
.begin();
539 it
!= public_sessions
.end();
541 users_
.push_back(user_manager::User::CreatePublicAccountUser(*it
));
542 UpdatePublicAccountDisplayName(*it
);
546 void ChromeUserManagerImpl::PerformPreUserListLoadingActions() {
547 // Clean up user list first. All code down the path should be synchronous,
548 // so that local state after transaction rollback is in consistent state.
549 // This process also should not trigger EnsureUsersLoaded again.
550 if (supervised_user_manager_
->HasFailedUserCreationTransaction())
551 supervised_user_manager_
->RollbackUserCreationTransaction();
553 // Abandon all unfinished bootstraps.
554 bootstrap_manager_
->RemoveAllPendingBootstrap();
557 void ChromeUserManagerImpl::PerformPostUserListLoadingActions() {
558 for (user_manager::UserList::iterator ui
= users_
.begin(), ue
= users_
.end();
561 GetUserImageManager((*ui
)->email())->LoadUserImage();
565 void ChromeUserManagerImpl::PerformPostUserLoggedInActions(
566 bool browser_restart
) {
567 // Initialize the session length limiter and start it only if
568 // session limit is defined by the policy.
569 session_length_limiter_
.reset(
570 new SessionLengthLimiter(NULL
, browser_restart
));
573 bool ChromeUserManagerImpl::IsDemoApp(const std::string
& user_id
) const {
574 return DemoAppLauncher::IsDemoAppSession(user_id
);
577 bool ChromeUserManagerImpl::IsKioskApp(const std::string
& user_id
) const {
578 policy::DeviceLocalAccount::Type device_local_account_type
;
579 return policy::IsDeviceLocalAccountUser(user_id
,
580 &device_local_account_type
) &&
581 device_local_account_type
==
582 policy::DeviceLocalAccount::TYPE_KIOSK_APP
;
585 bool ChromeUserManagerImpl::IsPublicAccountMarkedForRemoval(
586 const std::string
& user_id
) const {
588 GetLocalState()->GetString(kPublicAccountPendingDataRemoval
);
591 void ChromeUserManagerImpl::RetrieveTrustedDevicePolicies() {
592 // Local state may not be initialized in unit_tests.
593 if (!GetLocalState())
596 SetEphemeralUsersEnabled(false);
597 SetOwnerEmail(std::string());
599 // Schedule a callback if device policy has not yet been verified.
600 if (CrosSettingsProvider::TRUSTED
!=
601 cros_settings_
->PrepareTrustedValues(
602 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies
,
603 weak_factory_
.GetWeakPtr()))) {
607 bool ephemeral_users_enabled
= false;
608 cros_settings_
->GetBoolean(kAccountsPrefEphemeralUsersEnabled
,
609 &ephemeral_users_enabled
);
610 SetEphemeralUsersEnabled(ephemeral_users_enabled
);
612 std::string owner_email
;
613 cros_settings_
->GetString(kDeviceOwner
, &owner_email
);
614 SetOwnerEmail(owner_email
);
618 bool changed
= UpdateAndCleanUpPublicAccounts(
619 policy::GetDeviceLocalAccounts(cros_settings_
));
621 // If ephemeral users are enabled and we are on the login screen, take this
622 // opportunity to clean up by removing all regular users except the owner.
623 if (GetEphemeralUsersEnabled() && !IsUserLoggedIn()) {
624 ListPrefUpdate
prefs_users_update(GetLocalState(), kRegularUsers
);
625 prefs_users_update
->Clear();
626 for (user_manager::UserList::iterator it
= users_
.begin();
627 it
!= users_
.end();) {
628 const std::string user_email
= (*it
)->email();
629 if ((*it
)->HasGaiaAccount() && user_email
!= GetOwnerEmail()) {
630 RemoveNonCryptohomeData(user_email
);
632 it
= users_
.erase(it
);
635 if ((*it
)->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT
)
636 prefs_users_update
->Append(new base::StringValue(user_email
));
643 NotifyUserListChanged();
646 void ChromeUserManagerImpl::GuestUserLoggedIn() {
647 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
648 ChromeUserManager::GuestUserLoggedIn();
650 // TODO(nkostylev): Add support for passing guest session cryptohome
651 // mount point. Legacy (--login-profile) value will be used for now.
652 // http://crosbug.com/230859
653 active_user_
->SetStubImage(
654 user_manager::UserImage(
655 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
656 IDR_PROFILE_PICTURE_LOADING
)),
657 user_manager::User::USER_IMAGE_INVALID
,
660 // Initializes wallpaper after active_user_ is set.
661 WallpaperManager::Get()->SetUserWallpaperNow(chromeos::login::kGuestUserName
);
664 void ChromeUserManagerImpl::RegularUserLoggedIn(const std::string
& user_id
) {
665 ChromeUserManager::RegularUserLoggedIn(user_id
);
667 if (FakeOwnership()) {
668 std::string owner_email
= GetActiveUser()->email();
669 VLOG(1) << "Set device owner to: " << owner_email
;
670 CrosSettings::Get()->SetString(kDeviceOwner
, owner_email
);
671 SetOwnerEmail(owner_email
);
674 if (IsCurrentUserNew())
675 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
677 GetUserImageManager(user_id
)->UserLoggedIn(IsCurrentUserNew(), false);
679 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
681 // Make sure that new data is persisted to Local State.
682 GetLocalState()->CommitPendingWrite();
685 void ChromeUserManagerImpl::RegularUserLoggedInAsEphemeral(
686 const std::string
& user_id
) {
687 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
688 ChromeUserManager::RegularUserLoggedInAsEphemeral(user_id
);
690 GetUserImageManager(user_id
)->UserLoggedIn(IsCurrentUserNew(), false);
691 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
694 void ChromeUserManagerImpl::SupervisedUserLoggedIn(const std::string
& user_id
) {
695 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
697 // Remove the user from the user list.
698 active_user_
= RemoveRegularOrSupervisedUserFromList(user_id
);
700 // If the user was not found on the user list, create a new user.
701 if (!GetActiveUser()) {
702 SetIsCurrentUserNew(true);
703 active_user_
= user_manager::User::CreateSupervisedUser(user_id
);
704 // Leaving OAuth token status at the default state = unknown.
705 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
707 if (supervised_user_manager_
->CheckForFirstRun(user_id
)) {
708 SetIsCurrentUserNew(true);
709 WallpaperManager::Get()->SetUserWallpaperNow(user_id
);
711 SetIsCurrentUserNew(false);
715 // Add the user to the front of the user list.
716 ListPrefUpdate
prefs_users_update(GetLocalState(), kRegularUsers
);
717 prefs_users_update
->Insert(0, new base::StringValue(user_id
));
718 users_
.insert(users_
.begin(), active_user_
);
720 // Now that user is in the list, save display name.
721 if (IsCurrentUserNew()) {
722 SaveUserDisplayName(GetActiveUser()->email(),
723 GetActiveUser()->GetDisplayName());
726 GetUserImageManager(user_id
)->UserLoggedIn(IsCurrentUserNew(), true);
727 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
729 // Make sure that new data is persisted to Local State.
730 GetLocalState()->CommitPendingWrite();
733 bool ChromeUserManagerImpl::HasPendingBootstrap(
734 const std::string
& user_id
) const {
735 return bootstrap_manager_
->HasPendingBootstrap(user_id
);
738 void ChromeUserManagerImpl::PublicAccountUserLoggedIn(
739 user_manager::User
* user
) {
740 SetIsCurrentUserNew(true);
743 // The UserImageManager chooses a random avatar picture when a user logs in
744 // for the first time. Tell the UserImageManager that this user is not new to
745 // prevent the avatar from getting changed.
746 GetUserImageManager(user
->email())->UserLoggedIn(false, true);
747 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
750 void ChromeUserManagerImpl::KioskAppLoggedIn(const std::string
& app_id
) {
751 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
752 policy::DeviceLocalAccount::Type device_local_account_type
;
753 DCHECK(policy::IsDeviceLocalAccountUser(app_id
, &device_local_account_type
));
754 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP
,
755 device_local_account_type
);
757 active_user_
= user_manager::User::CreateKioskAppUser(app_id
);
758 active_user_
->SetStubImage(
759 user_manager::UserImage(
760 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
761 IDR_PROFILE_PICTURE_LOADING
)),
762 user_manager::User::USER_IMAGE_INVALID
,
765 WallpaperManager::Get()->SetUserWallpaperNow(app_id
);
767 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
768 // the kiosk_app_id in these objects, removing the need to re-parse the
769 // device-local account list here to extract the kiosk_app_id.
770 const std::vector
<policy::DeviceLocalAccount
> device_local_accounts
=
771 policy::GetDeviceLocalAccounts(cros_settings_
);
772 const policy::DeviceLocalAccount
* account
= NULL
;
773 for (std::vector
<policy::DeviceLocalAccount
>::const_iterator it
=
774 device_local_accounts
.begin();
775 it
!= device_local_accounts
.end();
777 if (it
->user_id
== app_id
) {
782 std::string kiosk_app_id
;
784 kiosk_app_id
= account
->kiosk_app_id
;
786 LOG(ERROR
) << "Logged into nonexistent kiosk-app account: " << app_id
;
790 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
791 command_line
->AppendSwitch(::switches::kForceAppMode
);
792 command_line
->AppendSwitchASCII(::switches::kAppId
, kiosk_app_id
);
794 // Disable window animation since kiosk app runs in a single full screen
795 // window and window animation causes start-up janks.
796 command_line
->AppendSwitch(wm::switches::kWindowAnimationsDisabled
);
799 void ChromeUserManagerImpl::DemoAccountLoggedIn() {
800 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
802 user_manager::User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName
);
803 active_user_
->SetStubImage(
804 user_manager::UserImage(
805 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
806 IDR_PROFILE_PICTURE_LOADING
)),
807 user_manager::User::USER_IMAGE_INVALID
,
809 WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName
);
811 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
812 command_line
->AppendSwitch(::switches::kForceAppMode
);
813 command_line
->AppendSwitchASCII(::switches::kAppId
,
814 DemoAppLauncher::kDemoAppId
);
816 // Disable window animation since the demo app runs in a single full screen
817 // window and window animation causes start-up janks.
818 base::CommandLine::ForCurrentProcess()->AppendSwitch(
819 wm::switches::kWindowAnimationsDisabled
);
822 void ChromeUserManagerImpl::NotifyOnLogin() {
823 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
825 UserSessionManager::OverrideHomedir();
826 UpdateNumberOfUsers();
828 ChromeUserManager::NotifyOnLogin();
830 // TODO(nkostylev): Deprecate this notification in favor of
831 // ActiveUserChanged() observer call.
832 content::NotificationService::current()->Notify(
833 chrome::NOTIFICATION_LOGIN_USER_CHANGED
,
834 content::Source
<UserManager
>(this),
835 content::Details
<const user_manager::User
>(GetActiveUser()));
837 UserSessionManager::GetInstance()->PerformPostUserLoggedInActions();
840 void ChromeUserManagerImpl::UpdateOwnership() {
842 FakeOwnership() || DeviceSettingsService::Get()->HasPrivateOwnerKey();
843 VLOG(1) << "Current user " << (is_owner
? "is owner" : "is not owner");
845 SetCurrentUserIsOwner(is_owner
);
848 void ChromeUserManagerImpl::RemoveNonCryptohomeData(
849 const std::string
& user_id
) {
850 ChromeUserManager::RemoveNonCryptohomeData(user_id
);
852 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id
);
853 GetUserImageManager(user_id
)->DeleteUserImage();
855 supervised_user_manager_
->RemoveNonCryptohomeData(user_id
);
857 multi_profile_user_controller_
->RemoveCachedValues(user_id
);
859 EasyUnlockService::ResetLocalStateForUser(user_id
);
863 ChromeUserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
864 PrefService
* local_state
= GetLocalState();
865 const std::string public_account_pending_data_removal
=
866 local_state
->GetString(kPublicAccountPendingDataRemoval
);
867 if (public_account_pending_data_removal
.empty() ||
869 public_account_pending_data_removal
== GetActiveUser()->email())) {
873 RemoveNonCryptohomeData(public_account_pending_data_removal
);
874 local_state
->ClearPref(kPublicAccountPendingDataRemoval
);
877 void ChromeUserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
878 const std::vector
<std::string
>& old_public_accounts
) {
879 std::set
<std::string
> users
;
880 for (user_manager::UserList::const_iterator it
= users_
.begin();
883 users
.insert((*it
)->email());
885 // If the user is logged into a public account that has been removed from the
886 // user list, mark the account's data as pending removal after logout.
887 if (IsLoggedInAsPublicAccount()) {
888 const std::string active_user_id
= GetActiveUser()->email();
889 if (users
.find(active_user_id
) == users
.end()) {
890 GetLocalState()->SetString(kPublicAccountPendingDataRemoval
,
892 users
.insert(active_user_id
);
896 // Remove the data belonging to any other public accounts that are no longer
897 // found on the user list.
898 for (std::vector
<std::string
>::const_iterator it
=
899 old_public_accounts
.begin();
900 it
!= old_public_accounts
.end();
902 if (users
.find(*it
) == users
.end())
903 RemoveNonCryptohomeData(*it
);
907 bool ChromeUserManagerImpl::UpdateAndCleanUpPublicAccounts(
908 const std::vector
<policy::DeviceLocalAccount
>& device_local_accounts
) {
909 // Try to remove any public account data marked as pending removal.
910 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
912 // Get the current list of public accounts.
913 std::vector
<std::string
> old_public_accounts
;
914 for (user_manager::UserList::const_iterator it
= users_
.begin();
917 if ((*it
)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT
)
918 old_public_accounts
.push_back((*it
)->email());
921 // Get the new list of public accounts from policy.
922 std::vector
<std::string
> new_public_accounts
;
923 for (std::vector
<policy::DeviceLocalAccount
>::const_iterator it
=
924 device_local_accounts
.begin();
925 it
!= device_local_accounts
.end();
927 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
928 // standard login framework: http://crbug.com/234694
929 if (it
->type
== policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION
)
930 new_public_accounts
.push_back(it
->user_id
);
933 // If the list of public accounts has not changed, return.
934 if (new_public_accounts
.size() == old_public_accounts
.size()) {
935 bool changed
= false;
936 for (size_t i
= 0; i
< new_public_accounts
.size(); ++i
) {
937 if (new_public_accounts
[i
] != old_public_accounts
[i
]) {
946 // Persist the new list of public accounts in a pref.
947 ListPrefUpdate
prefs_public_accounts_update(GetLocalState(), kPublicAccounts
);
948 prefs_public_accounts_update
->Clear();
949 for (std::vector
<std::string
>::const_iterator it
=
950 new_public_accounts
.begin();
951 it
!= new_public_accounts
.end();
953 prefs_public_accounts_update
->AppendString(*it
);
956 // Remove the old public accounts from the user list.
957 for (user_manager::UserList::iterator it
= users_
.begin();
958 it
!= users_
.end();) {
959 if ((*it
)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT
) {
960 if (*it
!= GetLoggedInUser())
962 it
= users_
.erase(it
);
968 // Add the new public accounts to the front of the user list.
969 for (std::vector
<std::string
>::const_reverse_iterator it
=
970 new_public_accounts
.rbegin();
971 it
!= new_public_accounts
.rend();
973 if (IsLoggedInAsPublicAccount() && *it
== GetActiveUser()->email())
974 users_
.insert(users_
.begin(), GetLoggedInUser());
976 users_
.insert(users_
.begin(),
977 user_manager::User::CreatePublicAccountUser(*it
));
978 UpdatePublicAccountDisplayName(*it
);
981 for (user_manager::UserList::iterator
983 ue
= users_
.begin() + new_public_accounts
.size();
986 GetUserImageManager((*ui
)->email())->LoadUserImage();
989 // Remove data belonging to public accounts that are no longer found on the
991 CleanUpPublicAccountNonCryptohomeData(old_public_accounts
);
996 void ChromeUserManagerImpl::UpdatePublicAccountDisplayName(
997 const std::string
& user_id
) {
998 std::string display_name
;
1000 if (device_local_account_policy_service_
) {
1001 policy::DeviceLocalAccountPolicyBroker
* broker
=
1002 device_local_account_policy_service_
->GetBrokerForUser(user_id
);
1004 display_name
= broker
->GetDisplayName();
1007 // Set or clear the display name.
1008 SaveUserDisplayName(user_id
, base::UTF8ToUTF16(display_name
));
1011 UserFlow
* ChromeUserManagerImpl::GetCurrentUserFlow() const {
1012 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
1013 if (!IsUserLoggedIn())
1014 return GetDefaultUserFlow();
1015 return GetUserFlow(GetLoggedInUser()->email());
1018 UserFlow
* ChromeUserManagerImpl::GetUserFlow(const std::string
& user_id
) const {
1019 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
1020 FlowMap::const_iterator it
= specific_flows_
.find(user_id
);
1021 if (it
!= specific_flows_
.end())
1023 return GetDefaultUserFlow();
1026 void ChromeUserManagerImpl::SetUserFlow(const std::string
& user_id
,
1028 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
1029 ResetUserFlow(user_id
);
1030 specific_flows_
[user_id
] = flow
;
1033 void ChromeUserManagerImpl::ResetUserFlow(const std::string
& user_id
) {
1034 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
1035 FlowMap::iterator it
= specific_flows_
.find(user_id
);
1036 if (it
!= specific_flows_
.end()) {
1038 specific_flows_
.erase(it
);
1042 bool ChromeUserManagerImpl::AreSupervisedUsersAllowed() const {
1043 bool supervised_users_allowed
= false;
1044 cros_settings_
->GetBoolean(kAccountsPrefSupervisedUsersEnabled
,
1045 &supervised_users_allowed
);
1046 return supervised_users_allowed
;
1049 UserFlow
* ChromeUserManagerImpl::GetDefaultUserFlow() const {
1050 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
1051 if (!default_flow_
.get())
1052 default_flow_
.reset(new DefaultUserFlow());
1053 return default_flow_
.get();
1056 void ChromeUserManagerImpl::NotifyUserListChanged() {
1057 content::NotificationService::current()->Notify(
1058 chrome::NOTIFICATION_USER_LIST_CHANGED
,
1059 content::Source
<UserManager
>(this),
1060 content::NotificationService::NoDetails());
1063 void ChromeUserManagerImpl::NotifyUserAddedToSession(
1064 const user_manager::User
* added_user
,
1065 bool user_switch_pending
) {
1066 // Special case for user session restoration after browser crash.
1067 // We don't switch to each user session that has been restored as once all
1068 // session will be restored we'll switch to the session that has been used
1069 // before the crash.
1070 if (user_switch_pending
&&
1071 !UserSessionManager::GetInstance()->UserSessionsRestoreInProgress()) {
1072 SetPendingUserSwitchID(added_user
->email());
1075 UpdateNumberOfUsers();
1076 ChromeUserManager::NotifyUserAddedToSession(added_user
, user_switch_pending
);
1079 void ChromeUserManagerImpl::OnUserNotAllowed(const std::string
& user_email
) {
1080 LOG(ERROR
) << "Shutdown session because a user is not allowed to be in the "
1082 chromeos::ShowMultiprofilesSessionAbortedDialog(user_email
);
1085 void ChromeUserManagerImpl::RemovePendingBootstrapUser(
1086 const std::string
& user_id
) {
1087 DCHECK(HasPendingBootstrap(user_id
));
1088 RemoveNonOwnerUserInternal(user_id
, NULL
);
1091 void ChromeUserManagerImpl::UpdateNumberOfUsers() {
1092 size_t users
= GetLoggedInUsers().size();
1094 // Write the user number as UMA stat when a multi user session is possible.
1095 if ((users
+ GetUsersAllowedForMultiProfile().size()) > 1)
1096 ash::MultiProfileUMA::RecordUserCount(users
);
1099 base::debug::SetCrashKeyValue(
1100 crash_keys::kNumberOfUsers
,
1101 base::StringPrintf("%" PRIuS
, GetLoggedInUsers().size()));
1104 void ChromeUserManagerImpl::UpdateUserTimeZoneRefresher(Profile
* profile
) {
1105 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1106 chromeos::switches::kDisableTimeZoneTrackingOption
)) {
1110 const user_manager::User
* user
=
1111 ProfileHelper::Get()->GetUserByProfile(profile
);
1115 // In Multi-Profile mode only primary user settings are in effect.
1116 if (user
!= user_manager::UserManager::Get()->GetPrimaryUser())
1119 if (!IsUserLoggedIn())
1122 // Timezone auto refresh is disabled for Guest, Supervized and OffTheRecord
1123 // users, but enabled for Kiosk mode.
1124 if (IsLoggedInAsGuest() || IsLoggedInAsSupervisedUser() ||
1125 profile
->IsOffTheRecord()) {
1126 g_browser_process
->platform_part()->GetTimezoneResolver()->Stop();
1130 if (profile
->GetPrefs()->GetBoolean(prefs::kResolveTimezoneByGeolocation
) &&
1131 !system::HasSystemTimezonePolicy()) {
1132 g_browser_process
->platform_part()->GetTimezoneResolver()->Start();
1134 g_browser_process
->platform_part()->GetTimezoneResolver()->Stop();
1138 void ChromeUserManagerImpl::SetUserAffiliation(
1139 const std::string
& user_email
,
1140 const AffiliationIDSet
& user_affiliation_ids
) {
1141 std::string canonicalized_email
= FullyCanonicalize(user_email
);
1142 user_manager::User
* user
= FindUserAndModify(canonicalized_email
);
1145 policy::BrowserPolicyConnectorChromeOS
const* const connector
=
1146 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
1147 const bool is_affiliated
= chromeos::IsUserAffiliated(
1148 user_affiliation_ids
, connector
->GetDeviceAffiliationIDs(),
1149 canonicalized_email
, connector
->GetEnterpriseDomain());
1150 user
->set_affiliation(is_affiliated
);
1152 if (user
->GetType() == user_manager::USER_TYPE_REGULAR
) {
1153 if (is_affiliated
) {
1154 AddReportingUser(canonicalized_email
);
1156 RemoveReportingUser(canonicalized_email
);
1162 bool ChromeUserManagerImpl::ShouldReportUser(const std::string
& user_id
) const {
1163 const base::ListValue
& reporting_users
=
1164 *(GetLocalState()->GetList(kReportingUsers
));
1165 base::StringValue
user_id_value(FullyCanonicalize(user_id
));
1166 return !(reporting_users
.Find(user_id_value
) == reporting_users
.end());
1169 void ChromeUserManagerImpl::AddReportingUser(const std::string
& user_id
) {
1170 ListPrefUpdate
users_update(GetLocalState(), kReportingUsers
);
1171 users_update
->AppendIfNotPresent(
1172 new base::StringValue(FullyCanonicalize(user_id
)));
1175 void ChromeUserManagerImpl::RemoveReportingUser(const std::string
& user_id
) {
1176 ListPrefUpdate
users_update(GetLocalState(), kReportingUsers
);
1177 users_update
->Remove(base::StringValue(FullyCanonicalize(user_id
)), NULL
);
1180 } // namespace chromeos