Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / chrome / browser / chromeos / login / users / chrome_user_manager_impl.cc
blobaf95e938965e2863125a3607fa482038c26245f4
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/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;
69 namespace chromeos {
70 namespace {
72 // A vector pref of the the regular users known on this device, arranged in LRU
73 // order.
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));
97 } // namespace
99 // static
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);
112 // static
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);
129 registrar_.Add(this,
130 chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
131 content::NotificationService::AllSources());
132 registrar_.Add(this,
133 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
134 content::NotificationService::AllSources());
135 registrar_.Add(this,
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(
142 FROM_HERE,
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(
157 cros_settings_,
158 connector->GetDeviceLocalAccountPolicyService(),
159 policy::key::kUserAvatarImage,
160 this));
161 avatar_policy_observer_->Init();
163 wallpaper_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
164 cros_settings_,
165 connector->GetDeviceLocalAccountPolicyService(),
166 policy::key::kWallpaperImage,
167 this));
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();
188 it != ie;
189 ++it) {
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;
214 return mgr.get();
217 SupervisedUserManager* ChromeUserManagerImpl::GetSupervisedUserManager() {
218 return supervised_user_manager_.get();
221 user_manager::UserList ChromeUserManagerImpl::GetUsersAllowedForMultiProfile()
222 const {
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();
232 it != users.end();
233 ++it) {
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(),
238 &check);
239 if (check ==
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);
251 return result;
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;
274 Profile* profile =
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_);
285 } else {
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();
289 ++it) {
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 &&
295 user->can_lock()) {
296 unlock_users.push_back(user);
297 } else if (behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
298 NOTREACHED()
299 << "Spotted primary-only multi-profile policy for non-primary user";
304 return unlock_users;
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(),
325 user_email,
326 delegate);
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.
333 return;
335 std::string owner;
336 cros_settings->GetString(kDeviceOwner, &owner);
337 if (user_email == owner) {
338 // Owner is not allowed to be removed from the device.
339 return;
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(
371 int type,
372 const content::NotificationSource& source,
373 const content::NotificationDetails& details) {
374 switch (type) {
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();
386 UpdateOwnership();
387 break;
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);
404 break;
406 case chrome::NOTIFICATION_PROFILE_CREATED: {
407 Profile* profile = content::Source<Profile>(source).ptr();
408 user_manager::User* user =
409 ProfileHelper::Get()->GetUserByProfile(profile);
410 if (user != NULL) {
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(
426 FROM_HERE,
427 base::Bind(&ChromeUserManagerImpl::SwitchActiveUser,
428 weak_factory_.GetWeakPtr(),
429 GetPendingUserSwitchID()));
430 SetPendingUserSwitchID(std::string());
432 break;
434 default:
435 NOTREACHED();
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);
445 else
446 NOTREACHED();
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);
455 else
456 NOTREACHED();
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());
467 else
468 NOTREACHED();
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)
474 return;
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>(),
536 &public_sessions,
537 public_sessions_set);
538 for (std::vector<std::string>::const_iterator it = public_sessions.begin();
539 it != public_sessions.end();
540 ++it) {
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();
559 ui != ue;
560 ++ui) {
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 {
587 return user_id ==
588 GetLocalState()->GetString(kPublicAccountPendingDataRemoval);
591 void ChromeUserManagerImpl::RetrieveTrustedDevicePolicies() {
592 // Local state may not be initialized in unit_tests.
593 if (!GetLocalState())
594 return;
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()))) {
604 return;
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);
616 EnsureUsersLoaded();
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);
631 DeleteUser(*it);
632 it = users_.erase(it);
633 changed = true;
634 } else {
635 if ((*it)->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
636 prefs_users_update->Append(new base::StringValue(user_email));
637 ++it;
642 if (changed)
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,
658 false);
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);
706 } else {
707 if (supervised_user_manager_->CheckForFirstRun(user_id)) {
708 SetIsCurrentUserNew(true);
709 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
710 } else {
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);
741 active_user_ = user;
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,
763 false);
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();
776 ++it) {
777 if (it->user_id == app_id) {
778 account = &*it;
779 break;
782 std::string kiosk_app_id;
783 if (account) {
784 kiosk_app_id = account->kiosk_app_id;
785 } else {
786 LOG(ERROR) << "Logged into nonexistent kiosk-app account: " << app_id;
787 NOTREACHED();
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);
801 active_user_ =
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,
808 false);
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() {
841 bool is_owner =
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);
862 void
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() ||
868 (IsUserLoggedIn() &&
869 public_account_pending_data_removal == GetActiveUser()->email())) {
870 return;
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();
881 it != users_.end();
882 ++it)
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,
891 active_user_id);
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();
901 ++it) {
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();
915 it != users_.end();
916 ++it) {
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();
926 ++it) {
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]) {
938 changed = true;
939 break;
942 if (!changed)
943 return false;
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();
952 ++it) {
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())
961 DeleteUser(*it);
962 it = users_.erase(it);
963 } else {
964 ++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();
972 ++it) {
973 if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email())
974 users_.insert(users_.begin(), GetLoggedInUser());
975 else
976 users_.insert(users_.begin(),
977 user_manager::User::CreatePublicAccountUser(*it));
978 UpdatePublicAccountDisplayName(*it);
981 for (user_manager::UserList::iterator
982 ui = users_.begin(),
983 ue = users_.begin() + new_public_accounts.size();
984 ui != ue;
985 ++ui) {
986 GetUserImageManager((*ui)->email())->LoadUserImage();
989 // Remove data belonging to public accounts that are no longer found on the
990 // user list.
991 CleanUpPublicAccountNonCryptohomeData(old_public_accounts);
993 return true;
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);
1003 if (broker)
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())
1022 return it->second;
1023 return GetDefaultUserFlow();
1026 void ChromeUserManagerImpl::SetUserFlow(const std::string& user_id,
1027 UserFlow* flow) {
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()) {
1037 delete it->second;
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 "
1081 "current session";
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();
1093 if (users) {
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)) {
1107 return;
1110 const user_manager::User* user =
1111 ProfileHelper::Get()->GetUserByProfile(profile);
1112 if (user == NULL)
1113 return;
1115 // In Multi-Profile mode only primary user settings are in effect.
1116 if (user != user_manager::UserManager::Get()->GetPrimaryUser())
1117 return;
1119 if (!IsUserLoggedIn())
1120 return;
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();
1127 return;
1130 if (profile->GetPrefs()->GetBoolean(prefs::kResolveTimezoneByGeolocation) &&
1131 !system::HasSystemTimezonePolicy()) {
1132 g_browser_process->platform_part()->GetTimezoneResolver()->Start();
1133 } else {
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);
1144 if (user) {
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);
1155 } else {
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