Fix infinite recursion on hiding panel when created during fullscreen mode.
[chromium-blink-merge.git] / chrome / browser / chromeos / login / user_manager_impl.cc
blobb6e1b27ba056801e7555d756e0d8960851feace6
1 // Copyright (c) 2013 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/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/files/file_path.h"
16 #include "base/format_macros.h"
17 #include "base/logging.h"
18 #include "base/metrics/histogram.h"
19 #include "base/prefs/pref_registry_simple.h"
20 #include "base/prefs/pref_service.h"
21 #include "base/prefs/scoped_user_pref_update.h"
22 #include "base/rand_util.h"
23 #include "base/strings/string_util.h"
24 #include "base/strings/stringprintf.h"
25 #include "base/strings/utf_string_conversions.h"
26 #include "base/sys_info.h"
27 #include "base/threading/worker_pool.h"
28 #include "base/values.h"
29 #include "chrome/browser/app_mode/app_mode_utils.h"
30 #include "chrome/browser/browser_process.h"
31 #include "chrome/browser/chrome_notification_types.h"
32 #include "chrome/browser/chromeos/base/locale_util.h"
33 #include "chrome/browser/chromeos/login/auth_sync_observer.h"
34 #include "chrome/browser/chromeos/login/auth_sync_observer_factory.h"
35 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
36 #include "chrome/browser/chromeos/login/login_display.h"
37 #include "chrome/browser/chromeos/login/login_utils.h"
38 #include "chrome/browser/chromeos/login/multi_profile_first_run_notification.h"
39 #include "chrome/browser/chromeos/login/multi_profile_user_controller.h"
40 #include "chrome/browser/chromeos/login/remove_user_delegate.h"
41 #include "chrome/browser/chromeos/login/supervised_user_manager_impl.h"
42 #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
43 #include "chrome/browser/chromeos/login/wizard_controller.h"
44 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
45 #include "chrome/browser/chromeos/policy/device_local_account.h"
46 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog.h"
47 #include "chrome/browser/chromeos/profiles/profile_helper.h"
48 #include "chrome/browser/chromeos/session_length_limiter.h"
49 #include "chrome/browser/managed_mode/chromeos/managed_user_password_service_factory.h"
50 #include "chrome/browser/managed_mode/chromeos/manager_password_service_factory.h"
51 #include "chrome/browser/net/nss_context.h"
52 #include "chrome/browser/profiles/profile.h"
53 #include "chrome/browser/profiles/profile_manager.h"
54 #include "chrome/browser/sync/profile_sync_service.h"
55 #include "chrome/browser/sync/profile_sync_service_factory.h"
56 #include "chrome/common/chrome_constants.h"
57 #include "chrome/common/chrome_switches.h"
58 #include "chrome/common/crash_keys.h"
59 #include "chrome/common/pref_names.h"
60 #include "chromeos/cert_loader.h"
61 #include "chromeos/chromeos_switches.h"
62 #include "chromeos/cryptohome/async_method_caller.h"
63 #include "chromeos/dbus/dbus_thread_manager.h"
64 #include "chromeos/login/login_state.h"
65 #include "chromeos/settings/cros_settings_names.h"
66 #include "content/public/browser/browser_thread.h"
67 #include "content/public/browser/notification_service.h"
68 #include "google_apis/gaia/gaia_auth_util.h"
69 #include "google_apis/gaia/google_service_auth_error.h"
70 #include "policy/policy_constants.h"
71 #include "ui/base/l10n/l10n_util.h"
72 #include "ui/wm/core/wm_core_switches.h"
74 using content::BrowserThread;
76 namespace chromeos {
77 namespace {
79 // A vector pref of the the regular users known on this device, arranged in LRU
80 // order.
81 const char kRegularUsers[] = "LoggedInUsers";
83 // A vector pref of the public accounts defined on this device.
84 const char kPublicAccounts[] = "PublicAccounts";
86 // A string pref that gets set when a public account is removed but a user is
87 // currently logged into that account, requiring the account's data to be
88 // removed after logout.
89 const char kPublicAccountPendingDataRemoval[] =
90 "PublicAccountPendingDataRemoval";
92 // A dictionary that maps user IDs to the displayed name.
93 const char kUserDisplayName[] = "UserDisplayName";
95 // A dictionary that maps user IDs to the user's given name.
96 const char kUserGivenName[] = "UserGivenName";
98 // A dictionary that maps user IDs to the displayed (non-canonical) emails.
99 const char kUserDisplayEmail[] = "UserDisplayEmail";
101 // A dictionary that maps user IDs to OAuth token presence flag.
102 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus";
104 // A dictionary that maps user IDs to a flag indicating whether online
105 // authentication against GAIA should be enforced during the next sign-in.
106 const char kUserForceOnlineSignin[] = "UserForceOnlineSignin";
108 // A string pref containing the ID of the last user who logged in if it was
109 // a regular user or an empty string if it was another type of user (guest,
110 // kiosk, public account, etc.).
111 const char kLastLoggedInRegularUser[] = "LastLoggedInRegularUser";
113 // Upper bound for a histogram metric reporting the amount of time between
114 // one regular user logging out and a different regular user logging in.
115 const int kLogoutToLoginDelayMaxSec = 1800;
117 // Callback that is called after user removal is complete.
118 void OnRemoveUserComplete(const std::string& user_email,
119 bool success,
120 cryptohome::MountError return_code) {
121 // Log the error, but there's not much we can do.
122 if (!success) {
123 LOG(ERROR) << "Removal of cryptohome for " << user_email
124 << " failed, return code: " << return_code;
128 // Helper function that copies users from |users_list| to |users_vector| and
129 // |users_set|. Duplicates and users already present in |existing_users| are
130 // skipped.
131 void ParseUserList(const base::ListValue& users_list,
132 const std::set<std::string>& existing_users,
133 std::vector<std::string>* users_vector,
134 std::set<std::string>* users_set) {
135 users_vector->clear();
136 users_set->clear();
137 for (size_t i = 0; i < users_list.GetSize(); ++i) {
138 std::string email;
139 if (!users_list.GetString(i, &email) || email.empty()) {
140 LOG(ERROR) << "Corrupt entry in user list at index " << i << ".";
141 continue;
143 if (existing_users.find(email) != existing_users.end() ||
144 !users_set->insert(email).second) {
145 LOG(ERROR) << "Duplicate user: " << email;
146 continue;
148 users_vector->push_back(email);
152 class UserHashMatcher {
153 public:
154 explicit UserHashMatcher(const std::string& h) : username_hash(h) {}
155 bool operator()(const User* user) const {
156 return user->username_hash() == username_hash;
159 private:
160 const std::string& username_hash;
163 // Runs on SequencedWorkerPool thread. Passes resolved locale to
164 // |on_resolve_callback| on UI thread.
165 void ResolveLocale(
166 const std::string& raw_locale,
167 base::Callback<void(const std::string&)> on_resolve_callback) {
168 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
169 std::string resolved_locale;
170 // Ignore result
171 l10n_util::CheckAndResolveLocale(raw_locale, &resolved_locale);
172 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
173 base::Bind(on_resolve_callback, resolved_locale));
176 // Callback to GetNSSCertDatabaseForProfile. It starts CertLoader using the
177 // provided NSS database. It must be called for primary user only.
178 void OnGetNSSCertDatabaseForUser(net::NSSCertDatabase* database) {
179 if (!CertLoader::IsInitialized())
180 return;
182 CertLoader::Get()->StartWithNSSDB(database);
185 } // namespace
187 // static
188 void UserManager::RegisterPrefs(PrefRegistrySimple* registry) {
189 registry->RegisterListPref(kRegularUsers);
190 registry->RegisterListPref(kPublicAccounts);
191 registry->RegisterStringPref(kPublicAccountPendingDataRemoval, "");
192 registry->RegisterStringPref(kLastLoggedInRegularUser, "");
193 registry->RegisterDictionaryPref(kUserDisplayName);
194 registry->RegisterDictionaryPref(kUserGivenName);
195 registry->RegisterDictionaryPref(kUserDisplayEmail);
196 registry->RegisterDictionaryPref(kUserOAuthTokenStatus);
197 registry->RegisterDictionaryPref(kUserForceOnlineSignin);
198 SupervisedUserManager::RegisterPrefs(registry);
199 SessionLengthLimiter::RegisterPrefs(registry);
202 UserManagerImpl::UserManagerImpl()
203 : cros_settings_(CrosSettings::Get()),
204 device_local_account_policy_service_(NULL),
205 user_loading_stage_(STAGE_NOT_LOADED),
206 active_user_(NULL),
207 primary_user_(NULL),
208 session_started_(false),
209 user_sessions_restored_(false),
210 is_current_user_owner_(false),
211 is_current_user_new_(false),
212 is_current_user_ephemeral_regular_user_(false),
213 ephemeral_users_enabled_(false),
214 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
215 manager_creation_time_(base::TimeTicks::Now()),
216 multi_profile_first_run_notification_(
217 new MultiProfileFirstRunNotification) {
218 UpdateNumberOfUsers();
219 // UserManager instance should be used only on UI thread.
220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
221 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
222 content::NotificationService::AllSources());
223 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
224 content::NotificationService::AllSources());
225 registrar_.Add(this,
226 chrome::NOTIFICATION_PROFILE_CREATED,
227 content::NotificationService::AllSources());
228 RetrieveTrustedDevicePolicies();
229 local_accounts_subscription_ = cros_settings_->AddSettingsObserver(
230 kAccountsPrefDeviceLocalAccounts,
231 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
232 base::Unretained(this)));
233 supervised_users_subscription_ = cros_settings_->AddSettingsObserver(
234 kAccountsPrefSupervisedUsersEnabled,
235 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
236 base::Unretained(this)));
237 multi_profile_user_controller_.reset(new MultiProfileUserController(
238 this, g_browser_process->local_state()));
240 policy::BrowserPolicyConnectorChromeOS* connector =
241 g_browser_process->platform_part()->browser_policy_connector_chromeos();
242 avatar_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
243 cros_settings_,
244 this,
245 connector->GetDeviceLocalAccountPolicyService(),
246 policy::key::kUserAvatarImage,
247 this));
248 avatar_policy_observer_->Init();
250 wallpaper_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
251 cros_settings_,
252 this,
253 connector->GetDeviceLocalAccountPolicyService(),
254 policy::key::kWallpaperImage,
255 this));
256 wallpaper_policy_observer_->Init();
258 UpdateLoginState();
261 UserManagerImpl::~UserManagerImpl() {
262 // Can't use STLDeleteElements because of the private destructor of User.
263 for (UserList::iterator it = users_.begin(); it != users_.end();
264 it = users_.erase(it)) {
265 DeleteUser(*it);
267 // These are pointers to the same User instances that were in users_ list.
268 logged_in_users_.clear();
269 lru_logged_in_users_.clear();
271 DeleteUser(active_user_);
274 void UserManagerImpl::Shutdown() {
275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
276 local_accounts_subscription_.reset();
277 supervised_users_subscription_.reset();
278 // Stop the session length limiter.
279 session_length_limiter_.reset();
281 if (device_local_account_policy_service_)
282 device_local_account_policy_service_->RemoveObserver(this);
284 for (UserImageManagerMap::iterator it = user_image_managers_.begin(),
285 ie = user_image_managers_.end();
286 it != ie; ++it) {
287 it->second->Shutdown();
289 multi_profile_user_controller_.reset();
290 avatar_policy_observer_.reset();
291 wallpaper_policy_observer_.reset();
294 MultiProfileUserController* UserManagerImpl::GetMultiProfileUserController() {
295 return multi_profile_user_controller_.get();
298 UserImageManager* UserManagerImpl::GetUserImageManager(
299 const std::string& user_id) {
300 UserImageManagerMap::iterator ui = user_image_managers_.find(user_id);
301 if (ui != user_image_managers_.end())
302 return ui->second.get();
303 linked_ptr<UserImageManagerImpl> mgr(new UserImageManagerImpl(user_id, this));
304 user_image_managers_[user_id] = mgr;
305 return mgr.get();
308 SupervisedUserManager* UserManagerImpl::GetSupervisedUserManager() {
309 return supervised_user_manager_.get();
312 const UserList& UserManagerImpl::GetUsers() const {
313 const_cast<UserManagerImpl*>(this)->EnsureUsersLoaded();
314 return users_;
317 UserList UserManagerImpl::GetUsersAdmittedForMultiProfile() const {
318 if (!UserManager::IsMultipleProfilesAllowed())
319 return UserList();
321 // Supervised users are not allowed to use multi profile.
322 if (logged_in_users_.size() == 1 &&
323 GetPrimaryUser()->GetType() != User::USER_TYPE_REGULAR)
324 return UserList();
326 UserList result;
327 int num_users_allowed = 0;
328 const UserList& users = GetUsers();
329 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
330 if ((*it)->GetType() == User::USER_TYPE_REGULAR && !(*it)->is_logged_in()) {
331 MultiProfileUserController::UserAllowedInSessionResult check =
332 multi_profile_user_controller_->
333 IsUserAllowedInSession((*it)->email());
334 if (check == MultiProfileUserController::
335 NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS) {
336 return UserList();
339 // Users with a policy that prevents them being added to a session will be
340 // shown in login UI but will be grayed out.
341 if (check == MultiProfileUserController::ALLOWED ||
342 check == MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS) {
343 result.push_back(*it);
344 if (check == MultiProfileUserController::ALLOWED)
345 num_users_allowed++;
350 // We only show multi-profiles sign in UI if there's at least one user that
351 // is allowed to be added to the session.
352 if (!num_users_allowed)
353 result.clear();
355 return result;
358 const UserList& UserManagerImpl::GetLoggedInUsers() const {
359 return logged_in_users_;
362 const UserList& UserManagerImpl::GetLRULoggedInUsers() {
363 // If there is no user logged in, we return the active user as the only one.
364 if (lru_logged_in_users_.empty() && active_user_) {
365 temp_single_logged_in_users_.clear();
366 temp_single_logged_in_users_.insert(temp_single_logged_in_users_.begin(),
367 active_user_);
368 return temp_single_logged_in_users_;
370 return lru_logged_in_users_;
373 UserList UserManagerImpl::GetUnlockUsers() const {
374 const UserList& logged_in_users = GetLoggedInUsers();
375 if (logged_in_users.empty())
376 return UserList();
378 UserList unlock_users;
379 Profile* profile = GetProfileByUser(primary_user_);
380 std::string primary_behavior =
381 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
383 // Specific case: only one logged in user or
384 // primary user has primary-only multi-profile policy.
385 if (logged_in_users.size() == 1 ||
386 primary_behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
387 if (primary_user_->can_lock())
388 unlock_users.push_back(primary_user_);
389 } else {
390 // Fill list of potential unlock users based on multi-profile policy state.
391 for (UserList::const_iterator it = logged_in_users.begin();
392 it != logged_in_users.end(); ++it) {
393 User* user = (*it);
394 Profile* profile = GetProfileByUser(user);
395 const std::string behavior =
396 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
397 if (behavior == MultiProfileUserController::kBehaviorUnrestricted &&
398 user->can_lock()) {
399 unlock_users.push_back(user);
400 } else if (behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
401 NOTREACHED()
402 << "Spotted primary-only multi-profile policy for non-primary user";
407 return unlock_users;
410 const std::string& UserManagerImpl::GetOwnerEmail() {
411 return owner_email_;
414 void UserManagerImpl::UserLoggedIn(const std::string& user_id,
415 const std::string& username_hash,
416 bool browser_restart) {
417 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
419 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles))
420 DCHECK(!IsUserLoggedIn());
422 User* user = FindUserInListAndModify(user_id);
423 if (active_user_ && user) {
424 user->set_is_logged_in(true);
425 user->set_username_hash(username_hash);
426 logged_in_users_.push_back(user);
427 lru_logged_in_users_.push_back(user);
428 // Reset the new user flag if the user already exists.
429 is_current_user_new_ = false;
430 // Set active user wallpaper back.
431 WallpaperManager::Get()->SetUserWallpaperNow(active_user_->email());
432 NotifyUserAddedToSession(user);
433 return;
436 policy::DeviceLocalAccount::Type device_local_account_type;
437 if (user_id == UserManager::kGuestUserName) {
438 GuestUserLoggedIn();
439 } else if (user_id == UserManager::kRetailModeUserName) {
440 RetailModeUserLoggedIn();
441 } else if (policy::IsDeviceLocalAccountUser(user_id,
442 &device_local_account_type) &&
443 device_local_account_type ==
444 policy::DeviceLocalAccount::TYPE_KIOSK_APP) {
445 KioskAppLoggedIn(user_id);
446 } else if (DemoAppLauncher::IsDemoAppSession(user_id)) {
447 DemoAccountLoggedIn();
448 } else {
449 EnsureUsersLoaded();
451 if (user && user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
452 PublicAccountUserLoggedIn(user);
453 } else if ((user && user->GetType() == User::USER_TYPE_LOCALLY_MANAGED) ||
454 (!user && gaia::ExtractDomainName(user_id) ==
455 UserManager::kLocallyManagedUserDomain)) {
456 LocallyManagedUserLoggedIn(user_id);
457 } else if (browser_restart && user_id == g_browser_process->local_state()->
458 GetString(kPublicAccountPendingDataRemoval)) {
459 PublicAccountUserLoggedIn(User::CreatePublicAccountUser(user_id));
460 } else if (user_id != owner_email_ && !user &&
461 (AreEphemeralUsersEnabled() || browser_restart)) {
462 RegularUserLoggedInAsEphemeral(user_id);
463 } else {
464 RegularUserLoggedIn(user_id);
467 // Initialize the session length limiter and start it only if
468 // session limit is defined by the policy.
469 session_length_limiter_.reset(new SessionLengthLimiter(NULL,
470 browser_restart));
472 DCHECK(active_user_);
473 active_user_->set_is_logged_in(true);
474 active_user_->set_is_active(true);
475 active_user_->set_username_hash(username_hash);
477 // Place user who just signed in to the top of the logged in users.
478 logged_in_users_.insert(logged_in_users_.begin(), active_user_);
479 SetLRUUser(active_user_);
481 if (!primary_user_) {
482 primary_user_ = active_user_;
483 if (primary_user_->GetType() == User::USER_TYPE_REGULAR)
484 SendRegularUserLoginMetrics(user_id);
487 UMA_HISTOGRAM_ENUMERATION("UserManager.LoginUserType",
488 active_user_->GetType(), User::NUM_USER_TYPES);
490 g_browser_process->local_state()->SetString(kLastLoggedInRegularUser,
491 (active_user_->GetType() == User::USER_TYPE_REGULAR) ? user_id : "");
493 NotifyOnLogin();
496 void UserManagerImpl::SwitchActiveUser(const std::string& user_id) {
497 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles))
498 return;
500 User* user = FindUserAndModify(user_id);
501 if (!user) {
502 NOTREACHED() << "Switching to a non-existing user";
503 return;
505 if (user == active_user_) {
506 NOTREACHED() << "Switching to a user who is already active";
507 return;
509 if (!user->is_logged_in()) {
510 NOTREACHED() << "Switching to a user that is not logged in";
511 return;
513 if (user->GetType() != User::USER_TYPE_REGULAR) {
514 NOTREACHED() << "Switching to a non-regular user";
515 return;
517 if (user->username_hash().empty()) {
518 NOTREACHED() << "Switching to a user that doesn't have username_hash set";
519 return;
522 DCHECK(active_user_);
523 active_user_->set_is_active(false);
524 user->set_is_active(true);
525 active_user_ = user;
527 // Move the user to the front.
528 SetLRUUser(active_user_);
530 NotifyActiveUserHashChanged(active_user_->username_hash());
531 NotifyActiveUserChanged(active_user_);
534 void UserManagerImpl::RestoreActiveSessions() {
535 DBusThreadManager::Get()->GetSessionManagerClient()->RetrieveActiveSessions(
536 base::Bind(&UserManagerImpl::OnRestoreActiveSessions,
537 base::Unretained(this)));
540 void UserManagerImpl::SessionStarted() {
541 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
542 session_started_ = true;
543 UpdateLoginState();
544 content::NotificationService::current()->Notify(
545 chrome::NOTIFICATION_SESSION_STARTED,
546 content::Source<UserManager>(this),
547 content::Details<const User>(active_user_));
548 if (is_current_user_new_) {
549 // Make sure that the new user's data is persisted to Local State.
550 g_browser_process->local_state()->CommitPendingWrite();
554 void UserManagerImpl::RemoveUser(const std::string& user_id,
555 RemoveUserDelegate* delegate) {
556 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
558 const User* user = FindUser(user_id);
559 if (!user || (user->GetType() != User::USER_TYPE_REGULAR &&
560 user->GetType() != User::USER_TYPE_LOCALLY_MANAGED))
561 return;
563 // Sanity check: we must not remove single user unless it's an enterprise
564 // device. This check may seem redundant at a first sight because
565 // this single user must be an owner and we perform special check later
566 // in order not to remove an owner. However due to non-instant nature of
567 // ownership assignment this later check may sometimes fail.
568 // See http://crosbug.com/12723
569 policy::BrowserPolicyConnectorChromeOS* connector =
570 g_browser_process->platform_part()
571 ->browser_policy_connector_chromeos();
572 if (users_.size() < 2 && !connector->IsEnterpriseManaged())
573 return;
575 // Sanity check: do not allow any of the the logged in users to be removed.
576 for (UserList::const_iterator it = logged_in_users_.begin();
577 it != logged_in_users_.end(); ++it) {
578 if ((*it)->email() == user_id)
579 return;
582 RemoveUserInternal(user_id, delegate);
585 void UserManagerImpl::RemoveUserInternal(const std::string& user_email,
586 RemoveUserDelegate* delegate) {
587 CrosSettings* cros_settings = CrosSettings::Get();
589 // Ensure the value of owner email has been fetched.
590 if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues(
591 base::Bind(&UserManagerImpl::RemoveUserInternal,
592 base::Unretained(this),
593 user_email, delegate))) {
594 // Value of owner email is not fetched yet. RemoveUserInternal will be
595 // called again after fetch completion.
596 return;
598 std::string owner;
599 cros_settings->GetString(kDeviceOwner, &owner);
600 if (user_email == owner) {
601 // Owner is not allowed to be removed from the device.
602 return;
604 RemoveNonOwnerUserInternal(user_email, delegate);
607 void UserManagerImpl::RemoveNonOwnerUserInternal(const std::string& user_email,
608 RemoveUserDelegate* delegate) {
609 if (delegate)
610 delegate->OnBeforeUserRemoved(user_email);
611 RemoveUserFromList(user_email);
612 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
613 user_email, base::Bind(&OnRemoveUserComplete, user_email));
615 if (delegate)
616 delegate->OnUserRemoved(user_email);
619 void UserManagerImpl::RemoveUserFromList(const std::string& user_id) {
620 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
621 RemoveNonCryptohomeData(user_id);
622 if (user_loading_stage_ == STAGE_LOADED) {
623 DeleteUser(RemoveRegularOrLocallyManagedUserFromList(user_id));
624 } else if (user_loading_stage_ == STAGE_LOADING) {
625 DCHECK(gaia::ExtractDomainName(user_id) ==
626 UserManager::kLocallyManagedUserDomain);
627 // Special case, removing partially-constructed supervised user during user
628 // list loading.
629 ListPrefUpdate users_update(g_browser_process->local_state(),
630 kRegularUsers);
631 users_update->Remove(base::StringValue(user_id), NULL);
632 } else {
633 NOTREACHED() << "Users are not loaded yet.";
634 return;
636 // Make sure that new data is persisted to Local State.
637 g_browser_process->local_state()->CommitPendingWrite();
640 bool UserManagerImpl::IsKnownUser(const std::string& user_id) const {
641 return FindUser(user_id) != NULL;
644 const User* UserManagerImpl::FindUser(const std::string& user_id) const {
645 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
646 if (active_user_ && active_user_->email() == user_id)
647 return active_user_;
648 return FindUserInList(user_id);
651 User* UserManagerImpl::FindUserAndModify(const std::string& user_id) {
652 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
653 if (active_user_ && active_user_->email() == user_id)
654 return active_user_;
655 return FindUserInListAndModify(user_id);
658 const User* UserManagerImpl::GetLoggedInUser() const {
659 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
660 return active_user_;
663 User* UserManagerImpl::GetLoggedInUser() {
664 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
665 return active_user_;
668 const User* UserManagerImpl::GetActiveUser() const {
669 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
670 return active_user_;
673 User* UserManagerImpl::GetActiveUser() {
674 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
675 return active_user_;
678 const User* UserManagerImpl::GetPrimaryUser() const {
679 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
680 return primary_user_;
683 User* UserManagerImpl::GetUserByProfile(Profile* profile) const {
684 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
685 if (ProfileHelper::IsSigninProfile(profile))
686 return NULL;
688 if (IsMultipleProfilesAllowed()) {
689 const std::string username_hash =
690 ProfileHelper::GetUserIdHashFromProfile(profile);
691 const UserList& users = GetUsers();
692 const UserList::const_iterator pos = std::find_if(
693 users.begin(), users.end(), UserHashMatcher(username_hash));
694 if (pos != users.end())
695 return *pos;
697 // Many tests do not have their users registered with UserManager and
698 // runs here. If |active_user_| matches |profile|, returns it.
699 return active_user_ &&
700 ProfileHelper::GetProfilePathByUserIdHash(
701 active_user_->username_hash()) == profile->GetPath()
702 ? active_user_
703 : NULL;
705 return active_user_;
708 Profile* UserManagerImpl::GetProfileByUser(const User* user) const {
709 Profile* profile = NULL;
710 if (IsMultipleProfilesAllowed() && user->is_profile_created())
711 profile = ProfileHelper::GetProfileByUserIdHash(user->username_hash());
712 else
713 profile = ProfileManager::GetActiveUserProfile();
715 // GetActiveUserProfile() or GetProfileByUserIdHash() returns a new instance
716 // of ProfileImpl(), but actually its OffTheRecordProfile() should be used.
717 if (profile && IsLoggedInAsGuest())
718 profile = profile->GetOffTheRecordProfile();
719 return profile;
722 void UserManagerImpl::SaveUserOAuthStatus(
723 const std::string& user_id,
724 User::OAuthTokenStatus oauth_token_status) {
725 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
727 DVLOG(1) << "Saving user OAuth token status in Local State";
728 User* user = FindUserAndModify(user_id);
729 if (user)
730 user->set_oauth_token_status(oauth_token_status);
732 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(oauth_token_status);
734 // Do not update local state if data stored or cached outside the user's
735 // cryptohome is to be treated as ephemeral.
736 if (IsUserNonCryptohomeDataEphemeral(user_id))
737 return;
739 PrefService* local_state = g_browser_process->local_state();
741 DictionaryPrefUpdate oauth_status_update(local_state, kUserOAuthTokenStatus);
742 oauth_status_update->SetWithoutPathExpansion(user_id,
743 new base::FundamentalValue(static_cast<int>(oauth_token_status)));
746 void UserManagerImpl::SaveForceOnlineSignin(const std::string& user_id,
747 bool force_online_signin) {
748 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
750 // Do not update local state if data stored or cached outside the user's
751 // cryptohome is to be treated as ephemeral.
752 if (IsUserNonCryptohomeDataEphemeral(user_id))
753 return;
755 DictionaryPrefUpdate force_online_update(g_browser_process->local_state(),
756 kUserForceOnlineSignin);
757 force_online_update->SetBooleanWithoutPathExpansion(user_id,
758 force_online_signin);
761 void UserManagerImpl::SaveUserDisplayName(const std::string& user_id,
762 const base::string16& display_name) {
763 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
765 if (User* user = FindUserAndModify(user_id)) {
766 user->set_display_name(display_name);
768 // Do not update local state if data stored or cached outside the user's
769 // cryptohome is to be treated as ephemeral.
770 if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
771 PrefService* local_state = g_browser_process->local_state();
773 DictionaryPrefUpdate display_name_update(local_state, kUserDisplayName);
774 display_name_update->SetWithoutPathExpansion(
775 user_id,
776 new base::StringValue(display_name));
778 supervised_user_manager_->UpdateManagerName(user_id, display_name);
783 base::string16 UserManagerImpl::GetUserDisplayName(
784 const std::string& user_id) const {
785 const User* user = FindUser(user_id);
786 return user ? user->display_name() : base::string16();
789 void UserManagerImpl::SaveUserDisplayEmail(const std::string& user_id,
790 const std::string& display_email) {
791 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
793 User* user = FindUserAndModify(user_id);
794 if (!user)
795 return; // Ignore if there is no such user.
797 user->set_display_email(display_email);
799 // Do not update local state if data stored or cached outside the user's
800 // cryptohome is to be treated as ephemeral.
801 if (IsUserNonCryptohomeDataEphemeral(user_id))
802 return;
804 PrefService* local_state = g_browser_process->local_state();
806 DictionaryPrefUpdate display_email_update(local_state, kUserDisplayEmail);
807 display_email_update->SetWithoutPathExpansion(
808 user_id,
809 new base::StringValue(display_email));
812 std::string UserManagerImpl::GetUserDisplayEmail(
813 const std::string& user_id) const {
814 const User* user = FindUser(user_id);
815 return user ? user->display_email() : user_id;
818 void UserManagerImpl::UpdateUserAccountData(
819 const std::string& user_id,
820 const UserAccountData& account_data) {
821 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
823 SaveUserDisplayName(user_id, account_data.display_name());
825 if (User* user = FindUserAndModify(user_id)) {
826 base::string16 given_name = account_data.given_name();
827 user->set_given_name(given_name);
828 if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
829 PrefService* local_state = g_browser_process->local_state();
831 DictionaryPrefUpdate given_name_update(local_state, kUserGivenName);
832 given_name_update->SetWithoutPathExpansion(
833 user_id,
834 new base::StringValue(given_name));
838 UpdateUserAccountLocale(user_id, account_data.locale());
841 // TODO(alemate): http://crbug.com/288941 : Respect preferred language list in
842 // the Google user profile.
844 // Returns true if callback will be called.
845 bool UserManagerImpl::RespectLocalePreference(
846 Profile* profile,
847 const User* user,
848 scoped_ptr<locale_util::SwitchLanguageCallback> callback) const {
849 if (g_browser_process == NULL)
850 return false;
851 if ((user == NULL) || (user != GetPrimaryUser()) ||
852 (!user->is_profile_created()))
853 return false;
855 // In case of Multi Profile mode we don't apply profile locale because it is
856 // unsafe.
857 if (GetLoggedInUsers().size() != 1)
858 return false;
859 const PrefService* prefs = profile->GetPrefs();
860 if (prefs == NULL)
861 return false;
863 std::string pref_locale;
864 const std::string pref_app_locale =
865 prefs->GetString(prefs::kApplicationLocale);
866 const std::string pref_bkup_locale =
867 prefs->GetString(prefs::kApplicationLocaleBackup);
869 pref_locale = pref_app_locale;
870 if (pref_locale.empty())
871 pref_locale = pref_bkup_locale;
873 const std::string* account_locale = NULL;
874 if (pref_locale.empty() && user->has_gaia_account()) {
875 if (user->GetAccountLocale() == NULL)
876 return false; // wait until Account profile is loaded.
877 account_locale = user->GetAccountLocale();
878 pref_locale = *account_locale;
880 const std::string global_app_locale =
881 g_browser_process->GetApplicationLocale();
882 if (pref_locale.empty())
883 pref_locale = global_app_locale;
884 DCHECK(!pref_locale.empty());
885 LOG(WARNING) << "RespectLocalePreference: "
886 << "app_locale='" << pref_app_locale << "', "
887 << "bkup_locale='" << pref_bkup_locale << "', "
888 << (account_locale != NULL
889 ? (std::string("account_locale='") + (*account_locale) +
890 "'. ")
891 : (std::string("account_locale - unused. ")))
892 << " Selected '" << pref_locale << "'";
893 profile->ChangeAppLocale(pref_locale, Profile::APP_LOCALE_CHANGED_VIA_LOGIN);
895 // Here we don't enable keyboard layouts for normal users. Input methods
896 // are set up when the user first logs in. Then the user may customize the
897 // input methods. Hence changing input methods here, just because the user's
898 // UI language is different from the login screen UI language, is not
899 // desirable. Note that input method preferences are synced, so users can use
900 // their farovite input methods as soon as the preferences are synced.
902 // For Guest mode, user locale preferences will never get initialized.
903 // So input methods should be enabled somewhere.
904 const bool enable_layouts = UserManager::Get()->IsLoggedInAsGuest();
905 locale_util::SwitchLanguage(pref_locale,
906 enable_layouts,
907 false /* login_layouts_only */,
908 callback.Pass());
910 return true;
913 void UserManagerImpl::StopPolicyObserverForTesting() {
914 avatar_policy_observer_.reset();
915 wallpaper_policy_observer_.reset();
918 void UserManagerImpl::Observe(int type,
919 const content::NotificationSource& source,
920 const content::NotificationDetails& details) {
921 switch (type) {
922 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED:
923 if (!device_local_account_policy_service_) {
924 policy::BrowserPolicyConnectorChromeOS* connector =
925 g_browser_process->platform_part()
926 ->browser_policy_connector_chromeos();
927 device_local_account_policy_service_ =
928 connector->GetDeviceLocalAccountPolicyService();
929 if (device_local_account_policy_service_)
930 device_local_account_policy_service_->AddObserver(this);
932 RetrieveTrustedDevicePolicies();
933 UpdateOwnership();
934 break;
935 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: {
936 Profile* profile = content::Details<Profile>(details).ptr();
937 if (IsUserLoggedIn() &&
938 !IsLoggedInAsGuest() &&
939 !IsLoggedInAsKioskApp()) {
940 if (IsLoggedInAsLocallyManagedUser())
941 ManagedUserPasswordServiceFactory::GetForProfile(profile);
942 if (IsLoggedInAsRegularUser())
943 ManagerPasswordServiceFactory::GetForProfile(profile);
945 if (!profile->IsOffTheRecord()) {
946 AuthSyncObserver* sync_observer =
947 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile);
948 sync_observer->StartObserving();
949 multi_profile_user_controller_->StartObserving(profile);
950 multi_profile_first_run_notification_->UserProfilePrepared(profile);
954 // Now that the user profile has been initialized and
955 // |GetNSSCertDatabaseForProfile| is safe to be used, get the NSS cert
956 // database for the primary user and start certificate loader with it.
957 if (IsUserLoggedIn() &&
958 GetPrimaryUser() &&
959 profile == GetProfileByUser(GetPrimaryUser()) &&
960 CertLoader::IsInitialized() &&
961 base::SysInfo::IsRunningOnChromeOS()) {
962 GetNSSCertDatabaseForProfile(profile,
963 base::Bind(&OnGetNSSCertDatabaseForUser));
965 break;
967 case chrome::NOTIFICATION_PROFILE_CREATED: {
968 Profile* profile = content::Source<Profile>(source).ptr();
969 User* user = GetUserByProfile(profile);
970 if (user != NULL)
971 user->set_profile_is_created();
973 break;
975 default:
976 NOTREACHED();
980 void UserManagerImpl::OnExternalDataSet(const std::string& policy,
981 const std::string& user_id) {
982 if (policy == policy::key::kUserAvatarImage)
983 GetUserImageManager(user_id)->OnExternalDataSet(policy);
984 else if (policy == policy::key::kWallpaperImage)
985 WallpaperManager::Get()->OnPolicySet(policy, user_id);
986 else
987 NOTREACHED();
990 void UserManagerImpl::OnExternalDataCleared(const std::string& policy,
991 const std::string& user_id) {
992 if (policy == policy::key::kUserAvatarImage)
993 GetUserImageManager(user_id)->OnExternalDataCleared(policy);
994 else if (policy == policy::key::kWallpaperImage)
995 WallpaperManager::Get()->OnPolicyCleared(policy, user_id);
996 else
997 NOTREACHED();
1000 void UserManagerImpl::OnExternalDataFetched(const std::string& policy,
1001 const std::string& user_id,
1002 scoped_ptr<std::string> data) {
1003 if (policy == policy::key::kUserAvatarImage)
1004 GetUserImageManager(user_id)->OnExternalDataFetched(policy, data.Pass());
1005 else if (policy == policy::key::kWallpaperImage)
1006 WallpaperManager::Get()->OnPolicyFetched(policy, user_id, data.Pass());
1007 else
1008 NOTREACHED();
1011 void UserManagerImpl::OnPolicyUpdated(const std::string& user_id) {
1012 UpdatePublicAccountDisplayName(user_id);
1013 NotifyUserListChanged();
1016 void UserManagerImpl::OnDeviceLocalAccountsChanged() {
1017 // No action needed here, changes to the list of device-local accounts get
1018 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
1021 bool UserManagerImpl::IsCurrentUserOwner() const {
1022 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1023 base::AutoLock lk(is_current_user_owner_lock_);
1024 return is_current_user_owner_;
1027 void UserManagerImpl::SetCurrentUserIsOwner(bool is_current_user_owner) {
1028 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1030 base::AutoLock lk(is_current_user_owner_lock_);
1031 is_current_user_owner_ = is_current_user_owner;
1033 UpdateLoginState();
1036 bool UserManagerImpl::IsCurrentUserNew() const {
1037 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1038 return is_current_user_new_;
1041 bool UserManagerImpl::IsCurrentUserNonCryptohomeDataEphemeral() const {
1042 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1043 return IsUserLoggedIn() &&
1044 IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email());
1047 bool UserManagerImpl::CanCurrentUserLock() const {
1048 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1049 return IsUserLoggedIn() && active_user_->can_lock() &&
1050 GetCurrentUserFlow()->CanLockScreen();
1053 bool UserManagerImpl::IsUserLoggedIn() const {
1054 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1055 return active_user_;
1058 bool UserManagerImpl::IsLoggedInAsRegularUser() const {
1059 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1060 return IsUserLoggedIn() &&
1061 active_user_->GetType() == User::USER_TYPE_REGULAR;
1064 bool UserManagerImpl::IsLoggedInAsDemoUser() const {
1065 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1066 return IsUserLoggedIn() &&
1067 active_user_->GetType() == User::USER_TYPE_RETAIL_MODE;
1070 bool UserManagerImpl::IsLoggedInAsPublicAccount() const {
1071 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1072 return IsUserLoggedIn() &&
1073 active_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
1076 bool UserManagerImpl::IsLoggedInAsGuest() const {
1077 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1078 return IsUserLoggedIn() &&
1079 active_user_->GetType() == User::USER_TYPE_GUEST;
1082 bool UserManagerImpl::IsLoggedInAsLocallyManagedUser() const {
1083 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1084 return IsUserLoggedIn() &&
1085 active_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED;
1088 bool UserManagerImpl::IsLoggedInAsKioskApp() const {
1089 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1090 return IsUserLoggedIn() &&
1091 active_user_->GetType() == User::USER_TYPE_KIOSK_APP;
1094 bool UserManagerImpl::IsLoggedInAsStub() const {
1095 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1096 return IsUserLoggedIn() && active_user_->email() == kStubUser;
1099 bool UserManagerImpl::IsSessionStarted() const {
1100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1101 return session_started_;
1104 bool UserManagerImpl::UserSessionsRestored() const {
1105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1106 return user_sessions_restored_;
1109 bool UserManagerImpl::HasBrowserRestarted() const {
1110 CommandLine* command_line = CommandLine::ForCurrentProcess();
1111 return base::SysInfo::IsRunningOnChromeOS() &&
1112 command_line->HasSwitch(switches::kLoginUser) &&
1113 !command_line->HasSwitch(switches::kLoginPassword);
1116 bool UserManagerImpl::IsUserNonCryptohomeDataEphemeral(
1117 const std::string& user_id) const {
1118 // Data belonging to the guest, retail mode and stub users is always
1119 // ephemeral.
1120 if (user_id == UserManager::kGuestUserName ||
1121 user_id == UserManager::kRetailModeUserName ||
1122 user_id == kStubUser) {
1123 return true;
1126 // Data belonging to the owner, anyone found on the user list and obsolete
1127 // public accounts whose data has not been removed yet is not ephemeral.
1128 if (user_id == owner_email_ || UserExistsInList(user_id) ||
1129 user_id == g_browser_process->local_state()->
1130 GetString(kPublicAccountPendingDataRemoval)) {
1131 return false;
1134 // Data belonging to the currently logged-in user is ephemeral when:
1135 // a) The user logged into a regular account while the ephemeral users policy
1136 // was enabled.
1137 // - or -
1138 // b) The user logged into any other account type.
1139 if (IsUserLoggedIn() && (user_id == GetLoggedInUser()->email()) &&
1140 (is_current_user_ephemeral_regular_user_ || !IsLoggedInAsRegularUser())) {
1141 return true;
1144 // Data belonging to any other user is ephemeral when:
1145 // a) Going through the regular login flow and the ephemeral users policy is
1146 // enabled.
1147 // - or -
1148 // b) The browser is restarting after a crash.
1149 return AreEphemeralUsersEnabled() || HasBrowserRestarted();
1152 void UserManagerImpl::AddObserver(UserManager::Observer* obs) {
1153 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1154 observer_list_.AddObserver(obs);
1157 void UserManagerImpl::RemoveObserver(UserManager::Observer* obs) {
1158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1159 observer_list_.RemoveObserver(obs);
1162 void UserManagerImpl::AddSessionStateObserver(
1163 UserManager::UserSessionStateObserver* obs) {
1164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1165 session_state_observer_list_.AddObserver(obs);
1168 void UserManagerImpl::RemoveSessionStateObserver(
1169 UserManager::UserSessionStateObserver* obs) {
1170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1171 session_state_observer_list_.RemoveObserver(obs);
1174 void UserManagerImpl::NotifyLocalStateChanged() {
1175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1176 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_,
1177 LocalStateChanged(this));
1180 void UserManagerImpl::OnProfilePrepared(Profile* profile) {
1181 LoginUtils::Get()->DoBrowserLaunch(profile,
1182 NULL); // host_, not needed here
1184 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) {
1185 // Did not log in (we crashed or are debugging), need to restore Sync.
1186 // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
1187 // users once it is fully multi-profile aware. http://crbug.com/238987
1188 // For now if we have other user pending sessions they'll override OAuth
1189 // session restore for previous users.
1190 LoginUtils::Get()->RestoreAuthenticationSession(profile);
1193 // Restore other user sessions if any.
1194 RestorePendingUserSessions();
1197 void UserManagerImpl::EnsureUsersLoaded() {
1198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1199 if (!g_browser_process || !g_browser_process->local_state())
1200 return;
1202 if (user_loading_stage_ != STAGE_NOT_LOADED)
1203 return;
1204 user_loading_stage_ = STAGE_LOADING;
1205 // Clean up user list first. All code down the path should be synchronous,
1206 // so that local state after transaction rollback is in consistent state.
1207 // This process also should not trigger EnsureUsersLoaded again.
1208 if (supervised_user_manager_->HasFailedUserCreationTransaction())
1209 supervised_user_manager_->RollbackUserCreationTransaction();
1211 PrefService* local_state = g_browser_process->local_state();
1212 const base::ListValue* prefs_regular_users =
1213 local_state->GetList(kRegularUsers);
1214 const base::ListValue* prefs_public_sessions =
1215 local_state->GetList(kPublicAccounts);
1216 const base::DictionaryValue* prefs_display_names =
1217 local_state->GetDictionary(kUserDisplayName);
1218 const base::DictionaryValue* prefs_given_names =
1219 local_state->GetDictionary(kUserGivenName);
1220 const base::DictionaryValue* prefs_display_emails =
1221 local_state->GetDictionary(kUserDisplayEmail);
1223 // Load public sessions first.
1224 std::vector<std::string> public_sessions;
1225 std::set<std::string> public_sessions_set;
1226 ParseUserList(*prefs_public_sessions, std::set<std::string>(),
1227 &public_sessions, &public_sessions_set);
1228 for (std::vector<std::string>::const_iterator it = public_sessions.begin();
1229 it != public_sessions.end(); ++it) {
1230 users_.push_back(User::CreatePublicAccountUser(*it));
1231 UpdatePublicAccountDisplayName(*it);
1234 // Load regular users and locally managed users.
1235 std::vector<std::string> regular_users;
1236 std::set<std::string> regular_users_set;
1237 ParseUserList(*prefs_regular_users, public_sessions_set,
1238 &regular_users, &regular_users_set);
1239 for (std::vector<std::string>::const_iterator it = regular_users.begin();
1240 it != regular_users.end(); ++it) {
1241 User* user = NULL;
1242 const std::string domain = gaia::ExtractDomainName(*it);
1243 if (domain == UserManager::kLocallyManagedUserDomain)
1244 user = User::CreateLocallyManagedUser(*it);
1245 else
1246 user = User::CreateRegularUser(*it);
1247 user->set_oauth_token_status(LoadUserOAuthStatus(*it));
1248 user->set_force_online_signin(LoadForceOnlineSignin(*it));
1249 users_.push_back(user);
1251 base::string16 display_name;
1252 if (prefs_display_names->GetStringWithoutPathExpansion(*it,
1253 &display_name)) {
1254 user->set_display_name(display_name);
1257 base::string16 given_name;
1258 if (prefs_given_names->GetStringWithoutPathExpansion(*it, &given_name)) {
1259 user->set_given_name(given_name);
1262 std::string display_email;
1263 if (prefs_display_emails->GetStringWithoutPathExpansion(*it,
1264 &display_email)) {
1265 user->set_display_email(display_email);
1269 user_loading_stage_ = STAGE_LOADED;
1271 for (UserList::iterator ui = users_.begin(), ue = users_.end();
1272 ui != ue; ++ui) {
1273 GetUserImageManager((*ui)->email())->LoadUserImage();
1277 void UserManagerImpl::RetrieveTrustedDevicePolicies() {
1278 ephemeral_users_enabled_ = false;
1279 owner_email_ = "";
1281 // Schedule a callback if device policy has not yet been verified.
1282 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
1283 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
1284 base::Unretained(this)))) {
1285 return;
1288 cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
1289 &ephemeral_users_enabled_);
1290 cros_settings_->GetString(kDeviceOwner, &owner_email_);
1292 EnsureUsersLoaded();
1294 bool changed = UpdateAndCleanUpPublicAccounts(
1295 policy::GetDeviceLocalAccounts(cros_settings_));
1297 // If ephemeral users are enabled and we are on the login screen, take this
1298 // opportunity to clean up by removing all regular users except the owner.
1299 if (ephemeral_users_enabled_ && !IsUserLoggedIn()) {
1300 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1301 kRegularUsers);
1302 prefs_users_update->Clear();
1303 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1304 const std::string user_email = (*it)->email();
1305 if ((*it)->GetType() == User::USER_TYPE_REGULAR &&
1306 user_email != owner_email_) {
1307 RemoveNonCryptohomeData(user_email);
1308 DeleteUser(*it);
1309 it = users_.erase(it);
1310 changed = true;
1311 } else {
1312 if ((*it)->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT)
1313 prefs_users_update->Append(new base::StringValue(user_email));
1314 ++it;
1319 if (changed)
1320 NotifyUserListChanged();
1323 bool UserManagerImpl::AreEphemeralUsersEnabled() const {
1324 policy::BrowserPolicyConnectorChromeOS* connector =
1325 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1326 return ephemeral_users_enabled_ &&
1327 (connector->IsEnterpriseManaged() || !owner_email_.empty());
1330 UserList& UserManagerImpl::GetUsersAndModify() {
1331 EnsureUsersLoaded();
1332 return users_;
1335 const User* UserManagerImpl::FindUserInList(const std::string& user_id) const {
1336 const UserList& users = GetUsers();
1337 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
1338 if ((*it)->email() == user_id)
1339 return *it;
1341 return NULL;
1344 const bool UserManagerImpl::UserExistsInList(const std::string& user_id) const {
1345 PrefService* local_state = g_browser_process->local_state();
1346 const base::ListValue* user_list = local_state->GetList(kRegularUsers);
1347 for (size_t i = 0; i < user_list->GetSize(); ++i) {
1348 std::string email;
1349 if (user_list->GetString(i, &email) && (user_id == email))
1350 return true;
1352 return false;
1355 User* UserManagerImpl::FindUserInListAndModify(const std::string& user_id) {
1356 UserList& users = GetUsersAndModify();
1357 for (UserList::iterator it = users.begin(); it != users.end(); ++it) {
1358 if ((*it)->email() == user_id)
1359 return *it;
1361 return NULL;
1364 void UserManagerImpl::GuestUserLoggedIn() {
1365 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1366 active_user_ = User::CreateGuestUser();
1367 // TODO(nkostylev): Add support for passing guest session cryptohome
1368 // mount point. Legacy (--login-profile) value will be used for now.
1369 // http://crosbug.com/230859
1370 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1371 // Initializes wallpaper after active_user_ is set.
1372 WallpaperManager::Get()->SetUserWallpaperNow(UserManager::kGuestUserName);
1375 void UserManagerImpl::AddUserRecord(User* user) {
1376 // Add the user to the front of the user list.
1377 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1378 kRegularUsers);
1379 prefs_users_update->Insert(0, new base::StringValue(user->email()));
1380 users_.insert(users_.begin(), user);
1383 void UserManagerImpl::RegularUserLoggedIn(const std::string& user_id) {
1384 // Remove the user from the user list.
1385 active_user_ = RemoveRegularOrLocallyManagedUserFromList(user_id);
1387 // If the user was not found on the user list, create a new user.
1388 is_current_user_new_ = !active_user_;
1389 if (!active_user_) {
1390 active_user_ = User::CreateRegularUser(user_id);
1391 active_user_->set_oauth_token_status(LoadUserOAuthStatus(user_id));
1392 SaveUserDisplayName(active_user_->email(),
1393 base::UTF8ToUTF16(active_user_->GetAccountName(true)));
1394 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1397 AddUserRecord(active_user_);
1399 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, false);
1401 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1403 // Make sure that new data is persisted to Local State.
1404 g_browser_process->local_state()->CommitPendingWrite();
1407 void UserManagerImpl::RegularUserLoggedInAsEphemeral(
1408 const std::string& user_id) {
1409 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1410 is_current_user_new_ = true;
1411 is_current_user_ephemeral_regular_user_ = true;
1412 active_user_ = User::CreateRegularUser(user_id);
1413 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, false);
1414 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1417 void UserManagerImpl::LocallyManagedUserLoggedIn(
1418 const std::string& user_id) {
1419 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
1421 // Remove the user from the user list.
1422 active_user_ = RemoveRegularOrLocallyManagedUserFromList(user_id);
1423 // If the user was not found on the user list, create a new user.
1424 if (!active_user_) {
1425 is_current_user_new_ = true;
1426 active_user_ = User::CreateLocallyManagedUser(user_id);
1427 // Leaving OAuth token status at the default state = unknown.
1428 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1429 } else {
1430 if (supervised_user_manager_->CheckForFirstRun(user_id)) {
1431 is_current_user_new_ = true;
1432 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1433 } else {
1434 is_current_user_new_ = false;
1438 // Add the user to the front of the user list.
1439 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1440 kRegularUsers);
1441 prefs_users_update->Insert(0, new base::StringValue(user_id));
1442 users_.insert(users_.begin(), active_user_);
1444 // Now that user is in the list, save display name.
1445 if (is_current_user_new_) {
1446 SaveUserDisplayName(active_user_->email(),
1447 active_user_->GetDisplayName());
1450 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, true);
1451 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1453 // Make sure that new data is persisted to Local State.
1454 g_browser_process->local_state()->CommitPendingWrite();
1457 void UserManagerImpl::PublicAccountUserLoggedIn(User* user) {
1458 is_current_user_new_ = true;
1459 active_user_ = user;
1460 // The UserImageManager chooses a random avatar picture when a user logs in
1461 // for the first time. Tell the UserImageManager that this user is not new to
1462 // prevent the avatar from getting changed.
1463 GetUserImageManager(user->email())->UserLoggedIn(false, true);
1464 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1467 void UserManagerImpl::KioskAppLoggedIn(const std::string& app_id) {
1468 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1469 policy::DeviceLocalAccount::Type device_local_account_type;
1470 DCHECK(policy::IsDeviceLocalAccountUser(app_id,
1471 &device_local_account_type));
1472 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
1473 device_local_account_type);
1475 active_user_ = User::CreateKioskAppUser(app_id);
1476 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1478 WallpaperManager::Get()->SetUserWallpaperNow(app_id);
1480 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
1481 // the kiosk_app_id in these objects, removing the need to re-parse the
1482 // device-local account list here to extract the kiosk_app_id.
1483 const std::vector<policy::DeviceLocalAccount> device_local_accounts =
1484 policy::GetDeviceLocalAccounts(cros_settings_);
1485 const policy::DeviceLocalAccount* account = NULL;
1486 for (std::vector<policy::DeviceLocalAccount>::const_iterator
1487 it = device_local_accounts.begin();
1488 it != device_local_accounts.end(); ++it) {
1489 if (it->user_id == app_id) {
1490 account = &*it;
1491 break;
1494 std::string kiosk_app_id;
1495 if (account) {
1496 kiosk_app_id = account->kiosk_app_id;
1497 } else {
1498 LOG(ERROR) << "Logged into nonexistent kiosk-app account: " << app_id;
1499 NOTREACHED();
1502 CommandLine* command_line = CommandLine::ForCurrentProcess();
1503 command_line->AppendSwitch(::switches::kForceAppMode);
1504 command_line->AppendSwitchASCII(::switches::kAppId, kiosk_app_id);
1506 // Disable window animation since kiosk app runs in a single full screen
1507 // window and window animation causes start-up janks.
1508 command_line->AppendSwitch(
1509 wm::switches::kWindowAnimationsDisabled);
1512 void UserManagerImpl::DemoAccountLoggedIn() {
1513 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1514 active_user_ = User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName);
1515 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1516 WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName);
1518 // Disable window animation since the demo app runs in a single full screen
1519 // window and window animation causes start-up janks.
1520 CommandLine::ForCurrentProcess()->AppendSwitch(
1521 wm::switches::kWindowAnimationsDisabled);
1524 void UserManagerImpl::RetailModeUserLoggedIn() {
1525 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1526 is_current_user_new_ = true;
1527 active_user_ = User::CreateRetailModeUser();
1528 GetUserImageManager(UserManager::kRetailModeUserName)->UserLoggedIn(
1529 is_current_user_new_,
1530 true);
1531 WallpaperManager::Get()->SetUserWallpaperNow(
1532 UserManager::kRetailModeUserName);
1535 void UserManagerImpl::NotifyOnLogin() {
1536 UpdateNumberOfUsers();
1537 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1538 NotifyActiveUserHashChanged(active_user_->username_hash());
1539 NotifyActiveUserChanged(active_user_);
1541 UpdateLoginState();
1542 // TODO(nkostylev): Deprecate this notification in favor of
1543 // ActiveUserChanged() observer call.
1544 content::NotificationService::current()->Notify(
1545 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
1546 content::Source<UserManager>(this),
1547 content::Details<const User>(active_user_));
1549 // Owner must be first user in session. DeviceSettingsService can't deal with
1550 // multiple user and will mix up ownership, crbug.com/230018.
1551 if (GetLoggedInUsers().size() == 1) {
1552 // Indicate to DeviceSettingsService that the owner key may have become
1553 // available.
1554 DeviceSettingsService::Get()->SetUsername(active_user_->email());
1558 User::OAuthTokenStatus UserManagerImpl::LoadUserOAuthStatus(
1559 const std::string& user_id) const {
1560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1562 PrefService* local_state = g_browser_process->local_state();
1563 const base::DictionaryValue* prefs_oauth_status =
1564 local_state->GetDictionary(kUserOAuthTokenStatus);
1565 int oauth_token_status = User::OAUTH_TOKEN_STATUS_UNKNOWN;
1566 if (prefs_oauth_status &&
1567 prefs_oauth_status->GetIntegerWithoutPathExpansion(
1568 user_id, &oauth_token_status)) {
1569 User::OAuthTokenStatus result =
1570 static_cast<User::OAuthTokenStatus>(oauth_token_status);
1571 if (result == User::OAUTH2_TOKEN_STATUS_INVALID)
1572 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(result);
1573 return result;
1575 return User::OAUTH_TOKEN_STATUS_UNKNOWN;
1578 bool UserManagerImpl::LoadForceOnlineSignin(const std::string& user_id) const {
1579 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1581 PrefService* local_state = g_browser_process->local_state();
1582 const base::DictionaryValue* prefs_force_online =
1583 local_state->GetDictionary(kUserForceOnlineSignin);
1584 bool force_online_signin = false;
1585 if (prefs_force_online) {
1586 prefs_force_online->GetBooleanWithoutPathExpansion(user_id,
1587 &force_online_signin);
1589 return force_online_signin;
1592 void UserManagerImpl::UpdateOwnership() {
1593 bool is_owner = DeviceSettingsService::Get()->HasPrivateOwnerKey();
1594 VLOG(1) << "Current user " << (is_owner ? "is owner" : "is not owner");
1596 SetCurrentUserIsOwner(is_owner);
1599 void UserManagerImpl::RemoveNonCryptohomeData(const std::string& user_id) {
1600 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id);
1601 GetUserImageManager(user_id)->DeleteUserImage();
1603 PrefService* prefs = g_browser_process->local_state();
1604 DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
1605 prefs_display_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1607 DictionaryPrefUpdate prefs_given_name_update(prefs, kUserGivenName);
1608 prefs_given_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1610 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
1611 prefs_display_email_update->RemoveWithoutPathExpansion(user_id, NULL);
1613 DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
1614 prefs_oauth_update->RemoveWithoutPathExpansion(user_id, NULL);
1616 DictionaryPrefUpdate prefs_force_online_update(prefs, kUserForceOnlineSignin);
1617 prefs_force_online_update->RemoveWithoutPathExpansion(user_id, NULL);
1619 supervised_user_manager_->RemoveNonCryptohomeData(user_id);
1621 multi_profile_user_controller_->RemoveCachedValues(user_id);
1624 User* UserManagerImpl::RemoveRegularOrLocallyManagedUserFromList(
1625 const std::string& user_id) {
1626 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1627 kRegularUsers);
1628 prefs_users_update->Clear();
1629 User* user = NULL;
1630 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1631 const std::string user_email = (*it)->email();
1632 if (user_email == user_id) {
1633 user = *it;
1634 it = users_.erase(it);
1635 } else {
1636 if ((*it)->GetType() == User::USER_TYPE_REGULAR ||
1637 (*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) {
1638 prefs_users_update->Append(new base::StringValue(user_email));
1640 ++it;
1643 return user;
1646 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
1647 PrefService* local_state = g_browser_process->local_state();
1648 const std::string public_account_pending_data_removal =
1649 local_state->GetString(kPublicAccountPendingDataRemoval);
1650 if (public_account_pending_data_removal.empty() ||
1651 (IsUserLoggedIn() &&
1652 public_account_pending_data_removal == GetActiveUser()->email())) {
1653 return;
1656 RemoveNonCryptohomeData(public_account_pending_data_removal);
1657 local_state->ClearPref(kPublicAccountPendingDataRemoval);
1660 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
1661 const std::vector<std::string>& old_public_accounts) {
1662 std::set<std::string> users;
1663 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it)
1664 users.insert((*it)->email());
1666 // If the user is logged into a public account that has been removed from the
1667 // user list, mark the account's data as pending removal after logout.
1668 if (IsLoggedInAsPublicAccount()) {
1669 const std::string active_user_id = GetActiveUser()->email();
1670 if (users.find(active_user_id) == users.end()) {
1671 g_browser_process->local_state()->SetString(
1672 kPublicAccountPendingDataRemoval, active_user_id);
1673 users.insert(active_user_id);
1677 // Remove the data belonging to any other public accounts that are no longer
1678 // found on the user list.
1679 for (std::vector<std::string>::const_iterator
1680 it = old_public_accounts.begin();
1681 it != old_public_accounts.end(); ++it) {
1682 if (users.find(*it) == users.end())
1683 RemoveNonCryptohomeData(*it);
1687 bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
1688 const std::vector<policy::DeviceLocalAccount>& device_local_accounts) {
1689 // Try to remove any public account data marked as pending removal.
1690 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
1692 // Get the current list of public accounts.
1693 std::vector<std::string> old_public_accounts;
1694 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it) {
1695 if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT)
1696 old_public_accounts.push_back((*it)->email());
1699 // Get the new list of public accounts from policy.
1700 std::vector<std::string> new_public_accounts;
1701 for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
1702 device_local_accounts.begin();
1703 it != device_local_accounts.end(); ++it) {
1704 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
1705 // standard login framework: http://crbug.com/234694
1706 if (it->type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
1707 new_public_accounts.push_back(it->user_id);
1710 // If the list of public accounts has not changed, return.
1711 if (new_public_accounts.size() == old_public_accounts.size()) {
1712 bool changed = false;
1713 for (size_t i = 0; i < new_public_accounts.size(); ++i) {
1714 if (new_public_accounts[i] != old_public_accounts[i]) {
1715 changed = true;
1716 break;
1719 if (!changed)
1720 return false;
1723 // Persist the new list of public accounts in a pref.
1724 ListPrefUpdate prefs_public_accounts_update(g_browser_process->local_state(),
1725 kPublicAccounts);
1726 prefs_public_accounts_update->Clear();
1727 for (std::vector<std::string>::const_iterator it =
1728 new_public_accounts.begin();
1729 it != new_public_accounts.end(); ++it) {
1730 prefs_public_accounts_update->AppendString(*it);
1733 // Remove the old public accounts from the user list.
1734 for (UserList::iterator it = users_.begin(); it != users_.end();) {
1735 if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
1736 if (*it != GetLoggedInUser())
1737 DeleteUser(*it);
1738 it = users_.erase(it);
1739 } else {
1740 ++it;
1744 // Add the new public accounts to the front of the user list.
1745 for (std::vector<std::string>::const_reverse_iterator it =
1746 new_public_accounts.rbegin();
1747 it != new_public_accounts.rend(); ++it) {
1748 if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email())
1749 users_.insert(users_.begin(), GetLoggedInUser());
1750 else
1751 users_.insert(users_.begin(), User::CreatePublicAccountUser(*it));
1752 UpdatePublicAccountDisplayName(*it);
1755 for (UserList::iterator ui = users_.begin(),
1756 ue = users_.begin() + new_public_accounts.size();
1757 ui != ue; ++ui) {
1758 GetUserImageManager((*ui)->email())->LoadUserImage();
1761 // Remove data belonging to public accounts that are no longer found on the
1762 // user list.
1763 CleanUpPublicAccountNonCryptohomeData(old_public_accounts);
1765 return true;
1768 void UserManagerImpl::UpdatePublicAccountDisplayName(
1769 const std::string& user_id) {
1770 std::string display_name;
1772 if (device_local_account_policy_service_) {
1773 policy::DeviceLocalAccountPolicyBroker* broker =
1774 device_local_account_policy_service_->GetBrokerForUser(user_id);
1775 if (broker)
1776 display_name = broker->GetDisplayName();
1779 // Set or clear the display name.
1780 SaveUserDisplayName(user_id, base::UTF8ToUTF16(display_name));
1783 UserFlow* UserManagerImpl::GetCurrentUserFlow() const {
1784 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1785 if (!IsUserLoggedIn())
1786 return GetDefaultUserFlow();
1787 return GetUserFlow(GetLoggedInUser()->email());
1790 UserFlow* UserManagerImpl::GetUserFlow(const std::string& user_id) const {
1791 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1792 FlowMap::const_iterator it = specific_flows_.find(user_id);
1793 if (it != specific_flows_.end())
1794 return it->second;
1795 return GetDefaultUserFlow();
1798 void UserManagerImpl::SetUserFlow(const std::string& user_id, UserFlow* flow) {
1799 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1800 ResetUserFlow(user_id);
1801 specific_flows_[user_id] = flow;
1804 void UserManagerImpl::ResetUserFlow(const std::string& user_id) {
1805 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1806 FlowMap::iterator it = specific_flows_.find(user_id);
1807 if (it != specific_flows_.end()) {
1808 delete it->second;
1809 specific_flows_.erase(it);
1813 bool UserManagerImpl::GetAppModeChromeClientOAuthInfo(
1814 std::string* chrome_client_id, std::string* chrome_client_secret) {
1815 if (!chrome::IsRunningInForcedAppMode() ||
1816 chrome_client_id_.empty() ||
1817 chrome_client_secret_.empty()) {
1818 return false;
1821 *chrome_client_id = chrome_client_id_;
1822 *chrome_client_secret = chrome_client_secret_;
1823 return true;
1826 void UserManagerImpl::SetAppModeChromeClientOAuthInfo(
1827 const std::string& chrome_client_id,
1828 const std::string& chrome_client_secret) {
1829 if (!chrome::IsRunningInForcedAppMode())
1830 return;
1832 chrome_client_id_ = chrome_client_id;
1833 chrome_client_secret_ = chrome_client_secret;
1836 bool UserManagerImpl::AreLocallyManagedUsersAllowed() const {
1837 bool locally_managed_users_allowed = false;
1838 cros_settings_->GetBoolean(kAccountsPrefSupervisedUsersEnabled,
1839 &locally_managed_users_allowed);
1840 policy::BrowserPolicyConnectorChromeOS* connector =
1841 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1842 return locally_managed_users_allowed || !connector->IsEnterpriseManaged();
1845 base::FilePath UserManagerImpl::GetUserProfileDir(
1846 const std::string& user_id) const {
1847 // TODO(dpolukhin): Remove Chrome OS specific profile path logic from
1848 // ProfileManager and use only this function to construct profile path.
1849 // TODO(nkostylev): Cleanup profile dir related code paths crbug.com/294233
1850 base::FilePath profile_dir;
1851 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1852 if (command_line.HasSwitch(::switches::kMultiProfiles)) {
1853 const User* user = FindUser(user_id);
1854 if (user && !user->username_hash().empty())
1855 profile_dir = ProfileHelper::GetUserProfileDir(user->username_hash());
1856 } else if (command_line.HasSwitch(chromeos::switches::kLoginProfile)) {
1857 profile_dir = ProfileHelper::GetProfileDirByLegacyLoginProfileSwitch();
1858 } else {
1859 // We should never be logged in with no profile dir unless
1860 // multi-profiles are enabled.
1861 NOTREACHED();
1862 profile_dir = base::FilePath();
1865 ProfileManager* profile_manager = g_browser_process->profile_manager();
1866 profile_dir = profile_manager->user_data_dir().Append(profile_dir);
1868 return profile_dir;
1871 UserFlow* UserManagerImpl::GetDefaultUserFlow() const {
1872 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1873 if (!default_flow_.get())
1874 default_flow_.reset(new DefaultUserFlow());
1875 return default_flow_.get();
1878 void UserManagerImpl::NotifyUserListChanged() {
1879 content::NotificationService::current()->Notify(
1880 chrome::NOTIFICATION_USER_LIST_CHANGED,
1881 content::Source<UserManager>(this),
1882 content::NotificationService::NoDetails());
1885 void UserManagerImpl::NotifyActiveUserChanged(const User* active_user) {
1886 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1887 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1888 session_state_observer_list_,
1889 ActiveUserChanged(active_user));
1892 void UserManagerImpl::NotifyUserAddedToSession(const User* added_user) {
1893 UpdateNumberOfUsers();
1894 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1895 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1896 session_state_observer_list_,
1897 UserAddedToSession(added_user));
1900 void UserManagerImpl::NotifyActiveUserHashChanged(const std::string& hash) {
1901 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1902 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1903 session_state_observer_list_,
1904 ActiveUserHashChanged(hash));
1907 void UserManagerImpl::NotifyPendingUserSessionsRestoreFinished() {
1908 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1909 user_sessions_restored_ = true;
1910 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1911 session_state_observer_list_,
1912 PendingUserSessionsRestoreFinished());
1915 void UserManagerImpl::UpdateLoginState() {
1916 if (!LoginState::IsInitialized())
1917 return; // LoginState may not be intialized in tests.
1918 LoginState::LoggedInState logged_in_state;
1919 logged_in_state = active_user_ ? LoginState::LOGGED_IN_ACTIVE
1920 : LoginState::LOGGED_IN_NONE;
1922 LoginState::LoggedInUserType login_user_type;
1923 if (logged_in_state == LoginState::LOGGED_IN_NONE)
1924 login_user_type = LoginState::LOGGED_IN_USER_NONE;
1925 else if (is_current_user_owner_)
1926 login_user_type = LoginState::LOGGED_IN_USER_OWNER;
1927 else if (active_user_->GetType() == User::USER_TYPE_GUEST)
1928 login_user_type = LoginState::LOGGED_IN_USER_GUEST;
1929 else if (active_user_->GetType() == User::USER_TYPE_RETAIL_MODE)
1930 login_user_type = LoginState::LOGGED_IN_USER_RETAIL_MODE;
1931 else if (active_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT)
1932 login_user_type = LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT;
1933 else if (active_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED)
1934 login_user_type = LoginState::LOGGED_IN_USER_LOCALLY_MANAGED;
1935 else if (active_user_->GetType() == User::USER_TYPE_KIOSK_APP)
1936 login_user_type = LoginState::LOGGED_IN_USER_KIOSK_APP;
1937 else
1938 login_user_type = LoginState::LOGGED_IN_USER_REGULAR;
1940 LoginState::Get()->SetLoggedInState(logged_in_state, login_user_type);
1943 void UserManagerImpl::SetLRUUser(User* user) {
1944 UserList::iterator it = std::find(lru_logged_in_users_.begin(),
1945 lru_logged_in_users_.end(),
1946 user);
1947 if (it != lru_logged_in_users_.end())
1948 lru_logged_in_users_.erase(it);
1949 lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user);
1952 void UserManagerImpl::OnRestoreActiveSessions(
1953 const SessionManagerClient::ActiveSessionsMap& sessions,
1954 bool success) {
1955 if (!success) {
1956 LOG(ERROR) << "Could not get list of active user sessions after crash.";
1957 // If we could not get list of active user sessions it is safer to just
1958 // sign out so that we don't get in the inconsistent state.
1959 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
1960 return;
1963 // One profile has been already loaded on browser start.
1964 DCHECK(GetLoggedInUsers().size() == 1);
1965 DCHECK(GetActiveUser());
1966 std::string active_user_id = GetActiveUser()->email();
1968 SessionManagerClient::ActiveSessionsMap::const_iterator it;
1969 for (it = sessions.begin(); it != sessions.end(); ++it) {
1970 if (active_user_id == it->first)
1971 continue;
1972 pending_user_sessions_[it->first] = it->second;
1974 RestorePendingUserSessions();
1977 void UserManagerImpl::RestorePendingUserSessions() {
1978 if (pending_user_sessions_.empty()) {
1979 NotifyPendingUserSessionsRestoreFinished();
1980 return;
1983 // Get next user to restore sessions and delete it from list.
1984 SessionManagerClient::ActiveSessionsMap::const_iterator it =
1985 pending_user_sessions_.begin();
1986 std::string user_id = it->first;
1987 std::string user_id_hash = it->second;
1988 DCHECK(!user_id.empty());
1989 DCHECK(!user_id_hash.empty());
1990 pending_user_sessions_.erase(user_id);
1992 // Check that this user is not logged in yet.
1993 UserList logged_in_users = GetLoggedInUsers();
1994 bool user_already_logged_in = false;
1995 for (UserList::const_iterator it = logged_in_users.begin();
1996 it != logged_in_users.end(); ++it) {
1997 const User* user = (*it);
1998 if (user->email() == user_id) {
1999 user_already_logged_in = true;
2000 break;
2003 DCHECK(!user_already_logged_in);
2005 if (!user_already_logged_in) {
2006 // Will call OnProfilePrepared() once profile has been loaded.
2007 LoginUtils::Get()->PrepareProfile(
2008 UserContext(user_id,
2009 std::string(), // password
2010 std::string(), // auth_code
2011 user_id_hash,
2012 false, // using_oauth
2013 UserContext::AUTH_FLOW_OFFLINE),
2014 std::string(), // display_email
2015 false, // has_cookies
2016 true, // has_active_session
2017 this);
2018 } else {
2019 RestorePendingUserSessions();
2023 void UserManagerImpl::SendRegularUserLoginMetrics(const std::string& user_id) {
2024 // If this isn't the first time Chrome was run after the system booted,
2025 // assume that Chrome was restarted because a previous session ended.
2026 if (!CommandLine::ForCurrentProcess()->HasSwitch(
2027 switches::kFirstExecAfterBoot)) {
2028 const std::string last_email =
2029 g_browser_process->local_state()->GetString(kLastLoggedInRegularUser);
2030 const base::TimeDelta time_to_login =
2031 base::TimeTicks::Now() - manager_creation_time_;
2032 if (!last_email.empty() && user_id != last_email &&
2033 time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) {
2034 UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay",
2035 time_to_login.InSeconds(), 0, kLogoutToLoginDelayMaxSec, 50);
2040 void UserManagerImpl::OnUserNotAllowed(const std::string& user_email) {
2041 LOG(ERROR) << "Shutdown session because a user is not allowed to be in the "
2042 "current session";
2043 chromeos::ShowMultiprofilesSessionAbortedDialog(user_email);
2046 void UserManagerImpl::UpdateUserAccountLocale(const std::string& user_id,
2047 const std::string& locale) {
2048 if (!locale.empty() &&
2049 locale != g_browser_process->GetApplicationLocale()) {
2050 BrowserThread::PostBlockingPoolTask(
2051 FROM_HERE,
2052 base::Bind(ResolveLocale, locale,
2053 base::Bind(&UserManagerImpl::DoUpdateAccountLocale,
2054 base::Unretained(this),
2055 user_id)));
2056 } else {
2057 DoUpdateAccountLocale(user_id, locale);
2061 void UserManagerImpl::DoUpdateAccountLocale(
2062 const std::string& user_id,
2063 const std::string& resolved_locale) {
2064 if (User* user = FindUserAndModify(user_id))
2065 user->SetAccountLocale(resolved_locale);
2068 void UserManagerImpl::UpdateNumberOfUsers() {
2069 size_t users = GetLoggedInUsers().size();
2070 if (users) {
2071 // Write the user number as UMA stat when a multi user session is possible.
2072 if ((users + GetUsersAdmittedForMultiProfile().size()) > 1)
2073 ash::MultiProfileUMA::RecordUserCount(users);
2076 base::debug::SetCrashKeyValue(crash_keys::kNumberOfUsers,
2077 base::StringPrintf("%" PRIuS, GetLoggedInUsers().size()));
2080 void UserManagerImpl::DeleteUser(User* user) {
2081 const bool is_active_user = (user == active_user_);
2082 delete user;
2083 if (is_active_user)
2084 active_user_ = NULL;
2087 } // namespace chromeos