Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / chromeos / login / user_manager_impl.cc
blob7f27162939a9bfc15504455f5649e9d745ee8804
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_user_controller.h"
39 #include "chrome/browser/chromeos/login/remove_user_delegate.h"
40 #include "chrome/browser/chromeos/login/supervised_user_manager_impl.h"
41 #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
42 #include "chrome/browser/chromeos/login/wizard_controller.h"
43 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
44 #include "chrome/browser/chromeos/policy/device_local_account.h"
45 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog.h"
46 #include "chrome/browser/chromeos/profiles/profile_helper.h"
47 #include "chrome/browser/chromeos/session_length_limiter.h"
48 #include "chrome/browser/managed_mode/chromeos/managed_user_password_service_factory.h"
49 #include "chrome/browser/managed_mode/chromeos/manager_password_service_factory.h"
50 #include "chrome/browser/net/nss_context.h"
51 #include "chrome/browser/profiles/profile.h"
52 #include "chrome/browser/profiles/profile_manager.h"
53 #include "chrome/browser/sync/profile_sync_service.h"
54 #include "chrome/browser/sync/profile_sync_service_factory.h"
55 #include "chrome/common/chrome_constants.h"
56 #include "chrome/common/chrome_switches.h"
57 #include "chrome/common/crash_keys.h"
58 #include "chrome/common/pref_names.h"
59 #include "chromeos/cert_loader.h"
60 #include "chromeos/chromeos_switches.h"
61 #include "chromeos/cryptohome/async_method_caller.h"
62 #include "chromeos/dbus/dbus_thread_manager.h"
63 #include "chromeos/login/login_state.h"
64 #include "chromeos/settings/cros_settings_names.h"
65 #include "content/public/browser/browser_thread.h"
66 #include "content/public/browser/notification_service.h"
67 #include "google_apis/gaia/gaia_auth_util.h"
68 #include "google_apis/gaia/google_service_auth_error.h"
69 #include "policy/policy_constants.h"
70 #include "ui/base/l10n/l10n_util.h"
71 #include "ui/wm/core/wm_core_switches.h"
73 using content::BrowserThread;
75 namespace chromeos {
76 namespace {
78 // A vector pref of the the regular users known on this device, arranged in LRU
79 // order.
80 const char kRegularUsers[] = "LoggedInUsers";
82 // A vector pref of the public accounts defined on this device.
83 const char kPublicAccounts[] = "PublicAccounts";
85 // A string pref that gets set when a public account is removed but a user is
86 // currently logged into that account, requiring the account's data to be
87 // removed after logout.
88 const char kPublicAccountPendingDataRemoval[] =
89 "PublicAccountPendingDataRemoval";
91 // A dictionary that maps user IDs to the displayed name.
92 const char kUserDisplayName[] = "UserDisplayName";
94 // A dictionary that maps user IDs to the user's given name.
95 const char kUserGivenName[] = "UserGivenName";
97 // A dictionary that maps user IDs to the displayed (non-canonical) emails.
98 const char kUserDisplayEmail[] = "UserDisplayEmail";
100 // A dictionary that maps user IDs to OAuth token presence flag.
101 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus";
103 // A dictionary that maps user IDs to a flag indicating whether online
104 // authentication against GAIA should be enforced during the next sign-in.
105 const char kUserForceOnlineSignin[] = "UserForceOnlineSignin";
107 // A string pref containing the ID of the last user who logged in if it was
108 // a regular user or an empty string if it was another type of user (guest,
109 // kiosk, public account, etc.).
110 const char kLastLoggedInRegularUser[] = "LastLoggedInRegularUser";
112 // Upper bound for a histogram metric reporting the amount of time between
113 // one regular user logging out and a different regular user logging in.
114 const int kLogoutToLoginDelayMaxSec = 1800;
116 // Callback that is called after user removal is complete.
117 void OnRemoveUserComplete(const std::string& user_email,
118 bool success,
119 cryptohome::MountError return_code) {
120 // Log the error, but there's not much we can do.
121 if (!success) {
122 LOG(ERROR) << "Removal of cryptohome for " << user_email
123 << " failed, return code: " << return_code;
127 // Helper function that copies users from |users_list| to |users_vector| and
128 // |users_set|. Duplicates and users already present in |existing_users| are
129 // skipped.
130 void ParseUserList(const base::ListValue& users_list,
131 const std::set<std::string>& existing_users,
132 std::vector<std::string>* users_vector,
133 std::set<std::string>* users_set) {
134 users_vector->clear();
135 users_set->clear();
136 for (size_t i = 0; i < users_list.GetSize(); ++i) {
137 std::string email;
138 if (!users_list.GetString(i, &email) || email.empty()) {
139 LOG(ERROR) << "Corrupt entry in user list at index " << i << ".";
140 continue;
142 if (existing_users.find(email) != existing_users.end() ||
143 !users_set->insert(email).second) {
144 LOG(ERROR) << "Duplicate user: " << email;
145 continue;
147 users_vector->push_back(email);
151 class UserHashMatcher {
152 public:
153 explicit UserHashMatcher(const std::string& h) : username_hash(h) {}
154 bool operator()(const User* user) const {
155 return user->username_hash() == username_hash;
158 private:
159 const std::string& username_hash;
162 // Runs on SequencedWorkerPool thread. Passes resolved locale to
163 // |on_resolve_callback| on UI thread.
164 void ResolveLocale(
165 const std::string& raw_locale,
166 base::Callback<void(const std::string&)> on_resolve_callback) {
167 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
168 std::string resolved_locale;
169 // Ignore result
170 l10n_util::CheckAndResolveLocale(raw_locale, &resolved_locale);
171 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
172 base::Bind(on_resolve_callback, resolved_locale));
175 // Callback to GetNSSCertDatabaseForProfile. It starts CertLoader using the
176 // provided NSS database. It must be called for primary user only.
177 void OnGetNSSCertDatabaseForUser(net::NSSCertDatabase* database) {
178 if (!CertLoader::IsInitialized())
179 return;
181 CertLoader::Get()->StartWithNSSDB(database);
184 } // namespace
186 // static
187 void UserManager::RegisterPrefs(PrefRegistrySimple* registry) {
188 registry->RegisterListPref(kRegularUsers);
189 registry->RegisterListPref(kPublicAccounts);
190 registry->RegisterStringPref(kPublicAccountPendingDataRemoval, "");
191 registry->RegisterStringPref(kLastLoggedInRegularUser, "");
192 registry->RegisterDictionaryPref(kUserDisplayName);
193 registry->RegisterDictionaryPref(kUserGivenName);
194 registry->RegisterDictionaryPref(kUserDisplayEmail);
195 registry->RegisterDictionaryPref(kUserOAuthTokenStatus);
196 registry->RegisterDictionaryPref(kUserForceOnlineSignin);
197 SupervisedUserManager::RegisterPrefs(registry);
198 SessionLengthLimiter::RegisterPrefs(registry);
201 UserManagerImpl::UserManagerImpl()
202 : cros_settings_(CrosSettings::Get()),
203 device_local_account_policy_service_(NULL),
204 user_loading_stage_(STAGE_NOT_LOADED),
205 active_user_(NULL),
206 primary_user_(NULL),
207 session_started_(false),
208 user_sessions_restored_(false),
209 is_current_user_owner_(false),
210 is_current_user_new_(false),
211 is_current_user_ephemeral_regular_user_(false),
212 ephemeral_users_enabled_(false),
213 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
214 manager_creation_time_(base::TimeTicks::Now()) {
215 UpdateNumberOfUsers();
216 // UserManager instance should be used only on UI thread.
217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
218 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
219 content::NotificationService::AllSources());
220 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
221 content::NotificationService::AllSources());
222 registrar_.Add(this,
223 chrome::NOTIFICATION_PROFILE_CREATED,
224 content::NotificationService::AllSources());
225 RetrieveTrustedDevicePolicies();
226 local_accounts_subscription_ = cros_settings_->AddSettingsObserver(
227 kAccountsPrefDeviceLocalAccounts,
228 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
229 base::Unretained(this)));
230 supervised_users_subscription_ = cros_settings_->AddSettingsObserver(
231 kAccountsPrefSupervisedUsersEnabled,
232 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
233 base::Unretained(this)));
234 multi_profile_user_controller_.reset(new MultiProfileUserController(
235 this, g_browser_process->local_state()));
237 policy::BrowserPolicyConnectorChromeOS* connector =
238 g_browser_process->platform_part()->browser_policy_connector_chromeos();
239 avatar_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
240 cros_settings_,
241 this,
242 connector->GetDeviceLocalAccountPolicyService(),
243 policy::key::kUserAvatarImage,
244 this));
245 avatar_policy_observer_->Init();
247 wallpaper_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
248 cros_settings_,
249 this,
250 connector->GetDeviceLocalAccountPolicyService(),
251 policy::key::kWallpaperImage,
252 this));
253 wallpaper_policy_observer_->Init();
255 UpdateLoginState();
258 UserManagerImpl::~UserManagerImpl() {
259 // Can't use STLDeleteElements because of the private destructor of User.
260 for (UserList::iterator it = users_.begin(); it != users_.end();
261 it = users_.erase(it)) {
262 DeleteUser(*it);
264 // These are pointers to the same User instances that were in users_ list.
265 logged_in_users_.clear();
266 lru_logged_in_users_.clear();
268 DeleteUser(active_user_);
271 void UserManagerImpl::Shutdown() {
272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
273 local_accounts_subscription_.reset();
274 supervised_users_subscription_.reset();
275 // Stop the session length limiter.
276 session_length_limiter_.reset();
278 if (device_local_account_policy_service_)
279 device_local_account_policy_service_->RemoveObserver(this);
281 for (UserImageManagerMap::iterator it = user_image_managers_.begin(),
282 ie = user_image_managers_.end();
283 it != ie; ++it) {
284 it->second->Shutdown();
286 multi_profile_user_controller_.reset();
287 avatar_policy_observer_.reset();
288 wallpaper_policy_observer_.reset();
291 MultiProfileUserController* UserManagerImpl::GetMultiProfileUserController() {
292 return multi_profile_user_controller_.get();
295 UserImageManager* UserManagerImpl::GetUserImageManager(
296 const std::string& user_id) {
297 UserImageManagerMap::iterator ui = user_image_managers_.find(user_id);
298 if (ui != user_image_managers_.end())
299 return ui->second.get();
300 linked_ptr<UserImageManagerImpl> mgr(new UserImageManagerImpl(user_id, this));
301 user_image_managers_[user_id] = mgr;
302 return mgr.get();
305 SupervisedUserManager* UserManagerImpl::GetSupervisedUserManager() {
306 return supervised_user_manager_.get();
309 const UserList& UserManagerImpl::GetUsers() const {
310 const_cast<UserManagerImpl*>(this)->EnsureUsersLoaded();
311 return users_;
314 UserList UserManagerImpl::GetUsersAdmittedForMultiProfile() const {
315 if (!UserManager::IsMultipleProfilesAllowed())
316 return UserList();
318 // Supervised users are not allowed to use multi profile.
319 if (logged_in_users_.size() == 1 &&
320 GetPrimaryUser()->GetType() != User::USER_TYPE_REGULAR)
321 return UserList();
323 UserList result;
324 int num_users_allowed = 0;
325 const UserList& users = GetUsers();
326 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
327 if ((*it)->GetType() == User::USER_TYPE_REGULAR && !(*it)->is_logged_in()) {
328 MultiProfileUserController::UserAllowedInSessionResult check =
329 multi_profile_user_controller_->
330 IsUserAllowedInSession((*it)->email());
331 if (check == MultiProfileUserController::
332 NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS) {
333 return UserList();
336 // Users with a policy that prevents them being added to a session will be
337 // shown in login UI but will be grayed out.
338 if (check == MultiProfileUserController::ALLOWED ||
339 check == MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS) {
340 result.push_back(*it);
341 if (check == MultiProfileUserController::ALLOWED)
342 num_users_allowed++;
347 // We only show multi-profiles sign in UI if there's at least one user that
348 // is allowed to be added to the session.
349 if (!num_users_allowed)
350 result.clear();
352 return result;
355 const UserList& UserManagerImpl::GetLoggedInUsers() const {
356 return logged_in_users_;
359 const UserList& UserManagerImpl::GetLRULoggedInUsers() {
360 // If there is no user logged in, we return the active user as the only one.
361 if (lru_logged_in_users_.empty() && active_user_) {
362 temp_single_logged_in_users_.clear();
363 temp_single_logged_in_users_.insert(temp_single_logged_in_users_.begin(),
364 active_user_);
365 return temp_single_logged_in_users_;
367 return lru_logged_in_users_;
370 UserList UserManagerImpl::GetUnlockUsers() const {
371 const UserList& logged_in_users = GetLoggedInUsers();
372 if (logged_in_users.empty())
373 return UserList();
375 UserList unlock_users;
376 Profile* profile = GetProfileByUser(primary_user_);
377 std::string primary_behavior =
378 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
380 // Specific case: only one logged in user or
381 // primary user has primary-only multi-profile policy.
382 if (logged_in_users.size() == 1 ||
383 primary_behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
384 if (primary_user_->can_lock())
385 unlock_users.push_back(primary_user_);
386 } else {
387 // Fill list of potential unlock users based on multi-profile policy state.
388 for (UserList::const_iterator it = logged_in_users.begin();
389 it != logged_in_users.end(); ++it) {
390 User* user = (*it);
391 Profile* profile = GetProfileByUser(user);
392 const std::string behavior =
393 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
394 if (behavior == MultiProfileUserController::kBehaviorUnrestricted &&
395 user->can_lock()) {
396 unlock_users.push_back(user);
397 } else if (behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
398 NOTREACHED()
399 << "Spotted primary-only multi-profile policy for non-primary user";
404 return unlock_users;
407 const std::string& UserManagerImpl::GetOwnerEmail() {
408 return owner_email_;
411 void UserManagerImpl::UserLoggedIn(const std::string& user_id,
412 const std::string& username_hash,
413 bool browser_restart) {
414 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
416 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles))
417 DCHECK(!IsUserLoggedIn());
419 User* user = FindUserInListAndModify(user_id);
420 if (active_user_ && user) {
421 user->set_is_logged_in(true);
422 user->set_username_hash(username_hash);
423 logged_in_users_.push_back(user);
424 lru_logged_in_users_.push_back(user);
425 // Reset the new user flag if the user already exists.
426 is_current_user_new_ = false;
427 NotifyUserAddedToSession(user);
428 // Remember that we need to switch to this user as soon as profile ready.
429 pending_user_switch_ = user_id;
430 return;
433 policy::DeviceLocalAccount::Type device_local_account_type;
434 if (user_id == UserManager::kGuestUserName) {
435 GuestUserLoggedIn();
436 } else if (user_id == UserManager::kRetailModeUserName) {
437 RetailModeUserLoggedIn();
438 } else if (policy::IsDeviceLocalAccountUser(user_id,
439 &device_local_account_type) &&
440 device_local_account_type ==
441 policy::DeviceLocalAccount::TYPE_KIOSK_APP) {
442 KioskAppLoggedIn(user_id);
443 } else if (DemoAppLauncher::IsDemoAppSession(user_id)) {
444 DemoAccountLoggedIn();
445 } else {
446 EnsureUsersLoaded();
448 if (user && user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
449 PublicAccountUserLoggedIn(user);
450 } else if ((user && user->GetType() == User::USER_TYPE_LOCALLY_MANAGED) ||
451 (!user && gaia::ExtractDomainName(user_id) ==
452 UserManager::kLocallyManagedUserDomain)) {
453 LocallyManagedUserLoggedIn(user_id);
454 } else if (browser_restart && user_id == g_browser_process->local_state()->
455 GetString(kPublicAccountPendingDataRemoval)) {
456 PublicAccountUserLoggedIn(User::CreatePublicAccountUser(user_id));
457 } else if (user_id != owner_email_ && !user &&
458 (AreEphemeralUsersEnabled() || browser_restart)) {
459 RegularUserLoggedInAsEphemeral(user_id);
460 } else {
461 RegularUserLoggedIn(user_id);
464 // Initialize the session length limiter and start it only if
465 // session limit is defined by the policy.
466 session_length_limiter_.reset(new SessionLengthLimiter(NULL,
467 browser_restart));
469 DCHECK(active_user_);
470 active_user_->set_is_logged_in(true);
471 active_user_->set_is_active(true);
472 active_user_->set_username_hash(username_hash);
474 // Place user who just signed in to the top of the logged in users.
475 logged_in_users_.insert(logged_in_users_.begin(), active_user_);
476 SetLRUUser(active_user_);
478 if (!primary_user_) {
479 primary_user_ = active_user_;
480 if (primary_user_->GetType() == User::USER_TYPE_REGULAR)
481 SendRegularUserLoginMetrics(user_id);
484 UMA_HISTOGRAM_ENUMERATION("UserManager.LoginUserType",
485 active_user_->GetType(), User::NUM_USER_TYPES);
487 g_browser_process->local_state()->SetString(kLastLoggedInRegularUser,
488 (active_user_->GetType() == User::USER_TYPE_REGULAR) ? user_id : "");
490 NotifyOnLogin();
493 void UserManagerImpl::SwitchActiveUser(const std::string& user_id) {
494 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles))
495 return;
497 User* user = FindUserAndModify(user_id);
498 if (!user) {
499 NOTREACHED() << "Switching to a non-existing user";
500 return;
502 if (user == active_user_) {
503 NOTREACHED() << "Switching to a user who is already active";
504 return;
506 if (!user->is_logged_in()) {
507 NOTREACHED() << "Switching to a user that is not logged in";
508 return;
510 if (user->GetType() != User::USER_TYPE_REGULAR) {
511 NOTREACHED() << "Switching to a non-regular user";
512 return;
514 if (user->username_hash().empty()) {
515 NOTREACHED() << "Switching to a user that doesn't have username_hash set";
516 return;
519 DCHECK(active_user_);
520 active_user_->set_is_active(false);
521 user->set_is_active(true);
522 active_user_ = user;
524 // Move the user to the front.
525 SetLRUUser(active_user_);
527 NotifyActiveUserHashChanged(active_user_->username_hash());
528 NotifyActiveUserChanged(active_user_);
531 void UserManagerImpl::RestoreActiveSessions() {
532 DBusThreadManager::Get()->GetSessionManagerClient()->RetrieveActiveSessions(
533 base::Bind(&UserManagerImpl::OnRestoreActiveSessions,
534 base::Unretained(this)));
537 void UserManagerImpl::SessionStarted() {
538 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
539 session_started_ = true;
540 UpdateLoginState();
541 content::NotificationService::current()->Notify(
542 chrome::NOTIFICATION_SESSION_STARTED,
543 content::Source<UserManager>(this),
544 content::Details<const User>(active_user_));
545 if (is_current_user_new_) {
546 // Make sure that the new user's data is persisted to Local State.
547 g_browser_process->local_state()->CommitPendingWrite();
551 void UserManagerImpl::RemoveUser(const std::string& user_id,
552 RemoveUserDelegate* delegate) {
553 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
555 const User* user = FindUser(user_id);
556 if (!user || (user->GetType() != User::USER_TYPE_REGULAR &&
557 user->GetType() != User::USER_TYPE_LOCALLY_MANAGED))
558 return;
560 // Sanity check: we must not remove single user unless it's an enterprise
561 // device. This check may seem redundant at a first sight because
562 // this single user must be an owner and we perform special check later
563 // in order not to remove an owner. However due to non-instant nature of
564 // ownership assignment this later check may sometimes fail.
565 // See http://crosbug.com/12723
566 policy::BrowserPolicyConnectorChromeOS* connector =
567 g_browser_process->platform_part()
568 ->browser_policy_connector_chromeos();
569 if (users_.size() < 2 && !connector->IsEnterpriseManaged())
570 return;
572 // Sanity check: do not allow any of the the logged in users to be removed.
573 for (UserList::const_iterator it = logged_in_users_.begin();
574 it != logged_in_users_.end(); ++it) {
575 if ((*it)->email() == user_id)
576 return;
579 RemoveUserInternal(user_id, delegate);
582 void UserManagerImpl::RemoveUserInternal(const std::string& user_email,
583 RemoveUserDelegate* delegate) {
584 CrosSettings* cros_settings = CrosSettings::Get();
586 // Ensure the value of owner email has been fetched.
587 if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues(
588 base::Bind(&UserManagerImpl::RemoveUserInternal,
589 base::Unretained(this),
590 user_email, delegate))) {
591 // Value of owner email is not fetched yet. RemoveUserInternal will be
592 // called again after fetch completion.
593 return;
595 std::string owner;
596 cros_settings->GetString(kDeviceOwner, &owner);
597 if (user_email == owner) {
598 // Owner is not allowed to be removed from the device.
599 return;
601 RemoveNonOwnerUserInternal(user_email, delegate);
604 void UserManagerImpl::RemoveNonOwnerUserInternal(const std::string& user_email,
605 RemoveUserDelegate* delegate) {
606 if (delegate)
607 delegate->OnBeforeUserRemoved(user_email);
608 RemoveUserFromList(user_email);
609 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
610 user_email, base::Bind(&OnRemoveUserComplete, user_email));
612 if (delegate)
613 delegate->OnUserRemoved(user_email);
616 void UserManagerImpl::RemoveUserFromList(const std::string& user_id) {
617 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
618 RemoveNonCryptohomeData(user_id);
619 if (user_loading_stage_ == STAGE_LOADED) {
620 DeleteUser(RemoveRegularOrLocallyManagedUserFromList(user_id));
621 } else if (user_loading_stage_ == STAGE_LOADING) {
622 DCHECK(gaia::ExtractDomainName(user_id) ==
623 UserManager::kLocallyManagedUserDomain);
624 // Special case, removing partially-constructed supervised user during user
625 // list loading.
626 ListPrefUpdate users_update(g_browser_process->local_state(),
627 kRegularUsers);
628 users_update->Remove(base::StringValue(user_id), NULL);
629 } else {
630 NOTREACHED() << "Users are not loaded yet.";
631 return;
633 // Make sure that new data is persisted to Local State.
634 g_browser_process->local_state()->CommitPendingWrite();
637 bool UserManagerImpl::IsKnownUser(const std::string& user_id) const {
638 return FindUser(user_id) != NULL;
641 const User* UserManagerImpl::FindUser(const std::string& user_id) const {
642 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
643 if (active_user_ && active_user_->email() == user_id)
644 return active_user_;
645 return FindUserInList(user_id);
648 User* UserManagerImpl::FindUserAndModify(const std::string& user_id) {
649 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
650 if (active_user_ && active_user_->email() == user_id)
651 return active_user_;
652 return FindUserInListAndModify(user_id);
655 const User* UserManagerImpl::GetLoggedInUser() const {
656 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
657 return active_user_;
660 User* UserManagerImpl::GetLoggedInUser() {
661 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
662 return active_user_;
665 const User* UserManagerImpl::GetActiveUser() const {
666 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
667 return active_user_;
670 User* UserManagerImpl::GetActiveUser() {
671 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
672 return active_user_;
675 const User* UserManagerImpl::GetPrimaryUser() const {
676 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
677 return primary_user_;
680 User* UserManagerImpl::GetUserByProfile(Profile* profile) const {
681 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
682 if (ProfileHelper::IsSigninProfile(profile))
683 return NULL;
685 if (IsMultipleProfilesAllowed()) {
686 const std::string username_hash =
687 ProfileHelper::GetUserIdHashFromProfile(profile);
688 const UserList& users = GetUsers();
689 const UserList::const_iterator pos = std::find_if(
690 users.begin(), users.end(), UserHashMatcher(username_hash));
691 if (pos != users.end())
692 return *pos;
694 // Many tests do not have their users registered with UserManager and
695 // runs here. If |active_user_| matches |profile|, returns it.
696 return active_user_ &&
697 ProfileHelper::GetProfilePathByUserIdHash(
698 active_user_->username_hash()) == profile->GetPath()
699 ? active_user_
700 : NULL;
702 return active_user_;
705 Profile* UserManagerImpl::GetProfileByUser(const User* user) const {
706 Profile* profile = NULL;
707 if (IsMultipleProfilesAllowed() && user->is_profile_created())
708 profile = ProfileHelper::GetProfileByUserIdHash(user->username_hash());
709 else
710 profile = ProfileManager::GetActiveUserProfile();
712 // GetActiveUserProfile() or GetProfileByUserIdHash() returns a new instance
713 // of ProfileImpl(), but actually its OffTheRecordProfile() should be used.
714 if (profile && IsLoggedInAsGuest())
715 profile = profile->GetOffTheRecordProfile();
716 return profile;
719 void UserManagerImpl::SaveUserOAuthStatus(
720 const std::string& user_id,
721 User::OAuthTokenStatus oauth_token_status) {
722 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
724 DVLOG(1) << "Saving user OAuth token status in Local State";
725 User* user = FindUserAndModify(user_id);
726 if (user)
727 user->set_oauth_token_status(oauth_token_status);
729 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(oauth_token_status);
731 // Do not update local state if data stored or cached outside the user's
732 // cryptohome is to be treated as ephemeral.
733 if (IsUserNonCryptohomeDataEphemeral(user_id))
734 return;
736 PrefService* local_state = g_browser_process->local_state();
738 DictionaryPrefUpdate oauth_status_update(local_state, kUserOAuthTokenStatus);
739 oauth_status_update->SetWithoutPathExpansion(user_id,
740 new base::FundamentalValue(static_cast<int>(oauth_token_status)));
743 void UserManagerImpl::SaveForceOnlineSignin(const std::string& user_id,
744 bool force_online_signin) {
745 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
747 // Do not update local state if data stored or cached outside the user's
748 // cryptohome is to be treated as ephemeral.
749 if (IsUserNonCryptohomeDataEphemeral(user_id))
750 return;
752 DictionaryPrefUpdate force_online_update(g_browser_process->local_state(),
753 kUserForceOnlineSignin);
754 force_online_update->SetBooleanWithoutPathExpansion(user_id,
755 force_online_signin);
758 void UserManagerImpl::SaveUserDisplayName(const std::string& user_id,
759 const base::string16& display_name) {
760 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
762 if (User* user = FindUserAndModify(user_id)) {
763 user->set_display_name(display_name);
765 // Do not update local state if data stored or cached outside the user's
766 // cryptohome is to be treated as ephemeral.
767 if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
768 PrefService* local_state = g_browser_process->local_state();
770 DictionaryPrefUpdate display_name_update(local_state, kUserDisplayName);
771 display_name_update->SetWithoutPathExpansion(
772 user_id,
773 new base::StringValue(display_name));
775 supervised_user_manager_->UpdateManagerName(user_id, display_name);
780 base::string16 UserManagerImpl::GetUserDisplayName(
781 const std::string& user_id) const {
782 const User* user = FindUser(user_id);
783 return user ? user->display_name() : base::string16();
786 void UserManagerImpl::SaveUserDisplayEmail(const std::string& user_id,
787 const std::string& display_email) {
788 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
790 User* user = FindUserAndModify(user_id);
791 if (!user)
792 return; // Ignore if there is no such user.
794 user->set_display_email(display_email);
796 // Do not update local state if data stored or cached outside the user's
797 // cryptohome is to be treated as ephemeral.
798 if (IsUserNonCryptohomeDataEphemeral(user_id))
799 return;
801 PrefService* local_state = g_browser_process->local_state();
803 DictionaryPrefUpdate display_email_update(local_state, kUserDisplayEmail);
804 display_email_update->SetWithoutPathExpansion(
805 user_id,
806 new base::StringValue(display_email));
809 std::string UserManagerImpl::GetUserDisplayEmail(
810 const std::string& user_id) const {
811 const User* user = FindUser(user_id);
812 return user ? user->display_email() : user_id;
815 void UserManagerImpl::UpdateUserAccountData(
816 const std::string& user_id,
817 const UserAccountData& account_data) {
818 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
820 SaveUserDisplayName(user_id, account_data.display_name());
822 if (User* user = FindUserAndModify(user_id)) {
823 base::string16 given_name = account_data.given_name();
824 user->set_given_name(given_name);
825 if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
826 PrefService* local_state = g_browser_process->local_state();
828 DictionaryPrefUpdate given_name_update(local_state, kUserGivenName);
829 given_name_update->SetWithoutPathExpansion(
830 user_id,
831 new base::StringValue(given_name));
835 UpdateUserAccountLocale(user_id, account_data.locale());
838 // TODO(alemate): http://crbug.com/288941 : Respect preferred language list in
839 // the Google user profile.
841 // Returns true if callback will be called.
842 bool UserManagerImpl::RespectLocalePreference(
843 Profile* profile,
844 const User* user,
845 scoped_ptr<locale_util::SwitchLanguageCallback> callback) const {
846 if (g_browser_process == NULL)
847 return false;
848 if ((user == NULL) || (user != GetPrimaryUser()) ||
849 (!user->is_profile_created()))
850 return false;
852 // In case of Multi Profile mode we don't apply profile locale because it is
853 // unsafe.
854 if (GetLoggedInUsers().size() != 1)
855 return false;
856 const PrefService* prefs = profile->GetPrefs();
857 if (prefs == NULL)
858 return false;
860 std::string pref_locale;
861 const std::string pref_app_locale =
862 prefs->GetString(prefs::kApplicationLocale);
863 const std::string pref_bkup_locale =
864 prefs->GetString(prefs::kApplicationLocaleBackup);
866 pref_locale = pref_app_locale;
867 if (pref_locale.empty())
868 pref_locale = pref_bkup_locale;
870 const std::string* account_locale = NULL;
871 if (pref_locale.empty() && user->has_gaia_account()) {
872 if (user->GetAccountLocale() == NULL)
873 return false; // wait until Account profile is loaded.
874 account_locale = user->GetAccountLocale();
875 pref_locale = *account_locale;
877 const std::string global_app_locale =
878 g_browser_process->GetApplicationLocale();
879 if (pref_locale.empty())
880 pref_locale = global_app_locale;
881 DCHECK(!pref_locale.empty());
882 LOG(WARNING) << "RespectLocalePreference: "
883 << "app_locale='" << pref_app_locale << "', "
884 << "bkup_locale='" << pref_bkup_locale << "', "
885 << (account_locale != NULL
886 ? (std::string("account_locale='") + (*account_locale) +
887 "'. ")
888 : (std::string("account_locale - unused. ")))
889 << " Selected '" << pref_locale << "'";
890 profile->ChangeAppLocale(pref_locale, Profile::APP_LOCALE_CHANGED_VIA_LOGIN);
892 // Here we don't enable keyboard layouts for normal users. Input methods
893 // are set up when the user first logs in. Then the user may customize the
894 // input methods. Hence changing input methods here, just because the user's
895 // UI language is different from the login screen UI language, is not
896 // desirable. Note that input method preferences are synced, so users can use
897 // their farovite input methods as soon as the preferences are synced.
899 // For Guest mode, user locale preferences will never get initialized.
900 // So input methods should be enabled somewhere.
901 const bool enable_layouts = UserManager::Get()->IsLoggedInAsGuest();
902 locale_util::SwitchLanguage(pref_locale,
903 enable_layouts,
904 false /* login_layouts_only */,
905 callback.Pass());
907 return true;
910 void UserManagerImpl::StopPolicyObserverForTesting() {
911 avatar_policy_observer_.reset();
912 wallpaper_policy_observer_.reset();
915 void UserManagerImpl::Observe(int type,
916 const content::NotificationSource& source,
917 const content::NotificationDetails& details) {
918 switch (type) {
919 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED:
920 if (!device_local_account_policy_service_) {
921 policy::BrowserPolicyConnectorChromeOS* connector =
922 g_browser_process->platform_part()
923 ->browser_policy_connector_chromeos();
924 device_local_account_policy_service_ =
925 connector->GetDeviceLocalAccountPolicyService();
926 if (device_local_account_policy_service_)
927 device_local_account_policy_service_->AddObserver(this);
929 // Making this call synchronously is not gonna cut it because
930 // notification order is not defined and in a single message loop run and
931 // getting trusted settings rely on a reload that happens on the very same
932 // notification observation.
933 base::MessageLoop::current()->PostTask(FROM_HERE,
934 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
935 base::Unretained(this)));
936 UserManagerImpl::UpdateOwnership();
937 break;
938 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: {
939 Profile* profile = content::Details<Profile>(details).ptr();
940 if (IsUserLoggedIn() &&
941 !IsLoggedInAsGuest() &&
942 !IsLoggedInAsKioskApp()) {
943 if (IsLoggedInAsLocallyManagedUser())
944 ManagedUserPasswordServiceFactory::GetForProfile(profile);
945 if (IsLoggedInAsRegularUser())
946 ManagerPasswordServiceFactory::GetForProfile(profile);
948 if (!profile->IsOffTheRecord()) {
949 AuthSyncObserver* sync_observer =
950 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile);
951 sync_observer->StartObserving();
952 multi_profile_user_controller_->StartObserving(profile);
956 // Now that the user profile has been initialized and
957 // |GetNSSCertDatabaseForProfile| is safe to be used, get the NSS cert
958 // database for the primary user and start certificate loader with it.
959 if (IsUserLoggedIn() &&
960 GetPrimaryUser() &&
961 profile == GetProfileByUser(GetPrimaryUser()) &&
962 CertLoader::IsInitialized() &&
963 base::SysInfo::IsRunningOnChromeOS()) {
964 GetNSSCertDatabaseForProfile(profile,
965 base::Bind(&OnGetNSSCertDatabaseForUser));
967 break;
969 case chrome::NOTIFICATION_PROFILE_CREATED: {
970 Profile* profile = content::Source<Profile>(source).ptr();
971 User* user = GetUserByProfile(profile);
972 if (user != NULL)
973 user->set_profile_is_created();
974 // If there is pending user switch, do it now.
975 if (!pending_user_switch_.empty()) {
976 // Call SwitchActiveUser async because otherwise it may cause
977 // ProfileManager::GetProfile before the profile gets registered
978 // in ProfileManager. It happens in case of sync profile load when
979 // NOTIFICATION_PROFILE_CREATED is called synchronously.
980 base::MessageLoop::current()->PostTask(FROM_HERE,
981 base::Bind(&UserManagerImpl::SwitchActiveUser,
982 base::Unretained(this),
983 pending_user_switch_));
984 pending_user_switch_.clear();
986 break;
988 default:
989 NOTREACHED();
993 void UserManagerImpl::OnExternalDataSet(const std::string& policy,
994 const std::string& user_id) {
995 if (policy == policy::key::kUserAvatarImage)
996 GetUserImageManager(user_id)->OnExternalDataSet(policy);
997 else if (policy == policy::key::kWallpaperImage)
998 WallpaperManager::Get()->OnPolicySet(policy, user_id);
999 else
1000 NOTREACHED();
1003 void UserManagerImpl::OnExternalDataCleared(const std::string& policy,
1004 const std::string& user_id) {
1005 if (policy == policy::key::kUserAvatarImage)
1006 GetUserImageManager(user_id)->OnExternalDataCleared(policy);
1007 else if (policy == policy::key::kWallpaperImage)
1008 WallpaperManager::Get()->OnPolicyCleared(policy, user_id);
1009 else
1010 NOTREACHED();
1013 void UserManagerImpl::OnExternalDataFetched(const std::string& policy,
1014 const std::string& user_id,
1015 scoped_ptr<std::string> data) {
1016 if (policy == policy::key::kUserAvatarImage)
1017 GetUserImageManager(user_id)->OnExternalDataFetched(policy, data.Pass());
1018 else if (policy == policy::key::kWallpaperImage)
1019 WallpaperManager::Get()->OnPolicyFetched(policy, user_id, data.Pass());
1020 else
1021 NOTREACHED();
1024 void UserManagerImpl::OnPolicyUpdated(const std::string& user_id) {
1025 UpdatePublicAccountDisplayName(user_id);
1026 NotifyUserListChanged();
1029 void UserManagerImpl::OnDeviceLocalAccountsChanged() {
1030 // No action needed here, changes to the list of device-local accounts get
1031 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
1034 bool UserManagerImpl::IsCurrentUserOwner() const {
1035 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1036 base::AutoLock lk(is_current_user_owner_lock_);
1037 return is_current_user_owner_;
1040 void UserManagerImpl::SetCurrentUserIsOwner(bool is_current_user_owner) {
1041 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1043 base::AutoLock lk(is_current_user_owner_lock_);
1044 is_current_user_owner_ = is_current_user_owner;
1046 UpdateLoginState();
1049 bool UserManagerImpl::IsCurrentUserNew() const {
1050 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1051 return is_current_user_new_;
1054 bool UserManagerImpl::IsCurrentUserNonCryptohomeDataEphemeral() const {
1055 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1056 return IsUserLoggedIn() &&
1057 IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email());
1060 bool UserManagerImpl::CanCurrentUserLock() const {
1061 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1062 return IsUserLoggedIn() && active_user_->can_lock() &&
1063 GetCurrentUserFlow()->CanLockScreen();
1066 bool UserManagerImpl::IsUserLoggedIn() const {
1067 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1068 return active_user_;
1071 bool UserManagerImpl::IsLoggedInAsRegularUser() const {
1072 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1073 return IsUserLoggedIn() &&
1074 active_user_->GetType() == User::USER_TYPE_REGULAR;
1077 bool UserManagerImpl::IsLoggedInAsDemoUser() const {
1078 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1079 return IsUserLoggedIn() &&
1080 active_user_->GetType() == User::USER_TYPE_RETAIL_MODE;
1083 bool UserManagerImpl::IsLoggedInAsPublicAccount() const {
1084 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1085 return IsUserLoggedIn() &&
1086 active_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
1089 bool UserManagerImpl::IsLoggedInAsGuest() const {
1090 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1091 return IsUserLoggedIn() &&
1092 active_user_->GetType() == User::USER_TYPE_GUEST;
1095 bool UserManagerImpl::IsLoggedInAsLocallyManagedUser() const {
1096 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1097 return IsUserLoggedIn() &&
1098 active_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED;
1101 bool UserManagerImpl::IsLoggedInAsKioskApp() const {
1102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1103 return IsUserLoggedIn() &&
1104 active_user_->GetType() == User::USER_TYPE_KIOSK_APP;
1107 bool UserManagerImpl::IsLoggedInAsStub() const {
1108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1109 return IsUserLoggedIn() && active_user_->email() == kStubUser;
1112 bool UserManagerImpl::IsSessionStarted() const {
1113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1114 return session_started_;
1117 bool UserManagerImpl::UserSessionsRestored() const {
1118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1119 return user_sessions_restored_;
1122 bool UserManagerImpl::HasBrowserRestarted() const {
1123 CommandLine* command_line = CommandLine::ForCurrentProcess();
1124 return base::SysInfo::IsRunningOnChromeOS() &&
1125 command_line->HasSwitch(switches::kLoginUser) &&
1126 !command_line->HasSwitch(switches::kLoginPassword);
1129 bool UserManagerImpl::IsUserNonCryptohomeDataEphemeral(
1130 const std::string& user_id) const {
1131 // Data belonging to the guest, retail mode and stub users is always
1132 // ephemeral.
1133 if (user_id == UserManager::kGuestUserName ||
1134 user_id == UserManager::kRetailModeUserName ||
1135 user_id == kStubUser) {
1136 return true;
1139 // Data belonging to the owner, anyone found on the user list and obsolete
1140 // public accounts whose data has not been removed yet is not ephemeral.
1141 if (user_id == owner_email_ || UserExistsInList(user_id) ||
1142 user_id == g_browser_process->local_state()->
1143 GetString(kPublicAccountPendingDataRemoval)) {
1144 return false;
1147 // Data belonging to the currently logged-in user is ephemeral when:
1148 // a) The user logged into a regular account while the ephemeral users policy
1149 // was enabled.
1150 // - or -
1151 // b) The user logged into any other account type.
1152 if (IsUserLoggedIn() && (user_id == GetLoggedInUser()->email()) &&
1153 (is_current_user_ephemeral_regular_user_ || !IsLoggedInAsRegularUser())) {
1154 return true;
1157 // Data belonging to any other user is ephemeral when:
1158 // a) Going through the regular login flow and the ephemeral users policy is
1159 // enabled.
1160 // - or -
1161 // b) The browser is restarting after a crash.
1162 return AreEphemeralUsersEnabled() || HasBrowserRestarted();
1165 void UserManagerImpl::AddObserver(UserManager::Observer* obs) {
1166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1167 observer_list_.AddObserver(obs);
1170 void UserManagerImpl::RemoveObserver(UserManager::Observer* obs) {
1171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1172 observer_list_.RemoveObserver(obs);
1175 void UserManagerImpl::AddSessionStateObserver(
1176 UserManager::UserSessionStateObserver* obs) {
1177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1178 session_state_observer_list_.AddObserver(obs);
1181 void UserManagerImpl::RemoveSessionStateObserver(
1182 UserManager::UserSessionStateObserver* obs) {
1183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1184 session_state_observer_list_.RemoveObserver(obs);
1187 void UserManagerImpl::NotifyLocalStateChanged() {
1188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1189 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_,
1190 LocalStateChanged(this));
1193 void UserManagerImpl::OnProfilePrepared(Profile* profile) {
1194 LoginUtils::Get()->DoBrowserLaunch(profile,
1195 NULL); // host_, not needed here
1197 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) {
1198 // Did not log in (we crashed or are debugging), need to restore Sync.
1199 // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
1200 // users once it is fully multi-profile aware. http://crbug.com/238987
1201 // For now if we have other user pending sessions they'll override OAuth
1202 // session restore for previous users.
1203 LoginUtils::Get()->RestoreAuthenticationSession(profile);
1206 // Restore other user sessions if any.
1207 RestorePendingUserSessions();
1210 void UserManagerImpl::EnsureUsersLoaded() {
1211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1212 if (!g_browser_process || !g_browser_process->local_state())
1213 return;
1215 if (user_loading_stage_ != STAGE_NOT_LOADED)
1216 return;
1217 user_loading_stage_ = STAGE_LOADING;
1218 // Clean up user list first. All code down the path should be synchronous,
1219 // so that local state after transaction rollback is in consistent state.
1220 // This process also should not trigger EnsureUsersLoaded again.
1221 if (supervised_user_manager_->HasFailedUserCreationTransaction())
1222 supervised_user_manager_->RollbackUserCreationTransaction();
1224 PrefService* local_state = g_browser_process->local_state();
1225 const base::ListValue* prefs_regular_users =
1226 local_state->GetList(kRegularUsers);
1227 const base::ListValue* prefs_public_sessions =
1228 local_state->GetList(kPublicAccounts);
1229 const base::DictionaryValue* prefs_display_names =
1230 local_state->GetDictionary(kUserDisplayName);
1231 const base::DictionaryValue* prefs_given_names =
1232 local_state->GetDictionary(kUserGivenName);
1233 const base::DictionaryValue* prefs_display_emails =
1234 local_state->GetDictionary(kUserDisplayEmail);
1236 // Load public sessions first.
1237 std::vector<std::string> public_sessions;
1238 std::set<std::string> public_sessions_set;
1239 ParseUserList(*prefs_public_sessions, std::set<std::string>(),
1240 &public_sessions, &public_sessions_set);
1241 for (std::vector<std::string>::const_iterator it = public_sessions.begin();
1242 it != public_sessions.end(); ++it) {
1243 users_.push_back(User::CreatePublicAccountUser(*it));
1244 UpdatePublicAccountDisplayName(*it);
1247 // Load regular users and locally managed users.
1248 std::vector<std::string> regular_users;
1249 std::set<std::string> regular_users_set;
1250 ParseUserList(*prefs_regular_users, public_sessions_set,
1251 &regular_users, &regular_users_set);
1252 for (std::vector<std::string>::const_iterator it = regular_users.begin();
1253 it != regular_users.end(); ++it) {
1254 User* user = NULL;
1255 const std::string domain = gaia::ExtractDomainName(*it);
1256 if (domain == UserManager::kLocallyManagedUserDomain)
1257 user = User::CreateLocallyManagedUser(*it);
1258 else
1259 user = User::CreateRegularUser(*it);
1260 user->set_oauth_token_status(LoadUserOAuthStatus(*it));
1261 user->set_force_online_signin(LoadForceOnlineSignin(*it));
1262 users_.push_back(user);
1264 base::string16 display_name;
1265 if (prefs_display_names->GetStringWithoutPathExpansion(*it,
1266 &display_name)) {
1267 user->set_display_name(display_name);
1270 base::string16 given_name;
1271 if (prefs_given_names->GetStringWithoutPathExpansion(*it, &given_name)) {
1272 user->set_given_name(given_name);
1275 std::string display_email;
1276 if (prefs_display_emails->GetStringWithoutPathExpansion(*it,
1277 &display_email)) {
1278 user->set_display_email(display_email);
1282 user_loading_stage_ = STAGE_LOADED;
1284 for (UserList::iterator ui = users_.begin(), ue = users_.end();
1285 ui != ue; ++ui) {
1286 GetUserImageManager((*ui)->email())->LoadUserImage();
1290 void UserManagerImpl::RetrieveTrustedDevicePolicies() {
1291 ephemeral_users_enabled_ = false;
1292 owner_email_ = "";
1294 // Schedule a callback if device policy has not yet been verified.
1295 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
1296 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
1297 base::Unretained(this)))) {
1298 return;
1301 cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
1302 &ephemeral_users_enabled_);
1303 cros_settings_->GetString(kDeviceOwner, &owner_email_);
1305 EnsureUsersLoaded();
1307 bool changed = UpdateAndCleanUpPublicAccounts(
1308 policy::GetDeviceLocalAccounts(cros_settings_));
1310 // If ephemeral users are enabled and we are on the login screen, take this
1311 // opportunity to clean up by removing all regular users except the owner.
1312 if (ephemeral_users_enabled_ && !IsUserLoggedIn()) {
1313 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1314 kRegularUsers);
1315 prefs_users_update->Clear();
1316 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1317 const std::string user_email = (*it)->email();
1318 if ((*it)->GetType() == User::USER_TYPE_REGULAR &&
1319 user_email != owner_email_) {
1320 RemoveNonCryptohomeData(user_email);
1321 DeleteUser(*it);
1322 it = users_.erase(it);
1323 changed = true;
1324 } else {
1325 if ((*it)->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT)
1326 prefs_users_update->Append(new base::StringValue(user_email));
1327 ++it;
1332 if (changed)
1333 NotifyUserListChanged();
1336 bool UserManagerImpl::AreEphemeralUsersEnabled() const {
1337 policy::BrowserPolicyConnectorChromeOS* connector =
1338 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1339 return ephemeral_users_enabled_ &&
1340 (connector->IsEnterpriseManaged() || !owner_email_.empty());
1343 UserList& UserManagerImpl::GetUsersAndModify() {
1344 EnsureUsersLoaded();
1345 return users_;
1348 const User* UserManagerImpl::FindUserInList(const std::string& user_id) const {
1349 const UserList& users = GetUsers();
1350 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
1351 if ((*it)->email() == user_id)
1352 return *it;
1354 return NULL;
1357 const bool UserManagerImpl::UserExistsInList(const std::string& user_id) const {
1358 PrefService* local_state = g_browser_process->local_state();
1359 const base::ListValue* user_list = local_state->GetList(kRegularUsers);
1360 for (size_t i = 0; i < user_list->GetSize(); ++i) {
1361 std::string email;
1362 if (user_list->GetString(i, &email) && (user_id == email))
1363 return true;
1365 return false;
1368 User* UserManagerImpl::FindUserInListAndModify(const std::string& user_id) {
1369 UserList& users = GetUsersAndModify();
1370 for (UserList::iterator it = users.begin(); it != users.end(); ++it) {
1371 if ((*it)->email() == user_id)
1372 return *it;
1374 return NULL;
1377 void UserManagerImpl::GuestUserLoggedIn() {
1378 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1379 active_user_ = User::CreateGuestUser();
1380 // TODO(nkostylev): Add support for passing guest session cryptohome
1381 // mount point. Legacy (--login-profile) value will be used for now.
1382 // http://crosbug.com/230859
1383 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1384 // Initializes wallpaper after active_user_ is set.
1385 WallpaperManager::Get()->SetUserWallpaperNow(UserManager::kGuestUserName);
1388 void UserManagerImpl::AddUserRecord(User* user) {
1389 // Add the user to the front of the user list.
1390 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1391 kRegularUsers);
1392 prefs_users_update->Insert(0, new base::StringValue(user->email()));
1393 users_.insert(users_.begin(), user);
1396 void UserManagerImpl::RegularUserLoggedIn(const std::string& user_id) {
1397 // Remove the user from the user list.
1398 active_user_ = RemoveRegularOrLocallyManagedUserFromList(user_id);
1400 // If the user was not found on the user list, create a new user.
1401 is_current_user_new_ = !active_user_;
1402 if (!active_user_) {
1403 active_user_ = User::CreateRegularUser(user_id);
1404 active_user_->set_oauth_token_status(LoadUserOAuthStatus(user_id));
1405 SaveUserDisplayName(active_user_->email(),
1406 base::UTF8ToUTF16(active_user_->GetAccountName(true)));
1407 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1410 AddUserRecord(active_user_);
1412 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, false);
1414 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1416 // Make sure that new data is persisted to Local State.
1417 g_browser_process->local_state()->CommitPendingWrite();
1420 void UserManagerImpl::RegularUserLoggedInAsEphemeral(
1421 const std::string& user_id) {
1422 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1423 is_current_user_new_ = true;
1424 is_current_user_ephemeral_regular_user_ = true;
1425 active_user_ = User::CreateRegularUser(user_id);
1426 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, false);
1427 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1430 void UserManagerImpl::LocallyManagedUserLoggedIn(
1431 const std::string& user_id) {
1432 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
1434 // Remove the user from the user list.
1435 active_user_ = RemoveRegularOrLocallyManagedUserFromList(user_id);
1436 // If the user was not found on the user list, create a new user.
1437 if (!active_user_) {
1438 is_current_user_new_ = true;
1439 active_user_ = User::CreateLocallyManagedUser(user_id);
1440 // Leaving OAuth token status at the default state = unknown.
1441 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1442 } else {
1443 if (supervised_user_manager_->CheckForFirstRun(user_id)) {
1444 is_current_user_new_ = true;
1445 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1446 } else {
1447 is_current_user_new_ = false;
1451 // Add the user to the front of the user list.
1452 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1453 kRegularUsers);
1454 prefs_users_update->Insert(0, new base::StringValue(user_id));
1455 users_.insert(users_.begin(), active_user_);
1457 // Now that user is in the list, save display name.
1458 if (is_current_user_new_) {
1459 SaveUserDisplayName(active_user_->email(),
1460 active_user_->GetDisplayName());
1463 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, true);
1464 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1466 // Make sure that new data is persisted to Local State.
1467 g_browser_process->local_state()->CommitPendingWrite();
1470 void UserManagerImpl::PublicAccountUserLoggedIn(User* user) {
1471 is_current_user_new_ = true;
1472 active_user_ = user;
1473 // The UserImageManager chooses a random avatar picture when a user logs in
1474 // for the first time. Tell the UserImageManager that this user is not new to
1475 // prevent the avatar from getting changed.
1476 GetUserImageManager(user->email())->UserLoggedIn(false, true);
1477 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1480 void UserManagerImpl::KioskAppLoggedIn(const std::string& app_id) {
1481 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1482 policy::DeviceLocalAccount::Type device_local_account_type;
1483 DCHECK(policy::IsDeviceLocalAccountUser(app_id,
1484 &device_local_account_type));
1485 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
1486 device_local_account_type);
1488 active_user_ = User::CreateKioskAppUser(app_id);
1489 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1491 WallpaperManager::Get()->SetUserWallpaperNow(app_id);
1493 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
1494 // the kiosk_app_id in these objects, removing the need to re-parse the
1495 // device-local account list here to extract the kiosk_app_id.
1496 const std::vector<policy::DeviceLocalAccount> device_local_accounts =
1497 policy::GetDeviceLocalAccounts(cros_settings_);
1498 const policy::DeviceLocalAccount* account = NULL;
1499 for (std::vector<policy::DeviceLocalAccount>::const_iterator
1500 it = device_local_accounts.begin();
1501 it != device_local_accounts.end(); ++it) {
1502 if (it->user_id == app_id) {
1503 account = &*it;
1504 break;
1507 std::string kiosk_app_id;
1508 if (account) {
1509 kiosk_app_id = account->kiosk_app_id;
1510 } else {
1511 LOG(ERROR) << "Logged into nonexistent kiosk-app account: " << app_id;
1512 NOTREACHED();
1515 CommandLine* command_line = CommandLine::ForCurrentProcess();
1516 command_line->AppendSwitch(::switches::kForceAppMode);
1517 command_line->AppendSwitchASCII(::switches::kAppId, kiosk_app_id);
1519 // Disable window animation since kiosk app runs in a single full screen
1520 // window and window animation causes start-up janks.
1521 command_line->AppendSwitch(
1522 wm::switches::kWindowAnimationsDisabled);
1525 void UserManagerImpl::DemoAccountLoggedIn() {
1526 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1527 active_user_ = User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName);
1528 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1529 WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName);
1531 CommandLine* command_line = CommandLine::ForCurrentProcess();
1532 command_line->AppendSwitch(::switches::kForceAppMode);
1533 command_line->AppendSwitchASCII(::switches::kAppId,
1534 DemoAppLauncher::kDemoAppId);
1536 // Disable window animation since the demo app runs in a single full screen
1537 // window and window animation causes start-up janks.
1538 CommandLine::ForCurrentProcess()->AppendSwitch(
1539 wm::switches::kWindowAnimationsDisabled);
1542 void UserManagerImpl::RetailModeUserLoggedIn() {
1543 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1544 is_current_user_new_ = true;
1545 active_user_ = User::CreateRetailModeUser();
1546 GetUserImageManager(UserManager::kRetailModeUserName)->UserLoggedIn(
1547 is_current_user_new_,
1548 true);
1549 WallpaperManager::Get()->SetUserWallpaperNow(
1550 UserManager::kRetailModeUserName);
1553 void UserManagerImpl::NotifyOnLogin() {
1554 UpdateNumberOfUsers();
1555 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1556 NotifyActiveUserHashChanged(active_user_->username_hash());
1557 NotifyActiveUserChanged(active_user_);
1559 UpdateLoginState();
1560 // TODO(nkostylev): Deprecate this notification in favor of
1561 // ActiveUserChanged() observer call.
1562 content::NotificationService::current()->Notify(
1563 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
1564 content::Source<UserManager>(this),
1565 content::Details<const User>(active_user_));
1567 // Owner must be first user in session. DeviceSettingsService can't deal with
1568 // multiple user and will mix up ownership, crbug.com/230018.
1569 if (GetLoggedInUsers().size() == 1) {
1570 // Indicate to DeviceSettingsService that the owner key may have become
1571 // available.
1572 DeviceSettingsService::Get()->SetUsername(active_user_->email());
1576 User::OAuthTokenStatus UserManagerImpl::LoadUserOAuthStatus(
1577 const std::string& user_id) const {
1578 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1580 PrefService* local_state = g_browser_process->local_state();
1581 const base::DictionaryValue* prefs_oauth_status =
1582 local_state->GetDictionary(kUserOAuthTokenStatus);
1583 int oauth_token_status = User::OAUTH_TOKEN_STATUS_UNKNOWN;
1584 if (prefs_oauth_status &&
1585 prefs_oauth_status->GetIntegerWithoutPathExpansion(
1586 user_id, &oauth_token_status)) {
1587 User::OAuthTokenStatus result =
1588 static_cast<User::OAuthTokenStatus>(oauth_token_status);
1589 if (result == User::OAUTH2_TOKEN_STATUS_INVALID)
1590 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(result);
1591 return result;
1593 return User::OAUTH_TOKEN_STATUS_UNKNOWN;
1596 bool UserManagerImpl::LoadForceOnlineSignin(const std::string& user_id) const {
1597 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1599 PrefService* local_state = g_browser_process->local_state();
1600 const base::DictionaryValue* prefs_force_online =
1601 local_state->GetDictionary(kUserForceOnlineSignin);
1602 bool force_online_signin = false;
1603 if (prefs_force_online) {
1604 prefs_force_online->GetBooleanWithoutPathExpansion(user_id,
1605 &force_online_signin);
1607 return force_online_signin;
1610 void UserManagerImpl::UpdateOwnership() {
1611 bool is_owner = DeviceSettingsService::Get()->HasPrivateOwnerKey();
1612 VLOG(1) << "Current user " << (is_owner ? "is owner" : "is not owner");
1614 SetCurrentUserIsOwner(is_owner);
1617 void UserManagerImpl::RemoveNonCryptohomeData(const std::string& user_id) {
1618 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id);
1619 GetUserImageManager(user_id)->DeleteUserImage();
1621 PrefService* prefs = g_browser_process->local_state();
1622 DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
1623 prefs_display_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1625 DictionaryPrefUpdate prefs_given_name_update(prefs, kUserGivenName);
1626 prefs_given_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1628 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
1629 prefs_display_email_update->RemoveWithoutPathExpansion(user_id, NULL);
1631 DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
1632 prefs_oauth_update->RemoveWithoutPathExpansion(user_id, NULL);
1634 DictionaryPrefUpdate prefs_force_online_update(prefs, kUserForceOnlineSignin);
1635 prefs_force_online_update->RemoveWithoutPathExpansion(user_id, NULL);
1637 supervised_user_manager_->RemoveNonCryptohomeData(user_id);
1639 multi_profile_user_controller_->RemoveCachedValues(user_id);
1642 User* UserManagerImpl::RemoveRegularOrLocallyManagedUserFromList(
1643 const std::string& user_id) {
1644 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1645 kRegularUsers);
1646 prefs_users_update->Clear();
1647 User* user = NULL;
1648 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1649 const std::string user_email = (*it)->email();
1650 if (user_email == user_id) {
1651 user = *it;
1652 it = users_.erase(it);
1653 } else {
1654 if ((*it)->GetType() == User::USER_TYPE_REGULAR ||
1655 (*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) {
1656 prefs_users_update->Append(new base::StringValue(user_email));
1658 ++it;
1661 return user;
1664 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
1665 PrefService* local_state = g_browser_process->local_state();
1666 const std::string public_account_pending_data_removal =
1667 local_state->GetString(kPublicAccountPendingDataRemoval);
1668 if (public_account_pending_data_removal.empty() ||
1669 (IsUserLoggedIn() &&
1670 public_account_pending_data_removal == GetActiveUser()->email())) {
1671 return;
1674 RemoveNonCryptohomeData(public_account_pending_data_removal);
1675 local_state->ClearPref(kPublicAccountPendingDataRemoval);
1678 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
1679 const std::vector<std::string>& old_public_accounts) {
1680 std::set<std::string> users;
1681 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it)
1682 users.insert((*it)->email());
1684 // If the user is logged into a public account that has been removed from the
1685 // user list, mark the account's data as pending removal after logout.
1686 if (IsLoggedInAsPublicAccount()) {
1687 const std::string active_user_id = GetActiveUser()->email();
1688 if (users.find(active_user_id) == users.end()) {
1689 g_browser_process->local_state()->SetString(
1690 kPublicAccountPendingDataRemoval, active_user_id);
1691 users.insert(active_user_id);
1695 // Remove the data belonging to any other public accounts that are no longer
1696 // found on the user list.
1697 for (std::vector<std::string>::const_iterator
1698 it = old_public_accounts.begin();
1699 it != old_public_accounts.end(); ++it) {
1700 if (users.find(*it) == users.end())
1701 RemoveNonCryptohomeData(*it);
1705 bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
1706 const std::vector<policy::DeviceLocalAccount>& device_local_accounts) {
1707 // Try to remove any public account data marked as pending removal.
1708 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
1710 // Get the current list of public accounts.
1711 std::vector<std::string> old_public_accounts;
1712 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it) {
1713 if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT)
1714 old_public_accounts.push_back((*it)->email());
1717 // Get the new list of public accounts from policy.
1718 std::vector<std::string> new_public_accounts;
1719 for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
1720 device_local_accounts.begin();
1721 it != device_local_accounts.end(); ++it) {
1722 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
1723 // standard login framework: http://crbug.com/234694
1724 if (it->type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
1725 new_public_accounts.push_back(it->user_id);
1728 // If the list of public accounts has not changed, return.
1729 if (new_public_accounts.size() == old_public_accounts.size()) {
1730 bool changed = false;
1731 for (size_t i = 0; i < new_public_accounts.size(); ++i) {
1732 if (new_public_accounts[i] != old_public_accounts[i]) {
1733 changed = true;
1734 break;
1737 if (!changed)
1738 return false;
1741 // Persist the new list of public accounts in a pref.
1742 ListPrefUpdate prefs_public_accounts_update(g_browser_process->local_state(),
1743 kPublicAccounts);
1744 prefs_public_accounts_update->Clear();
1745 for (std::vector<std::string>::const_iterator it =
1746 new_public_accounts.begin();
1747 it != new_public_accounts.end(); ++it) {
1748 prefs_public_accounts_update->AppendString(*it);
1751 // Remove the old public accounts from the user list.
1752 for (UserList::iterator it = users_.begin(); it != users_.end();) {
1753 if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
1754 if (*it != GetLoggedInUser())
1755 DeleteUser(*it);
1756 it = users_.erase(it);
1757 } else {
1758 ++it;
1762 // Add the new public accounts to the front of the user list.
1763 for (std::vector<std::string>::const_reverse_iterator it =
1764 new_public_accounts.rbegin();
1765 it != new_public_accounts.rend(); ++it) {
1766 if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email())
1767 users_.insert(users_.begin(), GetLoggedInUser());
1768 else
1769 users_.insert(users_.begin(), User::CreatePublicAccountUser(*it));
1770 UpdatePublicAccountDisplayName(*it);
1773 for (UserList::iterator ui = users_.begin(),
1774 ue = users_.begin() + new_public_accounts.size();
1775 ui != ue; ++ui) {
1776 GetUserImageManager((*ui)->email())->LoadUserImage();
1779 // Remove data belonging to public accounts that are no longer found on the
1780 // user list.
1781 CleanUpPublicAccountNonCryptohomeData(old_public_accounts);
1783 return true;
1786 void UserManagerImpl::UpdatePublicAccountDisplayName(
1787 const std::string& user_id) {
1788 std::string display_name;
1790 if (device_local_account_policy_service_) {
1791 policy::DeviceLocalAccountPolicyBroker* broker =
1792 device_local_account_policy_service_->GetBrokerForUser(user_id);
1793 if (broker)
1794 display_name = broker->GetDisplayName();
1797 // Set or clear the display name.
1798 SaveUserDisplayName(user_id, base::UTF8ToUTF16(display_name));
1801 UserFlow* UserManagerImpl::GetCurrentUserFlow() const {
1802 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1803 if (!IsUserLoggedIn())
1804 return GetDefaultUserFlow();
1805 return GetUserFlow(GetLoggedInUser()->email());
1808 UserFlow* UserManagerImpl::GetUserFlow(const std::string& user_id) const {
1809 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1810 FlowMap::const_iterator it = specific_flows_.find(user_id);
1811 if (it != specific_flows_.end())
1812 return it->second;
1813 return GetDefaultUserFlow();
1816 void UserManagerImpl::SetUserFlow(const std::string& user_id, UserFlow* flow) {
1817 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1818 ResetUserFlow(user_id);
1819 specific_flows_[user_id] = flow;
1822 void UserManagerImpl::ResetUserFlow(const std::string& user_id) {
1823 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1824 FlowMap::iterator it = specific_flows_.find(user_id);
1825 if (it != specific_flows_.end()) {
1826 delete it->second;
1827 specific_flows_.erase(it);
1831 bool UserManagerImpl::GetAppModeChromeClientOAuthInfo(
1832 std::string* chrome_client_id, std::string* chrome_client_secret) {
1833 if (!chrome::IsRunningInForcedAppMode() ||
1834 chrome_client_id_.empty() ||
1835 chrome_client_secret_.empty()) {
1836 return false;
1839 *chrome_client_id = chrome_client_id_;
1840 *chrome_client_secret = chrome_client_secret_;
1841 return true;
1844 void UserManagerImpl::SetAppModeChromeClientOAuthInfo(
1845 const std::string& chrome_client_id,
1846 const std::string& chrome_client_secret) {
1847 if (!chrome::IsRunningInForcedAppMode())
1848 return;
1850 chrome_client_id_ = chrome_client_id;
1851 chrome_client_secret_ = chrome_client_secret;
1854 bool UserManagerImpl::AreLocallyManagedUsersAllowed() const {
1855 bool locally_managed_users_allowed = false;
1856 cros_settings_->GetBoolean(kAccountsPrefSupervisedUsersEnabled,
1857 &locally_managed_users_allowed);
1858 policy::BrowserPolicyConnectorChromeOS* connector =
1859 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1860 return locally_managed_users_allowed || !connector->IsEnterpriseManaged();
1863 base::FilePath UserManagerImpl::GetUserProfileDir(
1864 const std::string& user_id) const {
1865 // TODO(dpolukhin): Remove Chrome OS specific profile path logic from
1866 // ProfileManager and use only this function to construct profile path.
1867 // TODO(nkostylev): Cleanup profile dir related code paths crbug.com/294233
1868 base::FilePath profile_dir;
1869 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1870 if (command_line.HasSwitch(::switches::kMultiProfiles)) {
1871 const User* user = FindUser(user_id);
1872 if (user && !user->username_hash().empty())
1873 profile_dir = ProfileHelper::GetUserProfileDir(user->username_hash());
1874 } else if (command_line.HasSwitch(chromeos::switches::kLoginProfile)) {
1875 profile_dir = ProfileHelper::GetProfileDirByLegacyLoginProfileSwitch();
1876 } else {
1877 // We should never be logged in with no profile dir unless
1878 // multi-profiles are enabled.
1879 NOTREACHED();
1880 profile_dir = base::FilePath();
1883 ProfileManager* profile_manager = g_browser_process->profile_manager();
1884 profile_dir = profile_manager->user_data_dir().Append(profile_dir);
1886 return profile_dir;
1889 UserFlow* UserManagerImpl::GetDefaultUserFlow() const {
1890 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1891 if (!default_flow_.get())
1892 default_flow_.reset(new DefaultUserFlow());
1893 return default_flow_.get();
1896 void UserManagerImpl::NotifyUserListChanged() {
1897 content::NotificationService::current()->Notify(
1898 chrome::NOTIFICATION_USER_LIST_CHANGED,
1899 content::Source<UserManager>(this),
1900 content::NotificationService::NoDetails());
1903 void UserManagerImpl::NotifyActiveUserChanged(const User* active_user) {
1904 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1905 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1906 session_state_observer_list_,
1907 ActiveUserChanged(active_user));
1910 void UserManagerImpl::NotifyUserAddedToSession(const User* added_user) {
1911 UpdateNumberOfUsers();
1912 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1913 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1914 session_state_observer_list_,
1915 UserAddedToSession(added_user));
1918 void UserManagerImpl::NotifyActiveUserHashChanged(const std::string& hash) {
1919 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1920 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1921 session_state_observer_list_,
1922 ActiveUserHashChanged(hash));
1925 void UserManagerImpl::NotifyPendingUserSessionsRestoreFinished() {
1926 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1927 user_sessions_restored_ = true;
1928 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1929 session_state_observer_list_,
1930 PendingUserSessionsRestoreFinished());
1933 void UserManagerImpl::UpdateLoginState() {
1934 if (!LoginState::IsInitialized())
1935 return; // LoginState may not be intialized in tests.
1936 LoginState::LoggedInState logged_in_state;
1937 logged_in_state = active_user_ ? LoginState::LOGGED_IN_ACTIVE
1938 : LoginState::LOGGED_IN_NONE;
1940 LoginState::LoggedInUserType login_user_type;
1941 if (logged_in_state == LoginState::LOGGED_IN_NONE)
1942 login_user_type = LoginState::LOGGED_IN_USER_NONE;
1943 else if (is_current_user_owner_)
1944 login_user_type = LoginState::LOGGED_IN_USER_OWNER;
1945 else if (active_user_->GetType() == User::USER_TYPE_GUEST)
1946 login_user_type = LoginState::LOGGED_IN_USER_GUEST;
1947 else if (active_user_->GetType() == User::USER_TYPE_RETAIL_MODE)
1948 login_user_type = LoginState::LOGGED_IN_USER_RETAIL_MODE;
1949 else if (active_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT)
1950 login_user_type = LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT;
1951 else if (active_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED)
1952 login_user_type = LoginState::LOGGED_IN_USER_LOCALLY_MANAGED;
1953 else if (active_user_->GetType() == User::USER_TYPE_KIOSK_APP)
1954 login_user_type = LoginState::LOGGED_IN_USER_KIOSK_APP;
1955 else
1956 login_user_type = LoginState::LOGGED_IN_USER_REGULAR;
1958 LoginState::Get()->SetLoggedInState(logged_in_state, login_user_type);
1961 void UserManagerImpl::SetLRUUser(User* user) {
1962 UserList::iterator it = std::find(lru_logged_in_users_.begin(),
1963 lru_logged_in_users_.end(),
1964 user);
1965 if (it != lru_logged_in_users_.end())
1966 lru_logged_in_users_.erase(it);
1967 lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user);
1970 void UserManagerImpl::OnRestoreActiveSessions(
1971 const SessionManagerClient::ActiveSessionsMap& sessions,
1972 bool success) {
1973 if (!success) {
1974 LOG(ERROR) << "Could not get list of active user sessions after crash.";
1975 // If we could not get list of active user sessions it is safer to just
1976 // sign out so that we don't get in the inconsistent state.
1977 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
1978 return;
1981 // One profile has been already loaded on browser start.
1982 DCHECK(GetLoggedInUsers().size() == 1);
1983 DCHECK(GetActiveUser());
1984 std::string active_user_id = GetActiveUser()->email();
1986 SessionManagerClient::ActiveSessionsMap::const_iterator it;
1987 for (it = sessions.begin(); it != sessions.end(); ++it) {
1988 if (active_user_id == it->first)
1989 continue;
1990 pending_user_sessions_[it->first] = it->second;
1992 RestorePendingUserSessions();
1995 void UserManagerImpl::RestorePendingUserSessions() {
1996 if (pending_user_sessions_.empty()) {
1997 NotifyPendingUserSessionsRestoreFinished();
1998 return;
2001 // Get next user to restore sessions and delete it from list.
2002 SessionManagerClient::ActiveSessionsMap::const_iterator it =
2003 pending_user_sessions_.begin();
2004 std::string user_id = it->first;
2005 std::string user_id_hash = it->second;
2006 DCHECK(!user_id.empty());
2007 DCHECK(!user_id_hash.empty());
2008 pending_user_sessions_.erase(user_id);
2010 // Check that this user is not logged in yet.
2011 UserList logged_in_users = GetLoggedInUsers();
2012 bool user_already_logged_in = false;
2013 for (UserList::const_iterator it = logged_in_users.begin();
2014 it != logged_in_users.end(); ++it) {
2015 const User* user = (*it);
2016 if (user->email() == user_id) {
2017 user_already_logged_in = true;
2018 break;
2021 DCHECK(!user_already_logged_in);
2023 if (!user_already_logged_in) {
2024 // Will call OnProfilePrepared() once profile has been loaded.
2025 LoginUtils::Get()->PrepareProfile(
2026 UserContext(user_id,
2027 std::string(), // password
2028 std::string(), // auth_code
2029 user_id_hash,
2030 false, // using_oauth
2031 UserContext::AUTH_FLOW_OFFLINE),
2032 std::string(), // display_email
2033 false, // has_cookies
2034 true, // has_active_session
2035 this);
2036 } else {
2037 RestorePendingUserSessions();
2041 void UserManagerImpl::SendRegularUserLoginMetrics(const std::string& user_id) {
2042 // If this isn't the first time Chrome was run after the system booted,
2043 // assume that Chrome was restarted because a previous session ended.
2044 if (!CommandLine::ForCurrentProcess()->HasSwitch(
2045 switches::kFirstExecAfterBoot)) {
2046 const std::string last_email =
2047 g_browser_process->local_state()->GetString(kLastLoggedInRegularUser);
2048 const base::TimeDelta time_to_login =
2049 base::TimeTicks::Now() - manager_creation_time_;
2050 if (!last_email.empty() && user_id != last_email &&
2051 time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) {
2052 UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay",
2053 time_to_login.InSeconds(), 0, kLogoutToLoginDelayMaxSec, 50);
2058 void UserManagerImpl::OnUserNotAllowed(const std::string& user_email) {
2059 LOG(ERROR) << "Shutdown session because a user is not allowed to be in the "
2060 "current session";
2061 chromeos::ShowMultiprofilesSessionAbortedDialog(user_email);
2064 void UserManagerImpl::UpdateUserAccountLocale(const std::string& user_id,
2065 const std::string& locale) {
2066 if (!locale.empty() &&
2067 locale != g_browser_process->GetApplicationLocale()) {
2068 BrowserThread::PostBlockingPoolTask(
2069 FROM_HERE,
2070 base::Bind(ResolveLocale, locale,
2071 base::Bind(&UserManagerImpl::DoUpdateAccountLocale,
2072 base::Unretained(this),
2073 user_id)));
2074 } else {
2075 DoUpdateAccountLocale(user_id, locale);
2079 void UserManagerImpl::DoUpdateAccountLocale(
2080 const std::string& user_id,
2081 const std::string& resolved_locale) {
2082 if (User* user = FindUserAndModify(user_id))
2083 user->SetAccountLocale(resolved_locale);
2086 void UserManagerImpl::UpdateNumberOfUsers() {
2087 size_t users = GetLoggedInUsers().size();
2088 if (users) {
2089 // Write the user number as UMA stat when a multi user session is possible.
2090 if ((users + GetUsersAdmittedForMultiProfile().size()) > 1)
2091 ash::MultiProfileUMA::RecordUserCount(users);
2094 base::debug::SetCrashKeyValue(crash_keys::kNumberOfUsers,
2095 base::StringPrintf("%" PRIuS, GetLoggedInUsers().size()));
2098 void UserManagerImpl::DeleteUser(User* user) {
2099 const bool is_active_user = (user == active_user_);
2100 delete user;
2101 if (is_active_user)
2102 active_user_ = NULL;
2105 } // namespace chromeos