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"
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/command_line.h"
13 #include "base/compiler_specific.h"
14 #include "base/files/file_path.h"
15 #include "base/logging.h"
16 #include "base/metrics/histogram.h"
17 #include "base/prefs/pref_registry_simple.h"
18 #include "base/prefs/pref_service.h"
19 #include "base/prefs/scoped_user_pref_update.h"
20 #include "base/rand_util.h"
21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h"
23 #include "base/strings/utf_string_conversions.h"
24 #include "base/sys_info.h"
25 #include "base/threading/worker_pool.h"
26 #include "base/values.h"
27 #include "chrome/browser/app_mode/app_mode_utils.h"
28 #include "chrome/browser/browser_process.h"
29 #include "chrome/browser/chrome_notification_types.h"
30 #include "chrome/browser/chromeos/login/auth_sync_observer.h"
31 #include "chrome/browser/chromeos/login/auth_sync_observer_factory.h"
32 #include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h"
33 #include "chrome/browser/chromeos/login/language_switch_menu.h"
34 #include "chrome/browser/chromeos/login/login_display.h"
35 #include "chrome/browser/chromeos/login/login_utils.h"
36 #include "chrome/browser/chromeos/login/multi_profile_first_run_notification.h"
37 #include "chrome/browser/chromeos/login/multi_profile_user_controller.h"
38 #include "chrome/browser/chromeos/login/remove_user_delegate.h"
39 #include "chrome/browser/chromeos/login/supervised_user_manager_impl.h"
40 #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
41 #include "chrome/browser/chromeos/login/wizard_controller.h"
42 #include "chrome/browser/chromeos/policy/device_local_account.h"
43 #include "chrome/browser/chromeos/profiles/profile_helper.h"
44 #include "chrome/browser/chromeos/session_length_limiter.h"
45 #include "chrome/browser/lifetime/application_lifetime.h"
46 #include "chrome/browser/managed_mode/managed_user_service.h"
47 #include "chrome/browser/policy/browser_policy_connector.h"
48 #include "chrome/browser/profiles/profile.h"
49 #include "chrome/browser/profiles/profile_manager.h"
50 #include "chrome/browser/sync/profile_sync_service.h"
51 #include "chrome/browser/sync/profile_sync_service_factory.h"
52 #include "chrome/common/chrome_constants.h"
53 #include "chrome/common/chrome_switches.h"
54 #include "chrome/common/pref_names.h"
55 #include "chromeos/chromeos_switches.h"
56 #include "chromeos/cryptohome/async_method_caller.h"
57 #include "chromeos/dbus/dbus_thread_manager.h"
58 #include "chromeos/login/login_state.h"
59 #include "chromeos/settings/cros_settings_names.h"
60 #include "content/public/browser/browser_thread.h"
61 #include "content/public/browser/notification_service.h"
62 #include "google_apis/gaia/gaia_auth_util.h"
63 #include "google_apis/gaia/google_service_auth_error.h"
64 #include "policy/policy_constants.h"
65 #include "ui/base/l10n/l10n_util.h"
66 #include "ui/views/corewm/corewm_switches.h"
68 using content::BrowserThread;
72 struct UpdateUserAccountDataCallbackData {
73 UpdateUserAccountDataCallbackData(const std::string& user_id,
74 const string16& display_name,
75 const std::string& raw_locale)
77 display_name_(display_name),
78 raw_locale_(raw_locale) {}
80 string16 display_name_;
81 std::string raw_locale_;
82 std::string resolved_locale_;
87 // A vector pref of the the regular users known on this device, arranged in LRU
89 const char kRegularUsers[] = "LoggedInUsers";
91 // A vector pref of the public accounts defined on this device.
92 const char kPublicAccounts[] = "PublicAccounts";
94 // A string pref that gets set when a public account is removed but a user is
95 // currently logged into that account, requiring the account's data to be
96 // removed after logout.
97 const char kPublicAccountPendingDataRemoval[] =
98 "PublicAccountPendingDataRemoval";
100 // A dictionary that maps usernames to the displayed name.
101 const char kUserDisplayName[] = "UserDisplayName";
103 // A dictionary that maps usernames to the displayed (non-canonical) emails.
104 const char kUserDisplayEmail[] = "UserDisplayEmail";
106 // A dictionary that maps usernames to OAuth token presence flag.
107 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus";
109 // A string pref containing the ID of the last user who logged in if it was
110 // a regular user or an empty string if it was another type of user (guest,
111 // kiosk, public account, etc.).
112 const char kLastLoggedInRegularUser[] = "LastLoggedInRegularUser";
114 // Upper bound for a histogram metric reporting the amount of time between
115 // one regular user logging out and a different regular user logging in.
116 const int kLogoutToLoginDelayMaxSec = 1800;
118 // Callback that is called after user removal is complete.
119 void OnRemoveUserComplete(const std::string& user_email,
121 cryptohome::MountError return_code) {
122 // Log the error, but there's not much we can do.
124 LOG(ERROR) << "Removal of cryptohome for " << user_email
125 << " failed, return code: " << return_code;
129 // This method is used to implement UserManager::RemoveUser.
130 void RemoveUserInternal(const std::string& user_email,
131 chromeos::RemoveUserDelegate* delegate) {
132 CrosSettings* cros_settings = CrosSettings::Get();
134 // Ensure the value of owner email has been fetched.
135 if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues(
136 base::Bind(&RemoveUserInternal, user_email, delegate))) {
137 // Value of owner email is not fetched yet. RemoveUserInternal will be
138 // called again after fetch completion.
142 cros_settings->GetString(kDeviceOwner, &owner);
143 if (user_email == owner) {
144 // Owner is not allowed to be removed from the device.
149 delegate->OnBeforeUserRemoved(user_email);
151 chromeos::UserManager::Get()->RemoveUserFromList(user_email);
152 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
153 user_email, base::Bind(&OnRemoveUserComplete, user_email));
156 delegate->OnUserRemoved(user_email);
159 // Helper function that copies users from |users_list| to |users_vector| and
160 // |users_set|. Duplicates and users already present in |existing_users| are
162 void ParseUserList(const ListValue& users_list,
163 const std::set<std::string>& existing_users,
164 std::vector<std::string>* users_vector,
165 std::set<std::string>* users_set) {
166 users_vector->clear();
168 for (size_t i = 0; i < users_list.GetSize(); ++i) {
170 if (!users_list.GetString(i, &email) || email.empty()) {
171 LOG(ERROR) << "Corrupt entry in user list at index " << i << ".";
174 if (existing_users.find(email) != existing_users.end() ||
175 !users_set->insert(email).second) {
176 LOG(ERROR) << "Duplicate user: " << email;
179 users_vector->push_back(email);
183 class UserHashMatcher {
185 explicit UserHashMatcher(const std::string& h) : username_hash(h) {}
186 bool operator()(const User* user) const {
187 return user->username_hash() == username_hash;
191 const std::string& username_hash;
194 // Runs on SequencedWorkerPool thread.
195 static void UpdateUserAccountDataImplCheckAndResolveLocale(
196 std::string* raw_account_locale,
197 std::string* resolved_account_locale) {
198 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
200 l10n_util::CheckAndResolveLocale(*raw_account_locale,
201 resolved_account_locale);
207 void UserManager::RegisterPrefs(PrefRegistrySimple* registry) {
208 registry->RegisterListPref(kRegularUsers);
209 registry->RegisterListPref(kPublicAccounts);
210 registry->RegisterStringPref(kPublicAccountPendingDataRemoval, "");
211 registry->RegisterStringPref(kLastLoggedInRegularUser, "");
212 registry->RegisterDictionaryPref(kUserOAuthTokenStatus);
213 registry->RegisterDictionaryPref(kUserDisplayName);
214 registry->RegisterDictionaryPref(kUserDisplayEmail);
215 SupervisedUserManager::RegisterPrefs(registry);
216 SessionLengthLimiter::RegisterPrefs(registry);
219 UserManagerImpl::UserManagerImpl()
220 : cros_settings_(CrosSettings::Get()),
221 device_local_account_policy_service_(NULL),
222 users_loaded_(false),
225 session_started_(false),
226 user_sessions_restored_(false),
227 is_current_user_owner_(false),
228 is_current_user_new_(false),
229 is_current_user_ephemeral_regular_user_(false),
230 ephemeral_users_enabled_(false),
231 user_image_manager_(new UserImageManagerImpl),
232 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
233 manager_creation_time_(base::TimeTicks::Now()),
234 multi_profile_first_run_notification_(
235 new MultiProfileFirstRunNotification) {
236 // UserManager instance should be used only on UI thread.
237 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
238 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
239 content::NotificationService::AllSources());
240 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
241 content::NotificationService::AllSources());
243 chrome::NOTIFICATION_PROFILE_CREATED,
244 content::NotificationService::AllSources());
245 RetrieveTrustedDevicePolicies();
246 local_accounts_subscription_ = cros_settings_->AddSettingsObserver(
247 kAccountsPrefDeviceLocalAccounts,
248 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
249 base::Unretained(this)));
250 supervised_users_subscription_ = cros_settings_->AddSettingsObserver(
251 kAccountsPrefSupervisedUsersEnabled,
252 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
253 base::Unretained(this)));
254 multi_profile_user_controller_.reset(new MultiProfileUserController(
255 this, g_browser_process->local_state()));
259 UserManagerImpl::~UserManagerImpl() {
260 // Can't use STLDeleteElements because of the private destructor of User.
261 for (UserList::iterator it = users_.begin(); it != users_.end();
262 it = users_.erase(it)) {
263 if (active_user_ == *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();
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 user_image_manager_->Shutdown();
285 multi_profile_user_controller_.reset();
288 UserImageManager* UserManagerImpl::GetUserImageManager() {
289 return user_image_manager_.get();
292 SupervisedUserManager* UserManagerImpl::GetSupervisedUserManager() {
293 return supervised_user_manager_.get();
296 const UserList& UserManagerImpl::GetUsers() const {
297 const_cast<UserManagerImpl*>(this)->EnsureUsersLoaded();
301 UserList UserManagerImpl::GetUsersAdmittedForMultiProfile() const {
302 if (!UserManager::IsMultipleProfilesAllowed())
306 const UserList& users = GetUsers();
307 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
308 if ((*it)->GetType() == User::USER_TYPE_REGULAR &&
309 !(*it)->is_logged_in() &&
310 multi_profile_user_controller_->IsUserAllowedInSession(
312 result.push_back(*it);
318 const UserList& UserManagerImpl::GetLoggedInUsers() const {
319 return logged_in_users_;
322 const UserList& UserManagerImpl::GetLRULoggedInUsers() {
323 // If there is no user logged in, we return the active user as the only one.
324 if (lru_logged_in_users_.empty() && active_user_) {
325 temp_single_logged_in_users_.clear();
326 temp_single_logged_in_users_.insert(temp_single_logged_in_users_.begin(),
328 return temp_single_logged_in_users_;
330 return lru_logged_in_users_;
333 UserList UserManagerImpl::GetUnlockUsers() const {
334 UserList unlock_users;
335 CHECK(primary_user_);
336 unlock_users.push_back(primary_user_);
340 const std::string& UserManagerImpl::GetOwnerEmail() {
344 void UserManagerImpl::UserLoggedIn(const std::string& user_id,
345 const std::string& username_hash,
346 bool browser_restart) {
347 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
349 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles))
350 DCHECK(!IsUserLoggedIn());
352 User* user = FindUserInListAndModify(user_id);
353 if (active_user_ && user) {
354 user->set_is_logged_in(true);
355 user->set_username_hash(username_hash);
356 logged_in_users_.push_back(user);
357 lru_logged_in_users_.push_back(user);
358 // Reset the new user flag if the user already exists.
359 is_current_user_new_ = false;
360 // Set active user wallpaper back.
361 WallpaperManager::Get()->SetUserWallpaper(active_user_->email());
362 NotifyUserAddedToSession(user);
366 policy::DeviceLocalAccount::Type device_local_account_type;
367 if (user_id == UserManager::kGuestUserName) {
369 } else if (user_id == UserManager::kRetailModeUserName) {
370 RetailModeUserLoggedIn();
371 } else if (policy::IsDeviceLocalAccountUser(user_id,
372 &device_local_account_type) &&
373 device_local_account_type ==
374 policy::DeviceLocalAccount::TYPE_KIOSK_APP) {
375 KioskAppLoggedIn(user_id);
379 if (user && user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
380 PublicAccountUserLoggedIn(user);
381 } else if ((user && user->GetType() == User::USER_TYPE_LOCALLY_MANAGED) ||
382 (!user && gaia::ExtractDomainName(user_id) ==
383 UserManager::kLocallyManagedUserDomain)) {
384 LocallyManagedUserLoggedIn(user_id);
385 } else if (browser_restart && user_id == g_browser_process->local_state()->
386 GetString(kPublicAccountPendingDataRemoval)) {
387 PublicAccountUserLoggedIn(User::CreatePublicAccountUser(user_id));
388 } else if (user_id != owner_email_ && !user &&
389 (AreEphemeralUsersEnabled() || browser_restart)) {
390 RegularUserLoggedInAsEphemeral(user_id);
392 RegularUserLoggedIn(user_id);
395 // Initialize the session length limiter and start it only if
396 // session limit is defined by the policy.
397 session_length_limiter_.reset(new SessionLengthLimiter(NULL,
400 DCHECK(active_user_);
401 active_user_->set_is_logged_in(true);
402 active_user_->set_is_active(true);
403 active_user_->set_username_hash(username_hash);
405 // Place user who just signed in to the top of the logged in users.
406 logged_in_users_.insert(logged_in_users_.begin(), active_user_);
407 SetLRUUser(active_user_);
409 if (!primary_user_) {
410 primary_user_ = active_user_;
411 if (primary_user_->GetType() == User::USER_TYPE_REGULAR)
412 SendRegularUserLoginMetrics(user_id);
415 UMA_HISTOGRAM_ENUMERATION("UserManager.LoginUserType",
416 active_user_->GetType(), User::NUM_USER_TYPES);
418 if (IsMultipleProfilesAllowed()) {
419 UMA_HISTOGRAM_COUNTS_100("MultiProfile.UserCount",
420 GetLoggedInUsers().size());
423 g_browser_process->local_state()->SetString(kLastLoggedInRegularUser,
424 (active_user_->GetType() == User::USER_TYPE_REGULAR) ? user_id : "");
429 void UserManagerImpl::SwitchActiveUser(const std::string& user_id) {
430 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles))
433 User* user = FindUserAndModify(user_id);
435 NOTREACHED() << "Switching to a non-existing user";
438 if (user == active_user_) {
439 NOTREACHED() << "Switching to a user who is already active";
442 if (!user->is_logged_in()) {
443 NOTREACHED() << "Switching to a user that is not logged in";
446 if (user->GetType() != User::USER_TYPE_REGULAR) {
447 NOTREACHED() << "Switching to a non-regular user";
450 if (user->username_hash().empty()) {
451 NOTREACHED() << "Switching to a user that doesn't have username_hash set";
455 DCHECK(active_user_);
456 active_user_->set_is_active(false);
457 user->set_is_active(true);
460 // Move the user to the front.
461 SetLRUUser(active_user_);
463 NotifyActiveUserHashChanged(active_user_->username_hash());
464 NotifyActiveUserChanged(active_user_);
467 void UserManagerImpl::RestoreActiveSessions() {
468 DBusThreadManager::Get()->GetSessionManagerClient()->RetrieveActiveSessions(
469 base::Bind(&UserManagerImpl::OnRestoreActiveSessions,
470 base::Unretained(this)));
473 void UserManagerImpl::SessionStarted() {
474 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
475 session_started_ = true;
477 content::NotificationService::current()->Notify(
478 chrome::NOTIFICATION_SESSION_STARTED,
479 content::Source<UserManager>(this),
480 content::Details<const User>(active_user_));
481 if (is_current_user_new_) {
482 // Make sure that the new user's data is persisted to Local State.
483 g_browser_process->local_state()->CommitPendingWrite();
487 void UserManagerImpl::RemoveUser(const std::string& user_id,
488 RemoveUserDelegate* delegate) {
489 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
491 const User* user = FindUser(user_id);
492 if (!user || (user->GetType() != User::USER_TYPE_REGULAR &&
493 user->GetType() != User::USER_TYPE_LOCALLY_MANAGED))
496 // Sanity check: we must not remove single user. This check may seem
497 // redundant at a first sight because this single user must be an owner and
498 // we perform special check later in order not to remove an owner. However
499 // due to non-instant nature of ownership assignment this later check may
500 // sometimes fail. See http://crosbug.com/12723
501 if (users_.size() < 2)
504 // Sanity check: do not allow any of the the logged in users to be removed.
505 for (UserList::const_iterator it = logged_in_users_.begin();
506 it != logged_in_users_.end(); ++it) {
507 if ((*it)->email() == user_id)
511 RemoveUserInternal(user_id, delegate);
514 void UserManagerImpl::RemoveUserFromList(const std::string& user_id) {
515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
517 RemoveNonCryptohomeData(user_id);
518 User* user = RemoveRegularOrLocallyManagedUserFromList(user_id);
520 // Make sure that new data is persisted to Local State.
521 g_browser_process->local_state()->CommitPendingWrite();
524 bool UserManagerImpl::IsKnownUser(const std::string& user_id) const {
525 return FindUser(user_id) != NULL;
528 const User* UserManagerImpl::FindUser(const std::string& user_id) const {
529 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
530 if (active_user_ && active_user_->email() == user_id)
532 return FindUserInList(user_id);
535 const User* UserManagerImpl::GetLoggedInUser() const {
536 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
540 User* UserManagerImpl::GetLoggedInUser() {
541 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
545 const User* UserManagerImpl::GetActiveUser() const {
546 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
550 User* UserManagerImpl::GetActiveUser() {
551 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
555 const User* UserManagerImpl::GetPrimaryUser() const {
556 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
557 return primary_user_;
560 User* UserManagerImpl::GetUserByProfile(Profile* profile) const {
561 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
562 if (ProfileHelper::IsSigninProfile(profile))
565 if (IsMultipleProfilesAllowed()) {
566 const std::string username_hash =
567 ProfileHelper::GetUserIdHashFromProfile(profile);
568 const UserList& users = GetUsers();
569 const UserList::const_iterator pos = std::find_if(
570 users.begin(), users.end(), UserHashMatcher(username_hash));
571 return (pos != users.end()) ? *pos : NULL;
576 void UserManagerImpl::SaveUserOAuthStatus(
577 const std::string& user_id,
578 User::OAuthTokenStatus oauth_token_status) {
579 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
581 DVLOG(1) << "Saving user OAuth token status in Local State";
582 User* user = FindUserAndModify(user_id);
584 user->set_oauth_token_status(oauth_token_status);
586 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(oauth_token_status);
588 // Do not update local store if data stored or cached outside the user's
589 // cryptohome is to be treated as ephemeral.
590 if (IsUserNonCryptohomeDataEphemeral(user_id))
593 PrefService* local_state = g_browser_process->local_state();
595 DictionaryPrefUpdate oauth_status_update(local_state, kUserOAuthTokenStatus);
596 oauth_status_update->SetWithoutPathExpansion(user_id,
597 new base::FundamentalValue(static_cast<int>(oauth_token_status)));
600 User::OAuthTokenStatus UserManagerImpl::LoadUserOAuthStatus(
601 const std::string& user_id) const {
602 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
604 PrefService* local_state = g_browser_process->local_state();
605 const DictionaryValue* prefs_oauth_status =
606 local_state->GetDictionary(kUserOAuthTokenStatus);
607 int oauth_token_status = User::OAUTH_TOKEN_STATUS_UNKNOWN;
608 if (prefs_oauth_status &&
609 prefs_oauth_status->GetIntegerWithoutPathExpansion(
610 user_id, &oauth_token_status)) {
611 User::OAuthTokenStatus result =
612 static_cast<User::OAuthTokenStatus>(oauth_token_status);
613 if (result == User::OAUTH2_TOKEN_STATUS_INVALID)
614 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(result);
617 return User::OAUTH_TOKEN_STATUS_UNKNOWN;
620 void UserManagerImpl::SaveUserDisplayName(const std::string& username,
621 const string16& display_name) {
622 UpdateUserAccountDataImpl(username, display_name, NULL);
625 void UserManagerImpl::UpdateUserAccountData(const std::string& username,
626 const string16& display_name,
627 const std::string& locale) {
628 UpdateUserAccountDataImpl(username, display_name, &locale);
631 // "second part" of UpdateUserAccountDataImpl is sometimes called as
632 // callback after IO thread has resolved locale.
633 void UserManagerImpl::UpdateUserAccountDataImplCallback(
634 const std::string& username,
635 const string16& display_name,
636 const std::string* resolved_account_locale) {
637 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
639 User* user = FindUserAndModify(username);
641 return; // Ignore if there is no such user.
643 // locale is not NULL if User Account has been downloaded
644 // (i.e. it is UpdateUserAccountData(), not SaveUserDisplayName() )
645 if (resolved_account_locale != NULL)
646 user->SetAccountLocale(*resolved_account_locale);
648 if (display_name.empty())
651 user->set_display_name(display_name);
653 // Do not update local store if data stored or cached outside the user's
654 // cryptohome is to be treated as ephemeral.
655 if (IsUserNonCryptohomeDataEphemeral(username))
658 PrefService* local_state = g_browser_process->local_state();
660 DictionaryPrefUpdate display_name_update(local_state, kUserDisplayName);
661 display_name_update->SetWithoutPathExpansion(
663 new base::StringValue(display_name));
665 supervised_user_manager_->UpdateManagerName(username, display_name);
668 // Proxy for the previous call.
669 void UserManagerImpl::UpdateUserAccountDataImplCallbackDecorator(
670 const scoped_ptr<UpdateUserAccountDataCallbackData>& data) {
671 UpdateUserAccountDataImplCallback(
672 data->user_id_, data->display_name_, &(data->resolved_locale_));
675 void UserManagerImpl::UpdateUserAccountDataImpl(const std::string& username,
676 const string16& display_name,
677 const std::string* locale) {
678 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
680 // locale is not NULL if User Account has been downloaded
681 // (i.e. it is UpdateUserAccountData(), not SaveUserDisplayName() )
682 if ((locale != NULL) && (!locale->empty()) &&
683 (*locale != g_browser_process->GetApplicationLocale())) {
684 scoped_ptr<UpdateUserAccountDataCallbackData> data(
685 new UpdateUserAccountDataCallbackData(username, display_name, *locale));
687 base::Closure resolver(
688 base::Bind(&UpdateUserAccountDataImplCheckAndResolveLocale,
689 base::Unretained(&(data->raw_locale_)),
690 base::Unretained(&(data->resolved_locale_))));
691 BrowserThread::PostBlockingPoolTaskAndReply(
694 base::Bind(&chromeos::UserManagerImpl::
695 UpdateUserAccountDataImplCallbackDecorator,
696 base::Unretained(this),
697 base::Passed(&data)));
699 UpdateUserAccountDataImplCallback(username, display_name, locale);
703 string16 UserManagerImpl::GetUserDisplayName(
704 const std::string& username) const {
705 const User* user = FindUser(username);
706 return user ? user->display_name() : string16();
709 void UserManagerImpl::SaveUserDisplayEmail(const std::string& username,
710 const std::string& display_email) {
711 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
713 User* user = FindUserAndModify(username);
715 return; // Ignore if there is no such user.
717 user->set_display_email(display_email);
719 // Do not update local store if data stored or cached outside the user's
720 // cryptohome is to be treated as ephemeral.
721 if (IsUserNonCryptohomeDataEphemeral(username))
724 PrefService* local_state = g_browser_process->local_state();
726 DictionaryPrefUpdate display_email_update(local_state, kUserDisplayEmail);
727 display_email_update->SetWithoutPathExpansion(
729 new base::StringValue(display_email));
732 std::string UserManagerImpl::GetUserDisplayEmail(
733 const std::string& username) const {
734 const User* user = FindUser(username);
735 return user ? user->display_email() : username;
738 // TODO(alemate): http://crbug.com/288941 : Respect preferred language list in
739 // the Google user profile.
740 void UserManagerImpl::RespectLocalePreference(Profile* profile,
741 const User* user) const {
742 if (g_browser_process == NULL)
744 if ((user == NULL) || (user != GetPrimaryUser()) ||
745 (!user->is_profile_created()))
748 // In case of Multi Profile mode we don't apply profile locale because it is
750 if (GetLoggedInUsers().size() != 1)
752 const PrefService* prefs = profile->GetPrefs();
756 std::string pref_locale;
757 const std::string pref_app_locale =
758 prefs->GetString(prefs::kApplicationLocale);
759 const std::string pref_bkup_locale =
760 prefs->GetString(prefs::kApplicationLocaleBackup);
762 pref_locale = pref_app_locale;
763 if (pref_locale.empty())
764 pref_locale = pref_bkup_locale;
766 const std::string* account_locale = NULL;
767 if (pref_locale.empty() && user->has_gaia_account()) {
768 if (user->GetAccountLocale() == NULL)
769 return; // wait until Account profile is loaded.
770 account_locale = user->GetAccountLocale();
771 pref_locale = *account_locale;
773 const std::string global_app_locale =
774 g_browser_process->GetApplicationLocale();
775 if (pref_locale.empty())
776 pref_locale = global_app_locale;
777 DCHECK(!pref_locale.empty());
778 LOG(WARNING) << "RespectLocalePreference: "
779 << "app_locale='" << pref_app_locale << "', "
780 << "bkup_locale='" << pref_bkup_locale << "', "
781 << (account_locale != NULL
782 ? (std::string("account_locale='") + (*account_locale) +
784 : (std::string("account_locale - unused. ")))
785 << " Selected '" << pref_locale << "'";
786 profile->ChangeAppLocale(pref_locale, Profile::APP_LOCALE_CHANGED_VIA_LOGIN);
787 // Here we don't enable keyboard layouts. Input methods are set up when
788 // the user first logs in. Then the user may customize the input methods.
789 // Hence changing input methods here, just because the user's UI language
790 // is different from the login screen UI language, is not desirable. Note
791 // that input method preferences are synced, so users can use their
792 // farovite input methods as soon as the preferences are synced.
793 chromeos::LanguageSwitchMenu::SwitchLanguage(pref_locale);
796 Profile* UserManagerImpl::GetProfileByUser(const User* user) const {
797 if (IsMultipleProfilesAllowed())
798 return ProfileHelper::GetProfileByUserIdHash(user->username_hash());
799 return g_browser_process->profile_manager()->GetDefaultProfile();
802 void UserManagerImpl::Observe(int type,
803 const content::NotificationSource& source,
804 const content::NotificationDetails& details) {
806 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED:
807 if (!device_local_account_policy_service_) {
808 device_local_account_policy_service_ =
809 g_browser_process->browser_policy_connector()->
810 GetDeviceLocalAccountPolicyService();
811 if (device_local_account_policy_service_)
812 device_local_account_policy_service_->AddObserver(this);
814 RetrieveTrustedDevicePolicies();
817 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED:
818 if (IsUserLoggedIn() &&
819 !IsLoggedInAsGuest() &&
820 !IsLoggedInAsKioskApp()) {
821 Profile* profile = content::Details<Profile>(details).ptr();
822 if (!profile->IsOffTheRecord()) {
823 AuthSyncObserver* sync_observer =
824 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile);
825 sync_observer->StartObserving();
826 multi_profile_user_controller_->StartObserving(profile);
827 multi_profile_first_run_notification_->UserProfilePrepared(profile);
831 case chrome::NOTIFICATION_PROFILE_CREATED: {
832 Profile* profile = content::Source<Profile>(source).ptr();
833 User* user = GetUserByProfile(profile);
835 user->set_profile_is_created();
844 void UserManagerImpl::OnPolicyUpdated(const std::string& user_id) {
845 UpdatePublicAccountDisplayName(user_id);
846 NotifyUserListChanged();
849 void UserManagerImpl::OnDeviceLocalAccountsChanged() {
850 // No action needed here, changes to the list of device-local accounts get
851 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
854 bool UserManagerImpl::IsCurrentUserOwner() const {
855 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
856 base::AutoLock lk(is_current_user_owner_lock_);
857 return is_current_user_owner_;
860 void UserManagerImpl::SetCurrentUserIsOwner(bool is_current_user_owner) {
861 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
863 base::AutoLock lk(is_current_user_owner_lock_);
864 is_current_user_owner_ = is_current_user_owner;
869 bool UserManagerImpl::IsCurrentUserNew() const {
870 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
871 return is_current_user_new_;
874 bool UserManagerImpl::IsCurrentUserNonCryptohomeDataEphemeral() const {
875 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
876 return IsUserLoggedIn() &&
877 IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email());
880 bool UserManagerImpl::CanCurrentUserLock() const {
881 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
882 return IsUserLoggedIn() && active_user_->can_lock();
885 bool UserManagerImpl::IsUserLoggedIn() const {
886 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
890 bool UserManagerImpl::IsLoggedInAsRegularUser() const {
891 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
892 return IsUserLoggedIn() &&
893 active_user_->GetType() == User::USER_TYPE_REGULAR;
896 bool UserManagerImpl::IsLoggedInAsDemoUser() const {
897 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
898 return IsUserLoggedIn() &&
899 active_user_->GetType() == User::USER_TYPE_RETAIL_MODE;
902 bool UserManagerImpl::IsLoggedInAsPublicAccount() const {
903 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
904 return IsUserLoggedIn() &&
905 active_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
908 bool UserManagerImpl::IsLoggedInAsGuest() const {
909 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
910 return IsUserLoggedIn() &&
911 active_user_->GetType() == User::USER_TYPE_GUEST;
914 bool UserManagerImpl::IsLoggedInAsLocallyManagedUser() const {
915 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
916 return IsUserLoggedIn() &&
917 active_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED;
920 bool UserManagerImpl::IsLoggedInAsKioskApp() const {
921 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
922 return IsUserLoggedIn() &&
923 active_user_->GetType() == User::USER_TYPE_KIOSK_APP;
926 bool UserManagerImpl::IsLoggedInAsStub() const {
927 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
928 return IsUserLoggedIn() && active_user_->email() == kStubUser;
931 bool UserManagerImpl::IsSessionStarted() const {
932 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
933 return session_started_;
936 bool UserManagerImpl::UserSessionsRestored() const {
937 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
938 return user_sessions_restored_;
941 bool UserManagerImpl::HasBrowserRestarted() const {
942 CommandLine* command_line = CommandLine::ForCurrentProcess();
943 return base::SysInfo::IsRunningOnChromeOS() &&
944 command_line->HasSwitch(switches::kLoginUser) &&
945 !command_line->HasSwitch(switches::kLoginPassword);
948 bool UserManagerImpl::IsUserNonCryptohomeDataEphemeral(
949 const std::string& user_id) const {
950 // Data belonging to the guest, retail mode and stub users is always
952 if (user_id == UserManager::kGuestUserName ||
953 user_id == UserManager::kRetailModeUserName ||
954 user_id == kStubUser) {
958 // Data belonging to the owner, anyone found on the user list and obsolete
959 // public accounts whose data has not been removed yet is not ephemeral.
960 if (user_id == owner_email_ || FindUserInList(user_id) ||
961 user_id == g_browser_process->local_state()->
962 GetString(kPublicAccountPendingDataRemoval)) {
966 // Data belonging to the currently logged-in user is ephemeral when:
967 // a) The user logged into a regular account while the ephemeral users policy
970 // b) The user logged into any other account type.
971 if (IsUserLoggedIn() && (user_id == GetLoggedInUser()->email()) &&
972 (is_current_user_ephemeral_regular_user_ || !IsLoggedInAsRegularUser())) {
976 // Data belonging to any other user is ephemeral when:
977 // a) Going through the regular login flow and the ephemeral users policy is
980 // b) The browser is restarting after a crash.
981 return AreEphemeralUsersEnabled() || HasBrowserRestarted();
984 void UserManagerImpl::AddObserver(UserManager::Observer* obs) {
985 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
986 observer_list_.AddObserver(obs);
989 void UserManagerImpl::RemoveObserver(UserManager::Observer* obs) {
990 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
991 observer_list_.RemoveObserver(obs);
994 void UserManagerImpl::AddSessionStateObserver(
995 UserManager::UserSessionStateObserver* obs) {
996 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
997 session_state_observer_list_.AddObserver(obs);
1000 void UserManagerImpl::RemoveSessionStateObserver(
1001 UserManager::UserSessionStateObserver* obs) {
1002 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1003 session_state_observer_list_.RemoveObserver(obs);
1006 void UserManagerImpl::NotifyLocalStateChanged() {
1007 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1008 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_,
1009 LocalStateChanged(this));
1012 void UserManagerImpl::OnProfilePrepared(Profile* profile) {
1013 LoginUtils::Get()->DoBrowserLaunch(profile,
1014 NULL); // host_, not needed here
1016 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) {
1017 // Did not log in (we crashed or are debugging), need to restore Sync.
1018 // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
1019 // users once it is fully multi-profile aware. http://crbug.com/238987
1020 // For now if we have other user pending sessions they'll override OAuth
1021 // session restore for previous users.
1022 LoginUtils::Get()->RestoreAuthenticationSession(profile);
1025 // Restore other user sessions if any.
1026 RestorePendingUserSessions();
1029 void UserManagerImpl::EnsureUsersLoaded() {
1030 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1031 if (!g_browser_process || !g_browser_process->local_state())
1036 users_loaded_ = true;
1038 // Clean up user list first.
1039 if (supervised_user_manager_->HasFailedUserCreationTransaction())
1040 supervised_user_manager_->RollbackUserCreationTransaction();
1042 PrefService* local_state = g_browser_process->local_state();
1043 const ListValue* prefs_regular_users = local_state->GetList(kRegularUsers);
1044 const ListValue* prefs_public_accounts =
1045 local_state->GetList(kPublicAccounts);
1046 const DictionaryValue* prefs_display_names =
1047 local_state->GetDictionary(kUserDisplayName);
1048 const DictionaryValue* prefs_display_emails =
1049 local_state->GetDictionary(kUserDisplayEmail);
1051 // Load regular users and locally managed users.
1052 std::vector<std::string> regular_users;
1053 std::set<std::string> regular_users_set;
1054 ParseUserList(*prefs_regular_users, std::set<std::string>(),
1055 ®ular_users, ®ular_users_set);
1056 for (std::vector<std::string>::const_iterator it = regular_users.begin();
1057 it != regular_users.end(); ++it) {
1059 const std::string domain = gaia::ExtractDomainName(*it);
1060 if (domain == UserManager::kLocallyManagedUserDomain)
1061 user = User::CreateLocallyManagedUser(*it);
1063 user = User::CreateRegularUser(*it);
1064 user->set_oauth_token_status(LoadUserOAuthStatus(*it));
1065 users_.push_back(user);
1067 string16 display_name;
1068 if (prefs_display_names->GetStringWithoutPathExpansion(*it,
1070 user->set_display_name(display_name);
1073 std::string display_email;
1074 if (prefs_display_emails->GetStringWithoutPathExpansion(*it,
1076 user->set_display_email(display_email);
1080 // Load public accounts.
1081 std::vector<std::string> public_accounts;
1082 std::set<std::string> public_accounts_set;
1083 ParseUserList(*prefs_public_accounts, regular_users_set,
1084 &public_accounts, &public_accounts_set);
1085 for (std::vector<std::string>::const_iterator it = public_accounts.begin();
1086 it != public_accounts.end(); ++it) {
1087 users_.push_back(User::CreatePublicAccountUser(*it));
1088 UpdatePublicAccountDisplayName(*it);
1091 user_image_manager_->LoadUserImages(users_);
1094 void UserManagerImpl::RetrieveTrustedDevicePolicies() {
1095 ephemeral_users_enabled_ = false;
1098 // Schedule a callback if device policy has not yet been verified.
1099 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
1100 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
1101 base::Unretained(this)))) {
1105 cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
1106 &ephemeral_users_enabled_);
1107 cros_settings_->GetString(kDeviceOwner, &owner_email_);
1109 EnsureUsersLoaded();
1111 bool changed = UpdateAndCleanUpPublicAccounts(
1112 policy::GetDeviceLocalAccounts(cros_settings_));
1114 // If ephemeral users are enabled and we are on the login screen, take this
1115 // opportunity to clean up by removing all regular users except the owner.
1116 if (ephemeral_users_enabled_ && !IsUserLoggedIn()) {
1117 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1119 prefs_users_update->Clear();
1120 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1121 const std::string user_email = (*it)->email();
1122 if ((*it)->GetType() == User::USER_TYPE_REGULAR &&
1123 user_email != owner_email_) {
1124 RemoveNonCryptohomeData(user_email);
1126 it = users_.erase(it);
1129 if ((*it)->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT)
1130 prefs_users_update->Append(new base::StringValue(user_email));
1137 NotifyUserListChanged();
1140 bool UserManagerImpl::AreEphemeralUsersEnabled() const {
1141 return ephemeral_users_enabled_ &&
1142 (g_browser_process->browser_policy_connector()->IsEnterpriseManaged() ||
1143 !owner_email_.empty());
1146 UserList& UserManagerImpl::GetUsersAndModify() {
1147 EnsureUsersLoaded();
1151 User* UserManagerImpl::FindUserAndModify(const std::string& user_id) {
1152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1153 if (active_user_ && active_user_->email() == user_id)
1154 return active_user_;
1155 return FindUserInListAndModify(user_id);
1158 const User* UserManagerImpl::FindUserInList(const std::string& user_id) const {
1159 const UserList& users = GetUsers();
1160 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
1161 if ((*it)->email() == user_id)
1167 User* UserManagerImpl::FindUserInListAndModify(const std::string& user_id) {
1168 UserList& users = GetUsersAndModify();
1169 for (UserList::iterator it = users.begin(); it != users.end(); ++it) {
1170 if ((*it)->email() == user_id)
1176 void UserManagerImpl::GuestUserLoggedIn() {
1177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1178 active_user_ = User::CreateGuestUser();
1179 // TODO(nkostylev): Add support for passing guest session cryptohome
1180 // mount point. Legacy (--login-profile) value will be used for now.
1181 // http://crosbug.com/230859
1182 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1183 // Initializes wallpaper after active_user_ is set.
1184 WallpaperManager::Get()->SetInitialUserWallpaper(UserManager::kGuestUserName,
1188 void UserManagerImpl::AddUserRecord(User* user) {
1189 // Add the user to the front of the user list.
1190 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1192 prefs_users_update->Insert(0, new base::StringValue(user->email()));
1193 users_.insert(users_.begin(), user);
1196 void UserManagerImpl::RegularUserLoggedIn(const std::string& user_id) {
1197 // Remove the user from the user list.
1198 active_user_ = RemoveRegularOrLocallyManagedUserFromList(user_id);
1200 // If the user was not found on the user list, create a new user.
1201 is_current_user_new_ = !active_user_;
1202 if (!active_user_) {
1203 active_user_ = User::CreateRegularUser(user_id);
1204 active_user_->set_oauth_token_status(LoadUserOAuthStatus(user_id));
1205 SaveUserDisplayName(active_user_->email(),
1206 UTF8ToUTF16(active_user_->GetAccountName(true)));
1207 WallpaperManager::Get()->SetInitialUserWallpaper(user_id, true);
1210 AddUserRecord(active_user_);
1212 user_image_manager_->UserLoggedIn(user_id, is_current_user_new_, false);
1214 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1216 default_pinned_apps_field_trial::SetupForUser(user_id, is_current_user_new_);
1218 // Make sure that new data is persisted to Local State.
1219 g_browser_process->local_state()->CommitPendingWrite();
1222 void UserManagerImpl::RegularUserLoggedInAsEphemeral(
1223 const std::string& user_id) {
1224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1225 is_current_user_new_ = true;
1226 is_current_user_ephemeral_regular_user_ = true;
1227 active_user_ = User::CreateRegularUser(user_id);
1228 user_image_manager_->UserLoggedIn(user_id, is_current_user_new_, false);
1229 WallpaperManager::Get()->SetInitialUserWallpaper(user_id, false);
1232 void UserManagerImpl::LocallyManagedUserLoggedIn(
1233 const std::string& user_id) {
1234 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
1236 // Remove the user from the user list.
1237 active_user_ = RemoveRegularOrLocallyManagedUserFromList(user_id);
1238 // If the user was not found on the user list, create a new user.
1239 if (!active_user_) {
1240 is_current_user_new_ = true;
1241 active_user_ = User::CreateLocallyManagedUser(user_id);
1242 // Leaving OAuth token status at the default state = unknown.
1243 WallpaperManager::Get()->SetInitialUserWallpaper(user_id, true);
1245 if (supervised_user_manager_->CheckForFirstRun(user_id)) {
1246 is_current_user_new_ = true;
1247 WallpaperManager::Get()->SetInitialUserWallpaper(user_id, true);
1249 is_current_user_new_ = false;
1253 // Add the user to the front of the user list.
1254 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1256 prefs_users_update->Insert(0, new base::StringValue(user_id));
1257 users_.insert(users_.begin(), active_user_);
1259 // Now that user is in the list, save display name.
1260 if (is_current_user_new_) {
1261 SaveUserDisplayName(active_user_->email(),
1262 active_user_->GetDisplayName());
1265 user_image_manager_->UserLoggedIn(user_id, is_current_user_new_, true);
1266 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1268 // Make sure that new data is persisted to Local State.
1269 g_browser_process->local_state()->CommitPendingWrite();
1272 void UserManagerImpl::PublicAccountUserLoggedIn(User* user) {
1273 is_current_user_new_ = true;
1274 active_user_ = user;
1275 // The UserImageManager chooses a random avatar picture when a user logs in
1276 // for the first time. Tell the UserImageManager that this user is not new to
1277 // prevent the avatar from getting changed.
1278 user_image_manager_->UserLoggedIn(user->email(), false, true);
1279 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1282 void UserManagerImpl::KioskAppLoggedIn(const std::string& username) {
1283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1284 policy::DeviceLocalAccount::Type device_local_account_type;
1285 DCHECK(policy::IsDeviceLocalAccountUser(username,
1286 &device_local_account_type));
1287 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
1288 device_local_account_type);
1290 active_user_ = User::CreateKioskAppUser(username);
1291 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1292 WallpaperManager::Get()->SetInitialUserWallpaper(username, false);
1294 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
1295 // the kiosk_app_id in these objects, removing the need to re-parse the
1296 // device-local account list here to extract the kiosk_app_id.
1297 const std::vector<policy::DeviceLocalAccount> device_local_accounts =
1298 policy::GetDeviceLocalAccounts(cros_settings_);
1299 const policy::DeviceLocalAccount* account = NULL;
1300 for (std::vector<policy::DeviceLocalAccount>::const_iterator
1301 it = device_local_accounts.begin();
1302 it != device_local_accounts.end(); ++it) {
1303 if (it->user_id == username) {
1308 std::string kiosk_app_id;
1310 kiosk_app_id = account->kiosk_app_id;
1312 LOG(ERROR) << "Logged into nonexistent kiosk-app account: " << username;
1316 CommandLine* command_line = CommandLine::ForCurrentProcess();
1317 command_line->AppendSwitch(::switches::kForceAppMode);
1318 command_line->AppendSwitchASCII(::switches::kAppId, kiosk_app_id);
1320 // Disable window animation since kiosk app runs in a single full screen
1321 // window and window animation causes start-up janks.
1322 command_line->AppendSwitch(
1323 views::corewm::switches::kWindowAnimationsDisabled);
1326 void UserManagerImpl::RetailModeUserLoggedIn() {
1327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1328 is_current_user_new_ = true;
1329 active_user_ = User::CreateRetailModeUser();
1330 user_image_manager_->UserLoggedIn(UserManager::kRetailModeUserName,
1331 is_current_user_new_,
1333 WallpaperManager::Get()->SetInitialUserWallpaper(
1334 UserManager::kRetailModeUserName, false);
1337 void UserManagerImpl::NotifyOnLogin() {
1338 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1339 NotifyActiveUserHashChanged(active_user_->username_hash());
1340 NotifyActiveUserChanged(active_user_);
1343 // TODO(nkostylev): Deprecate this notification in favor of
1344 // ActiveUserChanged() observer call.
1345 content::NotificationService::current()->Notify(
1346 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
1347 content::Source<UserManager>(this),
1348 content::Details<const User>(active_user_));
1350 // Owner must be first user in session. DeviceSettingsService can't deal with
1351 // multiple user and will mix up ownership, crbug.com/230018.
1352 if (GetLoggedInUsers().size() == 1) {
1353 // Indicate to DeviceSettingsService that the owner key may have become
1355 DeviceSettingsService::Get()->SetUsername(active_user_->email());
1359 void UserManagerImpl::UpdateOwnership() {
1360 bool is_owner = DeviceSettingsService::Get()->HasPrivateOwnerKey();
1361 VLOG(1) << "Current user " << (is_owner ? "is owner" : "is not owner");
1363 SetCurrentUserIsOwner(is_owner);
1366 void UserManagerImpl::RemoveNonCryptohomeData(const std::string& user_id) {
1367 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id);
1368 user_image_manager_->DeleteUserImage(user_id);
1370 PrefService* prefs = g_browser_process->local_state();
1371 DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
1373 prefs_oauth_update->GetIntegerWithoutPathExpansion(user_id, &oauth_status);
1374 prefs_oauth_update->RemoveWithoutPathExpansion(user_id, NULL);
1376 DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
1377 prefs_display_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1379 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
1380 prefs_display_email_update->RemoveWithoutPathExpansion(user_id, NULL);
1382 supervised_user_manager_->RemoveNonCryptohomeData(user_id);
1384 multi_profile_user_controller_->RemoveCachedValue(user_id);
1387 User* UserManagerImpl::RemoveRegularOrLocallyManagedUserFromList(
1388 const std::string& username) {
1389 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1391 prefs_users_update->Clear();
1393 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1394 const std::string user_email = (*it)->email();
1395 if (user_email == username) {
1397 it = users_.erase(it);
1399 if ((*it)->GetType() == User::USER_TYPE_REGULAR ||
1400 (*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) {
1401 prefs_users_update->Append(new base::StringValue(user_email));
1409 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
1410 PrefService* local_state = g_browser_process->local_state();
1411 const std::string public_account_pending_data_removal =
1412 local_state->GetString(kPublicAccountPendingDataRemoval);
1413 if (public_account_pending_data_removal.empty() ||
1414 (IsUserLoggedIn() &&
1415 public_account_pending_data_removal == GetActiveUser()->email())) {
1419 RemoveNonCryptohomeData(public_account_pending_data_removal);
1420 local_state->ClearPref(kPublicAccountPendingDataRemoval);
1423 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
1424 const std::vector<std::string>& old_public_accounts) {
1425 std::set<std::string> users;
1426 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it)
1427 users.insert((*it)->email());
1429 // If the user is logged into a public account that has been removed from the
1430 // user list, mark the account's data as pending removal after logout.
1431 if (IsLoggedInAsPublicAccount()) {
1432 const std::string active_user_id = GetActiveUser()->email();
1433 if (users.find(active_user_id) == users.end()) {
1434 g_browser_process->local_state()->SetString(
1435 kPublicAccountPendingDataRemoval, active_user_id);
1436 users.insert(active_user_id);
1440 // Remove the data belonging to any other public accounts that are no longer
1441 // found on the user list.
1442 for (std::vector<std::string>::const_iterator
1443 it = old_public_accounts.begin();
1444 it != old_public_accounts.end(); ++it) {
1445 if (users.find(*it) == users.end())
1446 RemoveNonCryptohomeData(*it);
1450 bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
1451 const std::vector<policy::DeviceLocalAccount>& device_local_accounts) {
1452 // Try to remove any public account data marked as pending removal.
1453 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
1455 // Get the current list of public accounts.
1456 std::vector<std::string> old_public_accounts;
1457 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it) {
1458 if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT)
1459 old_public_accounts.push_back((*it)->email());
1462 // Get the new list of public accounts from policy.
1463 std::vector<std::string> new_public_accounts;
1464 for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
1465 device_local_accounts.begin();
1466 it != device_local_accounts.end(); ++it) {
1467 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
1468 // standard login framework: http://crbug.com/234694
1469 if (it->type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
1470 new_public_accounts.push_back(it->user_id);
1473 // If the list of public accounts has not changed, return.
1474 if (new_public_accounts.size() == old_public_accounts.size()) {
1475 bool changed = false;
1476 for (size_t i = 0; i < new_public_accounts.size(); ++i) {
1477 if (new_public_accounts[i] != old_public_accounts[i]) {
1486 // Persist the new list of public accounts in a pref.
1487 ListPrefUpdate prefs_public_accounts_update(g_browser_process->local_state(),
1489 prefs_public_accounts_update->Clear();
1490 for (std::vector<std::string>::const_iterator
1491 it = new_public_accounts.begin();
1492 it != new_public_accounts.end(); ++it) {
1493 prefs_public_accounts_update->AppendString(*it);
1496 // Remove the old public accounts from the user list.
1497 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1498 if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
1499 if (*it != GetLoggedInUser())
1501 it = users_.erase(it);
1507 // Add the new public accounts to the front of the user list.
1508 for (std::vector<std::string>::const_reverse_iterator
1509 it = new_public_accounts.rbegin();
1510 it != new_public_accounts.rend(); ++it) {
1511 if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email())
1512 users_.insert(users_.begin(), GetLoggedInUser());
1514 users_.insert(users_.begin(), User::CreatePublicAccountUser(*it));
1515 UpdatePublicAccountDisplayName(*it);
1518 user_image_manager_->LoadUserImages(
1519 UserList(users_.begin(), users_.begin() + new_public_accounts.size()));
1521 // Remove data belonging to public accounts that are no longer found on the
1523 CleanUpPublicAccountNonCryptohomeData(old_public_accounts);
1528 void UserManagerImpl::UpdatePublicAccountDisplayName(
1529 const std::string& username) {
1530 std::string display_name;
1532 if (device_local_account_policy_service_) {
1533 policy::DeviceLocalAccountPolicyBroker* broker =
1534 device_local_account_policy_service_->GetBrokerForUser(username);
1536 display_name = broker->GetDisplayName();
1539 // Set or clear the display name.
1540 SaveUserDisplayName(username, UTF8ToUTF16(display_name));
1543 UserFlow* UserManagerImpl::GetCurrentUserFlow() const {
1544 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1545 if (!IsUserLoggedIn())
1546 return GetDefaultUserFlow();
1547 return GetUserFlow(GetLoggedInUser()->email());
1550 UserFlow* UserManagerImpl::GetUserFlow(const std::string& user_id) const {
1551 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1552 FlowMap::const_iterator it = specific_flows_.find(user_id);
1553 if (it != specific_flows_.end())
1555 return GetDefaultUserFlow();
1558 void UserManagerImpl::SetUserFlow(const std::string& user_id, UserFlow* flow) {
1559 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1560 ResetUserFlow(user_id);
1561 specific_flows_[user_id] = flow;
1564 void UserManagerImpl::ResetUserFlow(const std::string& user_id) {
1565 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1566 FlowMap::iterator it = specific_flows_.find(user_id);
1567 if (it != specific_flows_.end()) {
1569 specific_flows_.erase(it);
1573 bool UserManagerImpl::GetAppModeChromeClientOAuthInfo(
1574 std::string* chrome_client_id, std::string* chrome_client_secret) {
1575 if (!chrome::IsRunningInForcedAppMode() ||
1576 chrome_client_id_.empty() ||
1577 chrome_client_secret_.empty()) {
1581 *chrome_client_id = chrome_client_id_;
1582 *chrome_client_secret = chrome_client_secret_;
1586 void UserManagerImpl::SetAppModeChromeClientOAuthInfo(
1587 const std::string& chrome_client_id,
1588 const std::string& chrome_client_secret) {
1589 if (!chrome::IsRunningInForcedAppMode())
1592 chrome_client_id_ = chrome_client_id;
1593 chrome_client_secret_ = chrome_client_secret;
1596 bool UserManagerImpl::AreLocallyManagedUsersAllowed() const {
1597 bool locally_managed_users_allowed = false;
1598 cros_settings_->GetBoolean(kAccountsPrefSupervisedUsersEnabled,
1599 &locally_managed_users_allowed);
1600 return ManagedUserService::AreManagedUsersEnabled() &&
1601 (locally_managed_users_allowed ||
1602 !g_browser_process->browser_policy_connector()->IsEnterpriseManaged());
1605 base::FilePath UserManagerImpl::GetUserProfileDir(
1606 const std::string& user_id) const {
1607 // TODO(dpolukhin): Remove Chrome OS specific profile path logic from
1608 // ProfileManager and use only this function to construct profile path.
1609 // TODO(nkostylev): Cleanup profile dir related code paths crbug.com/294233
1610 base::FilePath profile_dir;
1611 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1612 if (command_line.HasSwitch(::switches::kMultiProfiles)) {
1613 const User* user = FindUser(user_id);
1614 if (user && !user->username_hash().empty()) {
1615 profile_dir = base::FilePath(
1616 chrome::kProfileDirPrefix + user->username_hash());
1618 } else if (command_line.HasSwitch(chromeos::switches::kLoginProfile)) {
1619 std::string login_profile_value =
1620 command_line.GetSwitchValueASCII(chromeos::switches::kLoginProfile);
1621 if (login_profile_value == chrome::kLegacyProfileDir ||
1622 login_profile_value == chrome::kTestUserProfileDir) {
1623 profile_dir = base::FilePath(login_profile_value);
1625 profile_dir = base::FilePath(
1626 chrome::kProfileDirPrefix + login_profile_value);
1629 // We should never be logged in with no profile dir unless
1630 // multi-profiles are enabled.
1632 profile_dir = base::FilePath();
1635 ProfileManager* profile_manager = g_browser_process->profile_manager();
1636 profile_dir = profile_manager->user_data_dir().Append(profile_dir);
1641 UserFlow* UserManagerImpl::GetDefaultUserFlow() const {
1642 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1643 if (!default_flow_.get())
1644 default_flow_.reset(new DefaultUserFlow());
1645 return default_flow_.get();
1648 void UserManagerImpl::NotifyUserListChanged() {
1649 content::NotificationService::current()->Notify(
1650 chrome::NOTIFICATION_USER_LIST_CHANGED,
1651 content::Source<UserManager>(this),
1652 content::NotificationService::NoDetails());
1655 void UserManagerImpl::NotifyActiveUserChanged(const User* active_user) {
1656 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1657 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1658 session_state_observer_list_,
1659 ActiveUserChanged(active_user));
1662 void UserManagerImpl::NotifyUserAddedToSession(const User* added_user) {
1663 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1664 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1665 session_state_observer_list_,
1666 UserAddedToSession(added_user));
1669 void UserManagerImpl::NotifyActiveUserHashChanged(const std::string& hash) {
1670 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1671 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1672 session_state_observer_list_,
1673 ActiveUserHashChanged(hash));
1676 void UserManagerImpl::NotifyPendingUserSessionsRestoreFinished() {
1677 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1678 user_sessions_restored_ = true;
1679 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1680 session_state_observer_list_,
1681 PendingUserSessionsRestoreFinished());
1684 void UserManagerImpl::UpdateLoginState() {
1685 if (!LoginState::IsInitialized())
1686 return; // LoginState may not be intialized in tests.
1687 LoginState::LoggedInState logged_in_state;
1688 logged_in_state = active_user_ ? LoginState::LOGGED_IN_ACTIVE
1689 : LoginState::LOGGED_IN_NONE;
1691 LoginState::LoggedInUserType login_user_type;
1692 if (logged_in_state == LoginState::LOGGED_IN_NONE)
1693 login_user_type = LoginState::LOGGED_IN_USER_NONE;
1694 else if (is_current_user_owner_)
1695 login_user_type = LoginState::LOGGED_IN_USER_OWNER;
1696 else if (active_user_->GetType() == User::USER_TYPE_GUEST)
1697 login_user_type = LoginState::LOGGED_IN_USER_GUEST;
1698 else if (active_user_->GetType() == User::USER_TYPE_RETAIL_MODE)
1699 login_user_type = LoginState::LOGGED_IN_USER_RETAIL_MODE;
1700 else if (active_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT)
1701 login_user_type = LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT;
1702 else if (active_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED)
1703 login_user_type = LoginState::LOGGED_IN_USER_LOCALLY_MANAGED;
1704 else if (active_user_->GetType() == User::USER_TYPE_KIOSK_APP)
1705 login_user_type = LoginState::LOGGED_IN_USER_KIOSK_APP;
1707 login_user_type = LoginState::LOGGED_IN_USER_REGULAR;
1709 LoginState::Get()->SetLoggedInState(logged_in_state, login_user_type);
1712 void UserManagerImpl::SetLRUUser(User* user) {
1713 UserList::iterator it = std::find(lru_logged_in_users_.begin(),
1714 lru_logged_in_users_.end(),
1716 if (it != lru_logged_in_users_.end())
1717 lru_logged_in_users_.erase(it);
1718 lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user);
1721 void UserManagerImpl::OnRestoreActiveSessions(
1722 const SessionManagerClient::ActiveSessionsMap& sessions,
1725 LOG(ERROR) << "Could not get list of active user sessions after crash.";
1726 // If we could not get list of active user sessions it is safer to just
1727 // sign out so that we don't get in the inconsistent state.
1728 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
1732 // One profile has been already loaded on browser start.
1733 DCHECK(GetLoggedInUsers().size() == 1);
1734 DCHECK(GetActiveUser());
1735 std::string active_user_id = GetActiveUser()->email();
1737 SessionManagerClient::ActiveSessionsMap::const_iterator it;
1738 for (it = sessions.begin(); it != sessions.end(); ++it) {
1739 if (active_user_id == it->first)
1741 pending_user_sessions_[it->first] = it->second;
1743 RestorePendingUserSessions();
1746 void UserManagerImpl::RestorePendingUserSessions() {
1747 if (pending_user_sessions_.empty()) {
1748 NotifyPendingUserSessionsRestoreFinished();
1752 // Get next user to restore sessions and delete it from list.
1753 SessionManagerClient::ActiveSessionsMap::const_iterator it =
1754 pending_user_sessions_.begin();
1755 std::string user_id = it->first;
1756 std::string user_id_hash = it->second;
1757 DCHECK(!user_id.empty());
1758 DCHECK(!user_id_hash.empty());
1759 pending_user_sessions_.erase(user_id);
1761 // Check that this user is not logged in yet.
1762 UserList logged_in_users = GetLoggedInUsers();
1763 bool user_already_logged_in = false;
1764 for (UserList::const_iterator it = logged_in_users.begin();
1765 it != logged_in_users.end(); ++it) {
1766 const User* user = (*it);
1767 if (user->email() == user_id) {
1768 user_already_logged_in = true;
1772 DCHECK(!user_already_logged_in);
1774 if (!user_already_logged_in) {
1775 // Will call OnProfilePrepared() once profile has been loaded.
1776 LoginUtils::Get()->PrepareProfile(UserContext(user_id,
1777 std::string(), // password
1778 std::string(), // auth_code
1780 false), // using_oauth
1781 std::string(), // display_email
1782 false, // has_cookies
1783 true, // has_active_session
1786 RestorePendingUserSessions();
1790 void UserManagerImpl::SendRegularUserLoginMetrics(const std::string& user_id) {
1791 // If this isn't the first time Chrome was run after the system booted,
1792 // assume that Chrome was restarted because a previous session ended.
1793 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1794 switches::kFirstExecAfterBoot)) {
1795 const std::string last_email =
1796 g_browser_process->local_state()->GetString(kLastLoggedInRegularUser);
1797 const base::TimeDelta time_to_login =
1798 base::TimeTicks::Now() - manager_creation_time_;
1799 if (!last_email.empty() && user_id != last_email &&
1800 time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) {
1801 UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay",
1802 time_to_login.InSeconds(), 0, kLogoutToLoginDelayMaxSec, 50);
1807 void UserManagerImpl::OnUserNotAllowed() {
1808 LOG(ERROR) << "Shutdown session because a user is not allowed to be in the "
1810 chrome::AttemptUserExit();
1813 } // namespace chromeos