Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / chromeos / login / users / chrome_user_manager_impl.cc
blob6cdf4b8b7590d1bf93e697480f119cf4516a0d63
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"
7 #include <cstddef>
8 #include <set>
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/settings/cros_settings.h"
42 #include "chrome/browser/chromeos/system/timezone_util.h"
43 #include "chrome/browser/profiles/profile.h"
44 #include "chrome/browser/signin/easy_unlock_service.h"
45 #include "chrome/browser/supervised_user/chromeos/manager_password_service_factory.h"
46 #include "chrome/browser/supervised_user/chromeos/supervised_user_password_service_factory.h"
47 #include "chrome/common/chrome_constants.h"
48 #include "chrome/common/chrome_switches.h"
49 #include "chrome/common/crash_keys.h"
50 #include "chrome/common/pref_names.h"
51 #include "chrome/grit/theme_resources.h"
52 #include "chromeos/chromeos_switches.h"
53 #include "chromeos/login/user_names.h"
54 #include "chromeos/settings/cros_settings_names.h"
55 #include "chromeos/timezone/timezone_resolver.h"
56 #include "components/session_manager/core/session_manager.h"
57 #include "components/user_manager/remove_user_delegate.h"
58 #include "components/user_manager/user_image/user_image.h"
59 #include "components/user_manager/user_type.h"
60 #include "content/public/browser/browser_thread.h"
61 #include "content/public/browser/notification_service.h"
62 #include "policy/policy_constants.h"
63 #include "ui/base/resource/resource_bundle.h"
64 #include "ui/wm/core/wm_core_switches.h"
66 using content::BrowserThread;
68 namespace chromeos {
69 namespace {
71 // A vector pref of the the regular users known on this device, arranged in LRU
72 // order.
73 const char kRegularUsers[] = "LoggedInUsers";
75 // A vector pref of the public accounts defined on this device.
76 const char kPublicAccounts[] = "PublicAccounts";
78 // A string pref that gets set when a public account is removed but a user is
79 // currently logged into that account, requiring the account's data to be
80 // removed after logout.
81 const char kPublicAccountPendingDataRemoval[] =
82 "PublicAccountPendingDataRemoval";
84 bool FakeOwnership() {
85 return base::CommandLine::ForCurrentProcess()->HasSwitch(
86 switches::kStubCrosSettings);
89 } // namespace
91 // static
92 void ChromeUserManagerImpl::RegisterPrefs(PrefRegistrySimple* registry) {
93 ChromeUserManager::RegisterPrefs(registry);
95 registry->RegisterListPref(kPublicAccounts);
96 registry->RegisterStringPref(kPublicAccountPendingDataRemoval, std::string());
97 SupervisedUserManager::RegisterPrefs(registry);
98 SessionLengthLimiter::RegisterPrefs(registry);
99 BootstrapManager::RegisterPrefs(registry);
102 // static
103 scoped_ptr<ChromeUserManager> ChromeUserManagerImpl::CreateChromeUserManager() {
104 return scoped_ptr<ChromeUserManager>(new ChromeUserManagerImpl());
107 ChromeUserManagerImpl::ChromeUserManagerImpl()
108 : ChromeUserManager(base::ThreadTaskRunnerHandle::Get(),
109 BrowserThread::GetBlockingPool()),
110 cros_settings_(CrosSettings::Get()),
111 device_local_account_policy_service_(NULL),
112 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
113 bootstrap_manager_(new BootstrapManager(this)),
114 weak_factory_(this) {
115 UpdateNumberOfUsers();
117 // UserManager instance should be used only on UI thread.
118 DCHECK_CURRENTLY_ON(BrowserThread::UI);
119 registrar_.Add(this,
120 chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
121 content::NotificationService::AllSources());
122 registrar_.Add(this,
123 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
124 content::NotificationService::AllSources());
125 registrar_.Add(this,
126 chrome::NOTIFICATION_PROFILE_CREATED,
127 content::NotificationService::AllSources());
129 // Since we're in ctor postpone any actions till this is fully created.
130 if (base::MessageLoop::current()) {
131 base::MessageLoop::current()->PostTask(
132 FROM_HERE,
133 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies,
134 weak_factory_.GetWeakPtr()));
137 local_accounts_subscription_ = cros_settings_->AddSettingsObserver(
138 kAccountsPrefDeviceLocalAccounts,
139 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies,
140 weak_factory_.GetWeakPtr()));
141 multi_profile_user_controller_.reset(
142 new MultiProfileUserController(this, GetLocalState()));
144 policy::BrowserPolicyConnectorChromeOS* connector =
145 g_browser_process->platform_part()->browser_policy_connector_chromeos();
146 avatar_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
147 cros_settings_,
148 connector->GetDeviceLocalAccountPolicyService(),
149 policy::key::kUserAvatarImage,
150 this));
151 avatar_policy_observer_->Init();
153 wallpaper_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
154 cros_settings_,
155 connector->GetDeviceLocalAccountPolicyService(),
156 policy::key::kWallpaperImage,
157 this));
158 wallpaper_policy_observer_->Init();
161 ChromeUserManagerImpl::~ChromeUserManagerImpl() {
164 void ChromeUserManagerImpl::Shutdown() {
165 DCHECK_CURRENTLY_ON(BrowserThread::UI);
166 ChromeUserManager::Shutdown();
168 local_accounts_subscription_.reset();
170 // Stop the session length limiter.
171 session_length_limiter_.reset();
173 if (device_local_account_policy_service_)
174 device_local_account_policy_service_->RemoveObserver(this);
176 for (UserImageManagerMap::iterator it = user_image_managers_.begin(),
177 ie = user_image_managers_.end();
178 it != ie;
179 ++it) {
180 it->second->Shutdown();
182 multi_profile_user_controller_.reset();
183 avatar_policy_observer_.reset();
184 wallpaper_policy_observer_.reset();
185 registrar_.RemoveAll();
188 BootstrapManager* ChromeUserManagerImpl::GetBootstrapManager() {
189 return bootstrap_manager_.get();
192 MultiProfileUserController*
193 ChromeUserManagerImpl::GetMultiProfileUserController() {
194 return multi_profile_user_controller_.get();
197 UserImageManager* ChromeUserManagerImpl::GetUserImageManager(
198 const std::string& user_id) {
199 UserImageManagerMap::iterator ui = user_image_managers_.find(user_id);
200 if (ui != user_image_managers_.end())
201 return ui->second.get();
202 linked_ptr<UserImageManagerImpl> mgr(new UserImageManagerImpl(user_id, this));
203 user_image_managers_[user_id] = mgr;
204 return mgr.get();
207 SupervisedUserManager* ChromeUserManagerImpl::GetSupervisedUserManager() {
208 return supervised_user_manager_.get();
211 user_manager::UserList ChromeUserManagerImpl::GetUsersAllowedForMultiProfile()
212 const {
213 // Supervised users are not allowed to use multi-profiles.
214 if (GetLoggedInUsers().size() == 1 &&
215 GetPrimaryUser()->GetType() != user_manager::USER_TYPE_REGULAR) {
216 return user_manager::UserList();
219 user_manager::UserList result;
220 const user_manager::UserList& users = GetUsers();
221 for (user_manager::UserList::const_iterator it = users.begin();
222 it != users.end();
223 ++it) {
224 if ((*it)->GetType() == user_manager::USER_TYPE_REGULAR &&
225 !(*it)->is_logged_in()) {
226 MultiProfileUserController::UserAllowedInSessionReason check;
227 multi_profile_user_controller_->IsUserAllowedInSession((*it)->email(),
228 &check);
229 if (check ==
230 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS) {
231 return user_manager::UserList();
234 // Users with a policy that prevents them being added to a session will be
235 // shown in login UI but will be grayed out.
236 // Same applies to owner account (see http://crbug.com/385034).
237 result.push_back(*it);
241 return result;
244 user_manager::UserList
245 ChromeUserManagerImpl::GetUsersAllowedForSupervisedUsersCreation() const {
246 CrosSettings* cros_settings = CrosSettings::Get();
247 bool allow_new_user = true;
248 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user);
249 bool supervised_users_allowed = AreSupervisedUsersAllowed();
251 // Restricted either by policy or by owner.
252 if (!allow_new_user || !supervised_users_allowed)
253 return user_manager::UserList();
255 return GetUsersAllowedAsSupervisedUserManagers(GetUsers());
258 user_manager::UserList ChromeUserManagerImpl::GetUnlockUsers() const {
259 const user_manager::UserList& logged_in_users = GetLoggedInUsers();
260 if (logged_in_users.empty())
261 return user_manager::UserList();
263 user_manager::UserList unlock_users;
264 Profile* profile =
265 ProfileHelper::Get()->GetProfileByUserUnsafe(GetPrimaryUser());
266 std::string primary_behavior =
267 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
269 // Specific case: only one logged in user or
270 // primary user has primary-only multi-profile policy.
271 if (logged_in_users.size() == 1 ||
272 primary_behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
273 if (GetPrimaryUser()->can_lock())
274 unlock_users.push_back(primary_user_);
275 } else {
276 // Fill list of potential unlock users based on multi-profile policy state.
277 for (user_manager::UserList::const_iterator it = logged_in_users.begin();
278 it != logged_in_users.end();
279 ++it) {
280 user_manager::User* user = (*it);
281 Profile* profile = ProfileHelper::Get()->GetProfileByUserUnsafe(user);
282 const std::string behavior =
283 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
284 if (behavior == MultiProfileUserController::kBehaviorUnrestricted &&
285 user->can_lock()) {
286 unlock_users.push_back(user);
287 } else if (behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
288 NOTREACHED()
289 << "Spotted primary-only multi-profile policy for non-primary user";
294 return unlock_users;
297 void ChromeUserManagerImpl::SessionStarted() {
298 DCHECK_CURRENTLY_ON(BrowserThread::UI);
299 ChromeUserManager::SessionStarted();
301 content::NotificationService::current()->Notify(
302 chrome::NOTIFICATION_SESSION_STARTED,
303 content::Source<UserManager>(this),
304 content::Details<const user_manager::User>(GetActiveUser()));
307 void ChromeUserManagerImpl::RemoveUserInternal(
308 const std::string& user_email,
309 user_manager::RemoveUserDelegate* delegate) {
310 CrosSettings* cros_settings = CrosSettings::Get();
312 const base::Closure& callback =
313 base::Bind(&ChromeUserManagerImpl::RemoveUserInternal,
314 weak_factory_.GetWeakPtr(),
315 user_email,
316 delegate);
318 // Ensure the value of owner email has been fetched.
319 if (CrosSettingsProvider::TRUSTED !=
320 cros_settings->PrepareTrustedValues(callback)) {
321 // Value of owner email is not fetched yet. RemoveUserInternal will be
322 // called again after fetch completion.
323 return;
325 std::string owner;
326 cros_settings->GetString(kDeviceOwner, &owner);
327 if (user_email == owner) {
328 // Owner is not allowed to be removed from the device.
329 return;
331 RemoveNonOwnerUserInternal(user_email, delegate);
334 void ChromeUserManagerImpl::SaveUserOAuthStatus(
335 const std::string& user_id,
336 user_manager::User::OAuthTokenStatus oauth_token_status) {
337 DCHECK_CURRENTLY_ON(BrowserThread::UI);
338 ChromeUserManager::SaveUserOAuthStatus(user_id, oauth_token_status);
340 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(oauth_token_status);
343 void ChromeUserManagerImpl::SaveUserDisplayName(
344 const std::string& user_id,
345 const base::string16& display_name) {
346 DCHECK_CURRENTLY_ON(BrowserThread::UI);
347 ChromeUserManager::SaveUserDisplayName(user_id, display_name);
349 // Do not update local state if data stored or cached outside the user's
350 // cryptohome is to be treated as ephemeral.
351 if (!IsUserNonCryptohomeDataEphemeral(user_id))
352 supervised_user_manager_->UpdateManagerName(user_id, display_name);
355 void ChromeUserManagerImpl::StopPolicyObserverForTesting() {
356 avatar_policy_observer_.reset();
357 wallpaper_policy_observer_.reset();
360 void ChromeUserManagerImpl::Observe(
361 int type,
362 const content::NotificationSource& source,
363 const content::NotificationDetails& details) {
364 switch (type) {
365 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED:
366 if (!device_local_account_policy_service_) {
367 policy::BrowserPolicyConnectorChromeOS* connector =
368 g_browser_process->platform_part()
369 ->browser_policy_connector_chromeos();
370 device_local_account_policy_service_ =
371 connector->GetDeviceLocalAccountPolicyService();
372 if (device_local_account_policy_service_)
373 device_local_account_policy_service_->AddObserver(this);
375 RetrieveTrustedDevicePolicies();
376 UpdateOwnership();
377 break;
378 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: {
379 Profile* profile = content::Details<Profile>(details).ptr();
380 if (IsUserLoggedIn() && !IsLoggedInAsGuest() && !IsLoggedInAsKioskApp()) {
381 if (IsLoggedInAsSupervisedUser())
382 SupervisedUserPasswordServiceFactory::GetForProfile(profile);
383 if (IsLoggedInAsUserWithGaiaAccount())
384 ManagerPasswordServiceFactory::GetForProfile(profile);
386 if (!profile->IsOffTheRecord()) {
387 AuthSyncObserver* sync_observer =
388 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile);
389 sync_observer->StartObserving();
390 multi_profile_user_controller_->StartObserving(profile);
393 UpdateUserTimeZoneRefresher(profile);
394 break;
396 case chrome::NOTIFICATION_PROFILE_CREATED: {
397 Profile* profile = content::Source<Profile>(source).ptr();
398 user_manager::User* user =
399 ProfileHelper::Get()->GetUserByProfile(profile);
400 if (user != NULL) {
401 user->set_profile_is_created();
403 if (user->HasGaiaAccount()) {
404 UserImageManager* image_manager = GetUserImageManager(user->email());
405 image_manager->UserProfileCreated();
409 // If there is pending user switch, do it now.
410 if (!GetPendingUserSwitchID().empty()) {
411 // Call SwitchActiveUser async because otherwise it may cause
412 // ProfileManager::GetProfile before the profile gets registered
413 // in ProfileManager. It happens in case of sync profile load when
414 // NOTIFICATION_PROFILE_CREATED is called synchronously.
415 base::MessageLoop::current()->PostTask(
416 FROM_HERE,
417 base::Bind(&ChromeUserManagerImpl::SwitchActiveUser,
418 weak_factory_.GetWeakPtr(),
419 GetPendingUserSwitchID()));
420 SetPendingUserSwitchID(std::string());
422 break;
424 default:
425 NOTREACHED();
429 void ChromeUserManagerImpl::OnExternalDataSet(const std::string& policy,
430 const std::string& user_id) {
431 if (policy == policy::key::kUserAvatarImage)
432 GetUserImageManager(user_id)->OnExternalDataSet(policy);
433 else if (policy == policy::key::kWallpaperImage)
434 WallpaperManager::Get()->OnPolicySet(policy, user_id);
435 else
436 NOTREACHED();
439 void ChromeUserManagerImpl::OnExternalDataCleared(const std::string& policy,
440 const std::string& user_id) {
441 if (policy == policy::key::kUserAvatarImage)
442 GetUserImageManager(user_id)->OnExternalDataCleared(policy);
443 else if (policy == policy::key::kWallpaperImage)
444 WallpaperManager::Get()->OnPolicyCleared(policy, user_id);
445 else
446 NOTREACHED();
449 void ChromeUserManagerImpl::OnExternalDataFetched(
450 const std::string& policy,
451 const std::string& user_id,
452 scoped_ptr<std::string> data) {
453 if (policy == policy::key::kUserAvatarImage)
454 GetUserImageManager(user_id)->OnExternalDataFetched(policy, data.Pass());
455 else if (policy == policy::key::kWallpaperImage)
456 WallpaperManager::Get()->OnPolicyFetched(policy, user_id, data.Pass());
457 else
458 NOTREACHED();
461 void ChromeUserManagerImpl::OnPolicyUpdated(const std::string& user_id) {
462 const user_manager::User* user = FindUser(user_id);
463 if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
464 return;
465 UpdatePublicAccountDisplayName(user_id);
468 void ChromeUserManagerImpl::OnDeviceLocalAccountsChanged() {
469 // No action needed here, changes to the list of device-local accounts get
470 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
473 bool ChromeUserManagerImpl::CanCurrentUserLock() const {
474 return ChromeUserManager::CanCurrentUserLock() &&
475 GetCurrentUserFlow()->CanLockScreen();
478 bool ChromeUserManagerImpl::IsUserNonCryptohomeDataEphemeral(
479 const std::string& user_id) const {
480 // Data belonging to the obsolete public accounts whose data has not been
481 // removed yet is not ephemeral.
482 bool is_obsolete_public_account = IsPublicAccountMarkedForRemoval(user_id);
484 return !is_obsolete_public_account &&
485 ChromeUserManager::IsUserNonCryptohomeDataEphemeral(user_id);
488 bool ChromeUserManagerImpl::AreEphemeralUsersEnabled() const {
489 policy::BrowserPolicyConnectorChromeOS* connector =
490 g_browser_process->platform_part()->browser_policy_connector_chromeos();
491 return GetEphemeralUsersEnabled() &&
492 (connector->IsEnterpriseManaged() || !GetOwnerEmail().empty());
495 const std::string& ChromeUserManagerImpl::GetApplicationLocale() const {
496 return g_browser_process->GetApplicationLocale();
499 PrefService* ChromeUserManagerImpl::GetLocalState() const {
500 return g_browser_process ? g_browser_process->local_state() : NULL;
503 void ChromeUserManagerImpl::HandleUserOAuthTokenStatusChange(
504 const std::string& user_id,
505 user_manager::User::OAuthTokenStatus status) const {
506 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(status);
509 bool ChromeUserManagerImpl::IsEnterpriseManaged() const {
510 policy::BrowserPolicyConnectorChromeOS* connector =
511 g_browser_process->platform_part()->browser_policy_connector_chromeos();
512 return connector->IsEnterpriseManaged();
515 void ChromeUserManagerImpl::LoadPublicAccounts(
516 std::set<std::string>* public_sessions_set) {
517 const base::ListValue* prefs_public_sessions =
518 GetLocalState()->GetList(kPublicAccounts);
519 std::vector<std::string> public_sessions;
520 ParseUserList(*prefs_public_sessions,
521 std::set<std::string>(),
522 &public_sessions,
523 public_sessions_set);
524 for (std::vector<std::string>::const_iterator it = public_sessions.begin();
525 it != public_sessions.end();
526 ++it) {
527 users_.push_back(user_manager::User::CreatePublicAccountUser(*it));
528 UpdatePublicAccountDisplayName(*it);
532 void ChromeUserManagerImpl::PerformPreUserListLoadingActions() {
533 // Clean up user list first. All code down the path should be synchronous,
534 // so that local state after transaction rollback is in consistent state.
535 // This process also should not trigger EnsureUsersLoaded again.
536 if (supervised_user_manager_->HasFailedUserCreationTransaction())
537 supervised_user_manager_->RollbackUserCreationTransaction();
539 // Abandon all unfinished bootstraps.
540 bootstrap_manager_->RemoveAllPendingBootstrap();
543 void ChromeUserManagerImpl::PerformPostUserListLoadingActions() {
544 for (user_manager::UserList::iterator ui = users_.begin(), ue = users_.end();
545 ui != ue;
546 ++ui) {
547 GetUserImageManager((*ui)->email())->LoadUserImage();
551 void ChromeUserManagerImpl::PerformPostUserLoggedInActions(
552 bool browser_restart) {
553 // Initialize the session length limiter and start it only if
554 // session limit is defined by the policy.
555 session_length_limiter_.reset(
556 new SessionLengthLimiter(NULL, browser_restart));
559 bool ChromeUserManagerImpl::IsDemoApp(const std::string& user_id) const {
560 return DemoAppLauncher::IsDemoAppSession(user_id);
563 bool ChromeUserManagerImpl::IsKioskApp(const std::string& user_id) const {
564 policy::DeviceLocalAccount::Type device_local_account_type;
565 return policy::IsDeviceLocalAccountUser(user_id,
566 &device_local_account_type) &&
567 device_local_account_type ==
568 policy::DeviceLocalAccount::TYPE_KIOSK_APP;
571 bool ChromeUserManagerImpl::IsPublicAccountMarkedForRemoval(
572 const std::string& user_id) const {
573 return user_id ==
574 GetLocalState()->GetString(kPublicAccountPendingDataRemoval);
577 void ChromeUserManagerImpl::RetrieveTrustedDevicePolicies() {
578 // Local state may not be initialized in unit_tests.
579 if (!GetLocalState())
580 return;
582 SetEphemeralUsersEnabled(false);
583 SetOwnerEmail(std::string());
585 // Schedule a callback if device policy has not yet been verified.
586 if (CrosSettingsProvider::TRUSTED !=
587 cros_settings_->PrepareTrustedValues(
588 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies,
589 weak_factory_.GetWeakPtr()))) {
590 return;
593 bool ephemeral_users_enabled = false;
594 cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
595 &ephemeral_users_enabled);
596 SetEphemeralUsersEnabled(ephemeral_users_enabled);
598 std::string owner_email;
599 cros_settings_->GetString(kDeviceOwner, &owner_email);
600 SetOwnerEmail(owner_email);
602 EnsureUsersLoaded();
604 bool changed = UpdateAndCleanUpPublicAccounts(
605 policy::GetDeviceLocalAccounts(cros_settings_));
607 // If ephemeral users are enabled and we are on the login screen, take this
608 // opportunity to clean up by removing all regular users except the owner.
609 if (GetEphemeralUsersEnabled() && !IsUserLoggedIn()) {
610 ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
611 prefs_users_update->Clear();
612 for (user_manager::UserList::iterator it = users_.begin();
613 it != users_.end();) {
614 const std::string user_email = (*it)->email();
615 if ((*it)->HasGaiaAccount() && user_email != GetOwnerEmail()) {
616 RemoveNonCryptohomeData(user_email);
617 DeleteUser(*it);
618 it = users_.erase(it);
619 changed = true;
620 } else {
621 if ((*it)->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
622 prefs_users_update->Append(new base::StringValue(user_email));
623 ++it;
628 if (changed)
629 NotifyUserListChanged();
632 void ChromeUserManagerImpl::GuestUserLoggedIn() {
633 DCHECK_CURRENTLY_ON(BrowserThread::UI);
634 ChromeUserManager::GuestUserLoggedIn();
636 // TODO(nkostylev): Add support for passing guest session cryptohome
637 // mount point. Legacy (--login-profile) value will be used for now.
638 // http://crosbug.com/230859
639 active_user_->SetStubImage(
640 user_manager::UserImage(
641 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
642 IDR_PROFILE_PICTURE_LOADING)),
643 user_manager::User::USER_IMAGE_INVALID,
644 false);
646 // Initializes wallpaper after active_user_ is set.
647 WallpaperManager::Get()->SetUserWallpaperNow(chromeos::login::kGuestUserName);
650 void ChromeUserManagerImpl::RegularUserLoggedIn(const std::string& user_id) {
651 ChromeUserManager::RegularUserLoggedIn(user_id);
653 if (FakeOwnership()) {
654 std::string owner_email = GetActiveUser()->email();
655 VLOG(1) << "Set device owner to: " << owner_email;
656 CrosSettings::Get()->SetString(kDeviceOwner, owner_email);
657 SetOwnerEmail(owner_email);
660 if (IsCurrentUserNew())
661 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
663 GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), false);
665 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
667 // Make sure that new data is persisted to Local State.
668 GetLocalState()->CommitPendingWrite();
671 void ChromeUserManagerImpl::RegularUserLoggedInAsEphemeral(
672 const std::string& user_id) {
673 DCHECK_CURRENTLY_ON(BrowserThread::UI);
674 ChromeUserManager::RegularUserLoggedInAsEphemeral(user_id);
676 GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), false);
677 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
680 void ChromeUserManagerImpl::SupervisedUserLoggedIn(const std::string& user_id) {
681 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
683 // Remove the user from the user list.
684 active_user_ = RemoveRegularOrSupervisedUserFromList(user_id);
686 // If the user was not found on the user list, create a new user.
687 if (!GetActiveUser()) {
688 SetIsCurrentUserNew(true);
689 active_user_ = user_manager::User::CreateSupervisedUser(user_id);
690 // Leaving OAuth token status at the default state = unknown.
691 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
692 } else {
693 if (supervised_user_manager_->CheckForFirstRun(user_id)) {
694 SetIsCurrentUserNew(true);
695 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
696 } else {
697 SetIsCurrentUserNew(false);
701 // Add the user to the front of the user list.
702 ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
703 prefs_users_update->Insert(0, new base::StringValue(user_id));
704 users_.insert(users_.begin(), active_user_);
706 // Now that user is in the list, save display name.
707 if (IsCurrentUserNew()) {
708 SaveUserDisplayName(GetActiveUser()->email(),
709 GetActiveUser()->GetDisplayName());
712 GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), true);
713 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
715 // Make sure that new data is persisted to Local State.
716 GetLocalState()->CommitPendingWrite();
719 bool ChromeUserManagerImpl::HasPendingBootstrap(
720 const std::string& user_id) const {
721 return bootstrap_manager_->HasPendingBootstrap(user_id);
724 void ChromeUserManagerImpl::PublicAccountUserLoggedIn(
725 user_manager::User* user) {
726 SetIsCurrentUserNew(true);
727 active_user_ = user;
729 // The UserImageManager chooses a random avatar picture when a user logs in
730 // for the first time. Tell the UserImageManager that this user is not new to
731 // prevent the avatar from getting changed.
732 GetUserImageManager(user->email())->UserLoggedIn(false, true);
733 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
736 void ChromeUserManagerImpl::KioskAppLoggedIn(const std::string& app_id) {
737 DCHECK_CURRENTLY_ON(BrowserThread::UI);
738 policy::DeviceLocalAccount::Type device_local_account_type;
739 DCHECK(policy::IsDeviceLocalAccountUser(app_id, &device_local_account_type));
740 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
741 device_local_account_type);
743 active_user_ = user_manager::User::CreateKioskAppUser(app_id);
744 active_user_->SetStubImage(
745 user_manager::UserImage(
746 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
747 IDR_PROFILE_PICTURE_LOADING)),
748 user_manager::User::USER_IMAGE_INVALID,
749 false);
751 WallpaperManager::Get()->SetUserWallpaperNow(app_id);
753 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
754 // the kiosk_app_id in these objects, removing the need to re-parse the
755 // device-local account list here to extract the kiosk_app_id.
756 const std::vector<policy::DeviceLocalAccount> device_local_accounts =
757 policy::GetDeviceLocalAccounts(cros_settings_);
758 const policy::DeviceLocalAccount* account = NULL;
759 for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
760 device_local_accounts.begin();
761 it != device_local_accounts.end();
762 ++it) {
763 if (it->user_id == app_id) {
764 account = &*it;
765 break;
768 std::string kiosk_app_id;
769 if (account) {
770 kiosk_app_id = account->kiosk_app_id;
771 } else {
772 LOG(ERROR) << "Logged into nonexistent kiosk-app account: " << app_id;
773 NOTREACHED();
776 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
777 command_line->AppendSwitch(::switches::kForceAppMode);
778 command_line->AppendSwitchASCII(::switches::kAppId, kiosk_app_id);
780 // Disable window animation since kiosk app runs in a single full screen
781 // window and window animation causes start-up janks.
782 command_line->AppendSwitch(wm::switches::kWindowAnimationsDisabled);
785 void ChromeUserManagerImpl::DemoAccountLoggedIn() {
786 DCHECK_CURRENTLY_ON(BrowserThread::UI);
787 active_user_ =
788 user_manager::User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName);
789 active_user_->SetStubImage(
790 user_manager::UserImage(
791 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
792 IDR_PROFILE_PICTURE_LOADING)),
793 user_manager::User::USER_IMAGE_INVALID,
794 false);
795 WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName);
797 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
798 command_line->AppendSwitch(::switches::kForceAppMode);
799 command_line->AppendSwitchASCII(::switches::kAppId,
800 DemoAppLauncher::kDemoAppId);
802 // Disable window animation since the demo app runs in a single full screen
803 // window and window animation causes start-up janks.
804 base::CommandLine::ForCurrentProcess()->AppendSwitch(
805 wm::switches::kWindowAnimationsDisabled);
808 void ChromeUserManagerImpl::NotifyOnLogin() {
809 DCHECK_CURRENTLY_ON(BrowserThread::UI);
811 UserSessionManager::OverrideHomedir();
812 UpdateNumberOfUsers();
814 ChromeUserManager::NotifyOnLogin();
816 // TODO(nkostylev): Deprecate this notification in favor of
817 // ActiveUserChanged() observer call.
818 content::NotificationService::current()->Notify(
819 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
820 content::Source<UserManager>(this),
821 content::Details<const user_manager::User>(GetActiveUser()));
823 UserSessionManager::GetInstance()->PerformPostUserLoggedInActions();
826 void ChromeUserManagerImpl::UpdateOwnership() {
827 bool is_owner =
828 FakeOwnership() || DeviceSettingsService::Get()->HasPrivateOwnerKey();
829 VLOG(1) << "Current user " << (is_owner ? "is owner" : "is not owner");
831 SetCurrentUserIsOwner(is_owner);
834 void ChromeUserManagerImpl::RemoveNonCryptohomeData(
835 const std::string& user_id) {
836 ChromeUserManager::RemoveNonCryptohomeData(user_id);
838 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id);
839 GetUserImageManager(user_id)->DeleteUserImage();
841 supervised_user_manager_->RemoveNonCryptohomeData(user_id);
843 multi_profile_user_controller_->RemoveCachedValues(user_id);
845 EasyUnlockService::ResetLocalStateForUser(user_id);
848 void
849 ChromeUserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
850 PrefService* local_state = GetLocalState();
851 const std::string public_account_pending_data_removal =
852 local_state->GetString(kPublicAccountPendingDataRemoval);
853 if (public_account_pending_data_removal.empty() ||
854 (IsUserLoggedIn() &&
855 public_account_pending_data_removal == GetActiveUser()->email())) {
856 return;
859 RemoveNonCryptohomeData(public_account_pending_data_removal);
860 local_state->ClearPref(kPublicAccountPendingDataRemoval);
863 void ChromeUserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
864 const std::vector<std::string>& old_public_accounts) {
865 std::set<std::string> users;
866 for (user_manager::UserList::const_iterator it = users_.begin();
867 it != users_.end();
868 ++it)
869 users.insert((*it)->email());
871 // If the user is logged into a public account that has been removed from the
872 // user list, mark the account's data as pending removal after logout.
873 if (IsLoggedInAsPublicAccount()) {
874 const std::string active_user_id = GetActiveUser()->email();
875 if (users.find(active_user_id) == users.end()) {
876 GetLocalState()->SetString(kPublicAccountPendingDataRemoval,
877 active_user_id);
878 users.insert(active_user_id);
882 // Remove the data belonging to any other public accounts that are no longer
883 // found on the user list.
884 for (std::vector<std::string>::const_iterator it =
885 old_public_accounts.begin();
886 it != old_public_accounts.end();
887 ++it) {
888 if (users.find(*it) == users.end())
889 RemoveNonCryptohomeData(*it);
893 bool ChromeUserManagerImpl::UpdateAndCleanUpPublicAccounts(
894 const std::vector<policy::DeviceLocalAccount>& device_local_accounts) {
895 // Try to remove any public account data marked as pending removal.
896 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
898 // Get the current list of public accounts.
899 std::vector<std::string> old_public_accounts;
900 for (user_manager::UserList::const_iterator it = users_.begin();
901 it != users_.end();
902 ++it) {
903 if ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT)
904 old_public_accounts.push_back((*it)->email());
907 // Get the new list of public accounts from policy.
908 std::vector<std::string> new_public_accounts;
909 for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
910 device_local_accounts.begin();
911 it != device_local_accounts.end();
912 ++it) {
913 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
914 // standard login framework: http://crbug.com/234694
915 if (it->type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
916 new_public_accounts.push_back(it->user_id);
919 // If the list of public accounts has not changed, return.
920 if (new_public_accounts.size() == old_public_accounts.size()) {
921 bool changed = false;
922 for (size_t i = 0; i < new_public_accounts.size(); ++i) {
923 if (new_public_accounts[i] != old_public_accounts[i]) {
924 changed = true;
925 break;
928 if (!changed)
929 return false;
932 // Persist the new list of public accounts in a pref.
933 ListPrefUpdate prefs_public_accounts_update(GetLocalState(), kPublicAccounts);
934 prefs_public_accounts_update->Clear();
935 for (std::vector<std::string>::const_iterator it =
936 new_public_accounts.begin();
937 it != new_public_accounts.end();
938 ++it) {
939 prefs_public_accounts_update->AppendString(*it);
942 // Remove the old public accounts from the user list.
943 for (user_manager::UserList::iterator it = users_.begin();
944 it != users_.end();) {
945 if ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
946 if (*it != GetLoggedInUser())
947 DeleteUser(*it);
948 it = users_.erase(it);
949 } else {
950 ++it;
954 // Add the new public accounts to the front of the user list.
955 for (std::vector<std::string>::const_reverse_iterator it =
956 new_public_accounts.rbegin();
957 it != new_public_accounts.rend();
958 ++it) {
959 if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email())
960 users_.insert(users_.begin(), GetLoggedInUser());
961 else
962 users_.insert(users_.begin(),
963 user_manager::User::CreatePublicAccountUser(*it));
964 UpdatePublicAccountDisplayName(*it);
967 for (user_manager::UserList::iterator
968 ui = users_.begin(),
969 ue = users_.begin() + new_public_accounts.size();
970 ui != ue;
971 ++ui) {
972 GetUserImageManager((*ui)->email())->LoadUserImage();
975 // Remove data belonging to public accounts that are no longer found on the
976 // user list.
977 CleanUpPublicAccountNonCryptohomeData(old_public_accounts);
979 return true;
982 void ChromeUserManagerImpl::UpdatePublicAccountDisplayName(
983 const std::string& user_id) {
984 std::string display_name;
986 if (device_local_account_policy_service_) {
987 policy::DeviceLocalAccountPolicyBroker* broker =
988 device_local_account_policy_service_->GetBrokerForUser(user_id);
989 if (broker)
990 display_name = broker->GetDisplayName();
993 // Set or clear the display name.
994 SaveUserDisplayName(user_id, base::UTF8ToUTF16(display_name));
997 UserFlow* ChromeUserManagerImpl::GetCurrentUserFlow() const {
998 DCHECK_CURRENTLY_ON(BrowserThread::UI);
999 if (!IsUserLoggedIn())
1000 return GetDefaultUserFlow();
1001 return GetUserFlow(GetLoggedInUser()->email());
1004 UserFlow* ChromeUserManagerImpl::GetUserFlow(const std::string& user_id) const {
1005 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1006 FlowMap::const_iterator it = specific_flows_.find(user_id);
1007 if (it != specific_flows_.end())
1008 return it->second;
1009 return GetDefaultUserFlow();
1012 void ChromeUserManagerImpl::SetUserFlow(const std::string& user_id,
1013 UserFlow* flow) {
1014 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1015 ResetUserFlow(user_id);
1016 specific_flows_[user_id] = flow;
1019 void ChromeUserManagerImpl::ResetUserFlow(const std::string& user_id) {
1020 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1021 FlowMap::iterator it = specific_flows_.find(user_id);
1022 if (it != specific_flows_.end()) {
1023 delete it->second;
1024 specific_flows_.erase(it);
1028 bool ChromeUserManagerImpl::AreSupervisedUsersAllowed() const {
1029 bool supervised_users_allowed = false;
1030 cros_settings_->GetBoolean(kAccountsPrefSupervisedUsersEnabled,
1031 &supervised_users_allowed);
1032 return supervised_users_allowed;
1035 UserFlow* ChromeUserManagerImpl::GetDefaultUserFlow() const {
1036 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1037 if (!default_flow_.get())
1038 default_flow_.reset(new DefaultUserFlow());
1039 return default_flow_.get();
1042 void ChromeUserManagerImpl::NotifyUserListChanged() {
1043 content::NotificationService::current()->Notify(
1044 chrome::NOTIFICATION_USER_LIST_CHANGED,
1045 content::Source<UserManager>(this),
1046 content::NotificationService::NoDetails());
1049 void ChromeUserManagerImpl::NotifyUserAddedToSession(
1050 const user_manager::User* added_user,
1051 bool user_switch_pending) {
1052 // Special case for user session restoration after browser crash.
1053 // We don't switch to each user session that has been restored as once all
1054 // session will be restored we'll switch to the session that has been used
1055 // before the crash.
1056 if (user_switch_pending &&
1057 !UserSessionManager::GetInstance()->UserSessionsRestoreInProgress()) {
1058 SetPendingUserSwitchID(added_user->email());
1061 UpdateNumberOfUsers();
1062 ChromeUserManager::NotifyUserAddedToSession(added_user, user_switch_pending);
1065 void ChromeUserManagerImpl::OnUserNotAllowed(const std::string& user_email) {
1066 LOG(ERROR) << "Shutdown session because a user is not allowed to be in the "
1067 "current session";
1068 chromeos::ShowMultiprofilesSessionAbortedDialog(user_email);
1071 void ChromeUserManagerImpl::RemovePendingBootstrapUser(
1072 const std::string& user_id) {
1073 DCHECK(HasPendingBootstrap(user_id));
1074 RemoveNonOwnerUserInternal(user_id, NULL);
1077 void ChromeUserManagerImpl::UpdateNumberOfUsers() {
1078 size_t users = GetLoggedInUsers().size();
1079 if (users) {
1080 // Write the user number as UMA stat when a multi user session is possible.
1081 if ((users + GetUsersAllowedForMultiProfile().size()) > 1)
1082 ash::MultiProfileUMA::RecordUserCount(users);
1085 base::debug::SetCrashKeyValue(
1086 crash_keys::kNumberOfUsers,
1087 base::StringPrintf("%" PRIuS, GetLoggedInUsers().size()));
1090 void ChromeUserManagerImpl::UpdateUserTimeZoneRefresher(Profile* profile) {
1091 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1092 chromeos::switches::kDisableTimeZoneTrackingOption)) {
1093 return;
1096 const user_manager::User* user =
1097 ProfileHelper::Get()->GetUserByProfile(profile);
1098 if (user == NULL)
1099 return;
1101 // In Multi-Profile mode only primary user settings are in effect.
1102 if (user != user_manager::UserManager::Get()->GetPrimaryUser())
1103 return;
1105 if (!IsUserLoggedIn())
1106 return;
1108 // Timezone auto refresh is disabled for Guest, Supervized and OffTheRecord
1109 // users, but enabled for Kiosk mode.
1110 if (IsLoggedInAsGuest() || IsLoggedInAsSupervisedUser() ||
1111 profile->IsOffTheRecord()) {
1112 g_browser_process->platform_part()->GetTimezoneResolver()->Stop();
1113 return;
1116 if (profile->GetPrefs()->GetBoolean(prefs::kResolveTimezoneByGeolocation) &&
1117 !system::HasSystemTimezonePolicy()) {
1118 g_browser_process->platform_part()->GetTimezoneResolver()->Start();
1119 } else {
1120 g_browser_process->platform_part()->GetTimezoneResolver()->Stop();
1124 } // namespace chromeos