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