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