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