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.
4
5 #include "chrome/browser/chromeos/login/user_manager_impl.h"
6
7 #include <cstddef>
8 #include <set>
9
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/base/locale_util.h"
31 #include "chrome/browser/chromeos/login/auth_sync_observer.h"
32 #include "chrome/browser/chromeos/login/auth_sync_observer_factory.h"
33 #include "chrome/browser/chromeos/login/login_display.h"
34 #include "chrome/browser/chromeos/login/login_utils.h"
35 #include "chrome/browser/chromeos/login/multi_profile_first_run_notification.h"
36 #include "chrome/browser/chromeos/login/multi_profile_user_controller.h"
37 #include "chrome/browser/chromeos/login/remove_user_delegate.h"
38 #include "chrome/browser/chromeos/login/supervised_user_manager_impl.h"
39 #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
40 #include "chrome/browser/chromeos/login/wizard_controller.h"
41 #include "chrome/browser/chromeos/policy/device_local_account.h"
42 #include "chrome/browser/chromeos/profiles/profile_helper.h"
43 #include "chrome/browser/chromeos/session_length_limiter.h"
44 #include "chrome/browser/lifetime/application_lifetime.h"
45 #include "chrome/browser/policy/browser_policy_connector.h"
46 #include "chrome/browser/profiles/profile.h"
47 #include "chrome/browser/profiles/profile_manager.h"
48 #include "chrome/browser/sync/profile_sync_service.h"
49 #include "chrome/browser/sync/profile_sync_service_factory.h"
50 #include "chrome/common/chrome_constants.h"
51 #include "chrome/common/chrome_switches.h"
52 #include "chrome/common/pref_names.h"
53 #include "chromeos/chromeos_switches.h"
54 #include "chromeos/cryptohome/async_method_caller.h"
55 #include "chromeos/dbus/dbus_thread_manager.h"
56 #include "chromeos/login/login_state.h"
57 #include "chromeos/settings/cros_settings_names.h"
58 #include "content/public/browser/browser_thread.h"
59 #include "content/public/browser/notification_service.h"
60 #include "google_apis/gaia/gaia_auth_util.h"
61 #include "google_apis/gaia/google_service_auth_error.h"
62 #include "policy/policy_constants.h"
63 #include "ui/base/l10n/l10n_util.h"
64 #include "ui/views/corewm/corewm_switches.h"
65
66 using content::BrowserThread;
67
68 namespace chromeos {
69 namespace {
70
71 // A vector pref of the the regular users known on this device, arranged in LRU
72 // order.
73 const char kRegularUsers[] = "LoggedInUsers";
74
75 // A vector pref of the public accounts defined on this device.
76 const char kPublicAccounts[] = "PublicAccounts";
77
78 // A string pref that gets set when a public account is removed but a user is
79 // currently logged into that account, requiring the account's data to be
80 // removed after logout.
81 const char kPublicAccountPendingDataRemoval[] =
82 "PublicAccountPendingDataRemoval";
83
84 // A dictionary that maps usernames to the displayed name.
85 const char kUserDisplayName[] = "UserDisplayName";
86
87 // A dictionary that maps usernames to the user's given name.
88 const char kUserGivenName[] = "UserGivenName";
89
90 // A dictionary that maps usernames to the displayed (non-canonical) emails.
91 const char kUserDisplayEmail[] = "UserDisplayEmail";
92
93 // A dictionary that maps usernames to OAuth token presence flag.
94 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus";
95
96 // A string pref containing the ID of the last user who logged in if it was
97 // a regular user or an empty string if it was another type of user (guest,
98 // kiosk, public account, etc.).
99 const char kLastLoggedInRegularUser[] = "LastLoggedInRegularUser";
100
101 // Upper bound for a histogram metric reporting the amount of time between
102 // one regular user logging out and a different regular user logging in.
103 const int kLogoutToLoginDelayMaxSec = 1800;
104
105 // Callback that is called after user removal is complete.
OnRemoveUserComplete(const std::string & user_email,bool success,cryptohome::MountError return_code)106 void OnRemoveUserComplete(const std::string& user_email,
107 bool success,
108 cryptohome::MountError return_code) {
109 // Log the error, but there's not much we can do.
110 if (!success) {
111 LOG(ERROR) << "Removal of cryptohome for " << user_email
112 << " failed, return code: " << return_code;
113 }
114 }
115
116 // Helper function that copies users from |users_list| to |users_vector| and
117 // |users_set|. Duplicates and users already present in |existing_users| are
118 // skipped.
ParseUserList(const ListValue & users_list,const std::set<std::string> & existing_users,std::vector<std::string> * users_vector,std::set<std::string> * users_set)119 void ParseUserList(const ListValue& users_list,
120 const std::set<std::string>& existing_users,
121 std::vector<std::string>* users_vector,
122 std::set<std::string>* users_set) {
123 users_vector->clear();
124 users_set->clear();
125 for (size_t i = 0; i < users_list.GetSize(); ++i) {
126 std::string email;
127 if (!users_list.GetString(i, &email) || email.empty()) {
128 LOG(ERROR) << "Corrupt entry in user list at index " << i << ".";
129 continue;
130 }
131 if (existing_users.find(email) != existing_users.end() ||
132 !users_set->insert(email).second) {
133 LOG(ERROR) << "Duplicate user: " << email;
134 continue;
135 }
136 users_vector->push_back(email);
137 }
138 }
139
140 class UserHashMatcher {
141 public:
UserHashMatcher(const std::string & h)142 explicit UserHashMatcher(const std::string& h) : username_hash(h) {}
operator ()(const User * user) const143 bool operator()(const User* user) const {
144 return user->username_hash() == username_hash;
145 }
146
147 private:
148 const std::string& username_hash;
149 };
150
151 // Runs on SequencedWorkerPool thread. Passes resolved locale to
152 // |on_resolve_callback| on UI thread.
ResolveLocale(const std::string & raw_locale,base::Callback<void (const std::string &)> on_resolve_callback)153 void ResolveLocale(
154 const std::string& raw_locale,
155 base::Callback<void(const std::string&)> on_resolve_callback) {
156 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
157 std::string resolved_locale;
158 // Ignore result
159 l10n_util::CheckAndResolveLocale(raw_locale, &resolved_locale);
160 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
161 base::Bind(on_resolve_callback, resolved_locale));
162 }
163
164 } // namespace
165
166 // static
RegisterPrefs(PrefRegistrySimple * registry)167 void UserManager::RegisterPrefs(PrefRegistrySimple* registry) {
168 registry->RegisterListPref(kRegularUsers);
169 registry->RegisterListPref(kPublicAccounts);
170 registry->RegisterStringPref(kPublicAccountPendingDataRemoval, "");
171 registry->RegisterStringPref(kLastLoggedInRegularUser, "");
172 registry->RegisterDictionaryPref(kUserOAuthTokenStatus);
173 registry->RegisterDictionaryPref(kUserDisplayName);
174 registry->RegisterDictionaryPref(kUserGivenName);
175 registry->RegisterDictionaryPref(kUserDisplayEmail);
176 SupervisedUserManager::RegisterPrefs(registry);
177 SessionLengthLimiter::RegisterPrefs(registry);
178 }
179
UserManagerImpl()180 UserManagerImpl::UserManagerImpl()
181 : cros_settings_(CrosSettings::Get()),
182 device_local_account_policy_service_(NULL),
183 user_loading_stage_(STAGE_NOT_LOADED),
184 active_user_(NULL),
185 primary_user_(NULL),
186 session_started_(false),
187 user_sessions_restored_(false),
188 is_current_user_owner_(false),
189 is_current_user_new_(false),
190 is_current_user_ephemeral_regular_user_(false),
191 ephemeral_users_enabled_(false),
192 user_image_manager_(new UserImageManagerImpl(cros_settings_, this)),
193 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
194 manager_creation_time_(base::TimeTicks::Now()),
195 multi_profile_first_run_notification_(
196 new MultiProfileFirstRunNotification) {
197 // UserManager instance should be used only on UI thread.
198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
199 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
200 content::NotificationService::AllSources());
201 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
202 content::NotificationService::AllSources());
203 registrar_.Add(this,
204 chrome::NOTIFICATION_PROFILE_CREATED,
205 content::NotificationService::AllSources());
206 RetrieveTrustedDevicePolicies();
207 local_accounts_subscription_ = cros_settings_->AddSettingsObserver(
208 kAccountsPrefDeviceLocalAccounts,
209 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
210 base::Unretained(this)));
211 supervised_users_subscription_ = cros_settings_->AddSettingsObserver(
212 kAccountsPrefSupervisedUsersEnabled,
213 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
214 base::Unretained(this)));
215 multi_profile_user_controller_.reset(new MultiProfileUserController(
216 this, g_browser_process->local_state()));
217 UpdateLoginState();
218 }
219
~UserManagerImpl()220 UserManagerImpl::~UserManagerImpl() {
221 // Can't use STLDeleteElements because of the private destructor of User.
222 for (UserList::iterator it = users_.begin(); it != users_.end();
223 it = users_.erase(it)) {
224 if (active_user_ == *it)
225 active_user_ = NULL;
226 delete *it;
227 }
228 // These are pointers to the same User instances that were in users_ list.
229 logged_in_users_.clear();
230 lru_logged_in_users_.clear();
231
232 delete active_user_;
233 }
234
Shutdown()235 void UserManagerImpl::Shutdown() {
236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
237 local_accounts_subscription_.reset();
238 supervised_users_subscription_.reset();
239 // Stop the session length limiter.
240 session_length_limiter_.reset();
241
242 if (device_local_account_policy_service_)
243 device_local_account_policy_service_->RemoveObserver(this);
244
245 user_image_manager_->Shutdown();
246 multi_profile_user_controller_.reset();
247 }
248
GetUserImageManager()249 UserImageManager* UserManagerImpl::GetUserImageManager() {
250 return user_image_manager_.get();
251 }
252
GetSupervisedUserManager()253 SupervisedUserManager* UserManagerImpl::GetSupervisedUserManager() {
254 return supervised_user_manager_.get();
255 }
256
GetUsers() const257 const UserList& UserManagerImpl::GetUsers() const {
258 const_cast<UserManagerImpl*>(this)->EnsureUsersLoaded();
259 return users_;
260 }
261
GetUsersAdmittedForMultiProfile() const262 UserList UserManagerImpl::GetUsersAdmittedForMultiProfile() const {
263 if (!UserManager::IsMultipleProfilesAllowed())
264 return UserList();
265
266 UserList result;
267 const UserList& users = GetUsers();
268 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
269 if ((*it)->GetType() == User::USER_TYPE_REGULAR &&
270 !(*it)->is_logged_in() &&
271 multi_profile_user_controller_->IsUserAllowedInSession(
272 (*it)->email())) {
273 result.push_back(*it);
274 }
275 }
276 return result;
277 }
278
GetLoggedInUsers() const279 const UserList& UserManagerImpl::GetLoggedInUsers() const {
280 return logged_in_users_;
281 }
282
GetLRULoggedInUsers()283 const UserList& UserManagerImpl::GetLRULoggedInUsers() {
284 // If there is no user logged in, we return the active user as the only one.
285 if (lru_logged_in_users_.empty() && active_user_) {
286 temp_single_logged_in_users_.clear();
287 temp_single_logged_in_users_.insert(temp_single_logged_in_users_.begin(),
288 active_user_);
289 return temp_single_logged_in_users_;
290 }
291 return lru_logged_in_users_;
292 }
293
GetUnlockUsers() const294 UserList UserManagerImpl::GetUnlockUsers() const {
295 UserList unlock_users;
296 if (primary_user_)
297 unlock_users.push_back(primary_user_);
298 return unlock_users;
299 }
300
GetOwnerEmail()301 const std::string& UserManagerImpl::GetOwnerEmail() {
302 return owner_email_;
303 }
304
UserLoggedIn(const std::string & user_id,const std::string & username_hash,bool browser_restart)305 void UserManagerImpl::UserLoggedIn(const std::string& user_id,
306 const std::string& username_hash,
307 bool browser_restart) {
308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
309
310 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles))
311 DCHECK(!IsUserLoggedIn());
312
313 User* user = FindUserInListAndModify(user_id);
314 if (active_user_ && user) {
315 user->set_is_logged_in(true);
316 user->set_username_hash(username_hash);
317 logged_in_users_.push_back(user);
318 lru_logged_in_users_.push_back(user);
319 // Reset the new user flag if the user already exists.
320 is_current_user_new_ = false;
321 // Set active user wallpaper back.
322 WallpaperManager::Get()->SetUserWallpaper(active_user_->email());
323 NotifyUserAddedToSession(user);
324 return;
325 }
326
327 policy::DeviceLocalAccount::Type device_local_account_type;
328 if (user_id == UserManager::kGuestUserName) {
329 GuestUserLoggedIn();
330 } else if (user_id == UserManager::kRetailModeUserName) {
331 RetailModeUserLoggedIn();
332 } else if (policy::IsDeviceLocalAccountUser(user_id,
333 &device_local_account_type) &&
334 device_local_account_type ==
335 policy::DeviceLocalAccount::TYPE_KIOSK_APP) {
336 KioskAppLoggedIn(user_id);
337 } else {
338 EnsureUsersLoaded();
339
340 if (user && user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
341 PublicAccountUserLoggedIn(user);
342 } else if ((user && user->GetType() == User::USER_TYPE_LOCALLY_MANAGED) ||
343 (!user && gaia::ExtractDomainName(user_id) ==
344 UserManager::kLocallyManagedUserDomain)) {
345 LocallyManagedUserLoggedIn(user_id);
346 } else if (browser_restart && user_id == g_browser_process->local_state()->
347 GetString(kPublicAccountPendingDataRemoval)) {
348 PublicAccountUserLoggedIn(User::CreatePublicAccountUser(user_id));
349 } else if (user_id != owner_email_ && !user &&
350 (AreEphemeralUsersEnabled() || browser_restart)) {
351 RegularUserLoggedInAsEphemeral(user_id);
352 } else {
353 RegularUserLoggedIn(user_id);
354 }
355
356 // Initialize the session length limiter and start it only if
357 // session limit is defined by the policy.
358 session_length_limiter_.reset(new SessionLengthLimiter(NULL,
359 browser_restart));
360 }
361 DCHECK(active_user_);
362 active_user_->set_is_logged_in(true);
363 active_user_->set_is_active(true);
364 active_user_->set_username_hash(username_hash);
365
366 // Place user who just signed in to the top of the logged in users.
367 logged_in_users_.insert(logged_in_users_.begin(), active_user_);
368 SetLRUUser(active_user_);
369
370 if (!primary_user_) {
371 primary_user_ = active_user_;
372 if (primary_user_->GetType() == User::USER_TYPE_REGULAR)
373 SendRegularUserLoginMetrics(user_id);
374 }
375
376 UMA_HISTOGRAM_ENUMERATION("UserManager.LoginUserType",
377 active_user_->GetType(), User::NUM_USER_TYPES);
378
379 g_browser_process->local_state()->SetString(kLastLoggedInRegularUser,
380 (active_user_->GetType() == User::USER_TYPE_REGULAR) ? user_id : "");
381
382 NotifyOnLogin();
383 }
384
SwitchActiveUser(const std::string & user_id)385 void UserManagerImpl::SwitchActiveUser(const std::string& user_id) {
386 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles))
387 return;
388
389 User* user = FindUserAndModify(user_id);
390 if (!user) {
391 NOTREACHED() << "Switching to a non-existing user";
392 return;
393 }
394 if (user == active_user_) {
395 NOTREACHED() << "Switching to a user who is already active";
396 return;
397 }
398 if (!user->is_logged_in()) {
399 NOTREACHED() << "Switching to a user that is not logged in";
400 return;
401 }
402 if (user->GetType() != User::USER_TYPE_REGULAR) {
403 NOTREACHED() << "Switching to a non-regular user";
404 return;
405 }
406 if (user->username_hash().empty()) {
407 NOTREACHED() << "Switching to a user that doesn't have username_hash set";
408 return;
409 }
410
411 DCHECK(active_user_);
412 active_user_->set_is_active(false);
413 user->set_is_active(true);
414 active_user_ = user;
415
416 // Move the user to the front.
417 SetLRUUser(active_user_);
418
419 NotifyActiveUserHashChanged(active_user_->username_hash());
420 NotifyActiveUserChanged(active_user_);
421 }
422
RestoreActiveSessions()423 void UserManagerImpl::RestoreActiveSessions() {
424 DBusThreadManager::Get()->GetSessionManagerClient()->RetrieveActiveSessions(
425 base::Bind(&UserManagerImpl::OnRestoreActiveSessions,
426 base::Unretained(this)));
427 }
428
SessionStarted()429 void UserManagerImpl::SessionStarted() {
430 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
431 session_started_ = true;
432 UpdateLoginState();
433 content::NotificationService::current()->Notify(
434 chrome::NOTIFICATION_SESSION_STARTED,
435 content::Source<UserManager>(this),
436 content::Details<const User>(active_user_));
437 if (is_current_user_new_) {
438 // Make sure that the new user's data is persisted to Local State.
439 g_browser_process->local_state()->CommitPendingWrite();
440 }
441 }
442
RemoveUser(const std::string & user_id,RemoveUserDelegate * delegate)443 void UserManagerImpl::RemoveUser(const std::string& user_id,
444 RemoveUserDelegate* delegate) {
445 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
446
447 const User* user = FindUser(user_id);
448 if (!user || (user->GetType() != User::USER_TYPE_REGULAR &&
449 user->GetType() != User::USER_TYPE_LOCALLY_MANAGED))
450 return;
451
452 // Sanity check: we must not remove single user. This check may seem
453 // redundant at a first sight because this single user must be an owner and
454 // we perform special check later in order not to remove an owner. However
455 // due to non-instant nature of ownership assignment this later check may
456 // sometimes fail. See http://crosbug.com/12723
457 if (users_.size() < 2)
458 return;
459
460 // Sanity check: do not allow any of the the logged in users to be removed.
461 for (UserList::const_iterator it = logged_in_users_.begin();
462 it != logged_in_users_.end(); ++it) {
463 if ((*it)->email() == user_id)
464 return;
465 }
466
467 RemoveUserInternal(user_id, delegate);
468 }
469
RemoveUserInternal(const std::string & user_email,RemoveUserDelegate * delegate)470 void UserManagerImpl::RemoveUserInternal(const std::string& user_email,
471 RemoveUserDelegate* delegate) {
472 CrosSettings* cros_settings = CrosSettings::Get();
473
474 // Ensure the value of owner email has been fetched.
475 if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues(
476 base::Bind(&UserManagerImpl::RemoveUserInternal,
477 base::Unretained(this),
478 user_email, delegate))) {
479 // Value of owner email is not fetched yet. RemoveUserInternal will be
480 // called again after fetch completion.
481 return;
482 }
483 std::string owner;
484 cros_settings->GetString(kDeviceOwner, &owner);
485 if (user_email == owner) {
486 // Owner is not allowed to be removed from the device.
487 return;
488 }
489 RemoveNonOwnerUserInternal(user_email, delegate);
490 }
491
RemoveNonOwnerUserInternal(const std::string & user_email,RemoveUserDelegate * delegate)492 void UserManagerImpl::RemoveNonOwnerUserInternal(const std::string& user_email,
493 RemoveUserDelegate* delegate) {
494 if (delegate)
495 delegate->OnBeforeUserRemoved(user_email);
496 RemoveUserFromList(user_email);
497 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
498 user_email, base::Bind(&OnRemoveUserComplete, user_email));
499
500 if (delegate)
501 delegate->OnUserRemoved(user_email);
502 }
503
RemoveUserFromList(const std::string & user_id)504 void UserManagerImpl::RemoveUserFromList(const std::string& user_id) {
505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
506 RemoveNonCryptohomeData(user_id);
507 if (user_loading_stage_ == STAGE_LOADED) {
508 User* user = RemoveRegularOrLocallyManagedUserFromList(user_id);
509 delete user;
510 } else if (user_loading_stage_ == STAGE_LOADING) {
511 DCHECK(gaia::ExtractDomainName(user_id) ==
512 UserManager::kLocallyManagedUserDomain);
513 // Special case, removing partially-constructed supervised user during user
514 // list loading.
515 ListPrefUpdate users_update(g_browser_process->local_state(),
516 kRegularUsers);
517 users_update->Remove(base::StringValue(user_id), NULL);
518 } else {
519 NOTREACHED() << "Users are not loaded yet.";
520 return;
521 }
522 // Make sure that new data is persisted to Local State.
523 g_browser_process->local_state()->CommitPendingWrite();
524 }
525
IsKnownUser(const std::string & user_id) const526 bool UserManagerImpl::IsKnownUser(const std::string& user_id) const {
527 return FindUser(user_id) != NULL;
528 }
529
FindUser(const std::string & user_id) const530 const User* UserManagerImpl::FindUser(const std::string& user_id) const {
531 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
532 if (active_user_ && active_user_->email() == user_id)
533 return active_user_;
534 return FindUserInList(user_id);
535 }
536
FindUserAndModify(const std::string & user_id)537 User* UserManagerImpl::FindUserAndModify(const std::string& user_id) {
538 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
539 if (active_user_ && active_user_->email() == user_id)
540 return active_user_;
541 return FindUserInListAndModify(user_id);
542 }
543
GetLoggedInUser() const544 const User* UserManagerImpl::GetLoggedInUser() const {
545 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
546 return active_user_;
547 }
548
GetLoggedInUser()549 User* UserManagerImpl::GetLoggedInUser() {
550 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
551 return active_user_;
552 }
553
GetActiveUser() const554 const User* UserManagerImpl::GetActiveUser() const {
555 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
556 return active_user_;
557 }
558
GetActiveUser()559 User* UserManagerImpl::GetActiveUser() {
560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
561 return active_user_;
562 }
563
GetPrimaryUser() const564 const User* UserManagerImpl::GetPrimaryUser() const {
565 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
566 return primary_user_;
567 }
568
GetUserByProfile(Profile * profile) const569 User* UserManagerImpl::GetUserByProfile(Profile* profile) const {
570 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
571 if (ProfileHelper::IsSigninProfile(profile))
572 return NULL;
573
574 if (IsMultipleProfilesAllowed()) {
575 const std::string username_hash =
576 ProfileHelper::GetUserIdHashFromProfile(profile);
577 const UserList& users = GetUsers();
578 const UserList::const_iterator pos = std::find_if(
579 users.begin(), users.end(), UserHashMatcher(username_hash));
580 if (pos != users.end())
581 return *pos;
582
583 // Many tests do not have their users registered with UserManager and
584 // runs here. If |active_user_| matches |profile|, returns it.
585 return active_user_ &&
586 ProfileHelper::GetProfilePathByUserIdHash(
587 active_user_->username_hash()) == profile->GetPath()
588 ? active_user_
589 : NULL;
590 }
591 return active_user_;
592 }
593
GetProfileByUser(const User * user) const594 Profile* UserManagerImpl::GetProfileByUser(const User* user) const {
595 Profile* profile = NULL;
596 if (IsMultipleProfilesAllowed() && user->is_profile_created())
597 profile = ProfileHelper::GetProfileByUserIdHash(user->username_hash());
598 else
599 profile = g_browser_process->profile_manager()->GetDefaultProfile();
600
601 // GetDefaultProfile() or GetProfileByUserIdHash() returns a new instance of
602 // ProfileImpl(), but actually its OffTheRecordProfile() should be used.
603 if (profile && IsLoggedInAsGuest())
604 profile = profile->GetOffTheRecordProfile();
605 return profile;
606 }
607
SaveUserOAuthStatus(const std::string & user_id,User::OAuthTokenStatus oauth_token_status)608 void UserManagerImpl::SaveUserOAuthStatus(
609 const std::string& user_id,
610 User::OAuthTokenStatus oauth_token_status) {
611 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
612
613 DVLOG(1) << "Saving user OAuth token status in Local State";
614 User* user = FindUserAndModify(user_id);
615 if (user)
616 user->set_oauth_token_status(oauth_token_status);
617
618 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(oauth_token_status);
619
620 // Do not update local store if data stored or cached outside the user's
621 // cryptohome is to be treated as ephemeral.
622 if (IsUserNonCryptohomeDataEphemeral(user_id))
623 return;
624
625 PrefService* local_state = g_browser_process->local_state();
626
627 DictionaryPrefUpdate oauth_status_update(local_state, kUserOAuthTokenStatus);
628 oauth_status_update->SetWithoutPathExpansion(user_id,
629 new base::FundamentalValue(static_cast<int>(oauth_token_status)));
630 }
631
LoadUserOAuthStatus(const std::string & user_id) const632 User::OAuthTokenStatus UserManagerImpl::LoadUserOAuthStatus(
633 const std::string& user_id) const {
634 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
635
636 PrefService* local_state = g_browser_process->local_state();
637 const DictionaryValue* prefs_oauth_status =
638 local_state->GetDictionary(kUserOAuthTokenStatus);
639 int oauth_token_status = User::OAUTH_TOKEN_STATUS_UNKNOWN;
640 if (prefs_oauth_status &&
641 prefs_oauth_status->GetIntegerWithoutPathExpansion(
642 user_id, &oauth_token_status)) {
643 User::OAuthTokenStatus result =
644 static_cast<User::OAuthTokenStatus>(oauth_token_status);
645 if (result == User::OAUTH2_TOKEN_STATUS_INVALID)
646 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(result);
647 return result;
648 }
649 return User::OAUTH_TOKEN_STATUS_UNKNOWN;
650 }
651
SaveUserDisplayName(const std::string & user_id,const base::string16 & display_name)652 void UserManagerImpl::SaveUserDisplayName(const std::string& user_id,
653 const base::string16& display_name) {
654 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
655
656 if (User* user = FindUserAndModify(user_id)) {
657 user->set_display_name(display_name);
658
659 // Do not update local store if data stored or cached outside the user's
660 // cryptohome is to be treated as ephemeral.
661 if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
662 PrefService* local_state = g_browser_process->local_state();
663
664 DictionaryPrefUpdate display_name_update(local_state, kUserDisplayName);
665 display_name_update->SetWithoutPathExpansion(
666 user_id,
667 new base::StringValue(display_name));
668
669 supervised_user_manager_->UpdateManagerName(user_id, display_name);
670 }
671 }
672 }
673
GetUserDisplayName(const std::string & user_id) const674 base::string16 UserManagerImpl::GetUserDisplayName(
675 const std::string& user_id) const {
676 const User* user = FindUser(user_id);
677 return user ? user->display_name() : base::string16();
678 }
679
SaveUserDisplayEmail(const std::string & user_id,const std::string & display_email)680 void UserManagerImpl::SaveUserDisplayEmail(const std::string& user_id,
681 const std::string& display_email) {
682 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
683
684 User* user = FindUserAndModify(user_id);
685 if (!user)
686 return; // Ignore if there is no such user.
687
688 user->set_display_email(display_email);
689
690 // Do not update local store if data stored or cached outside the user's
691 // cryptohome is to be treated as ephemeral.
692 if (IsUserNonCryptohomeDataEphemeral(user_id))
693 return;
694
695 PrefService* local_state = g_browser_process->local_state();
696
697 DictionaryPrefUpdate display_email_update(local_state, kUserDisplayEmail);
698 display_email_update->SetWithoutPathExpansion(
699 user_id,
700 new base::StringValue(display_email));
701 }
702
GetUserDisplayEmail(const std::string & user_id) const703 std::string UserManagerImpl::GetUserDisplayEmail(
704 const std::string& user_id) const {
705 const User* user = FindUser(user_id);
706 return user ? user->display_email() : user_id;
707 }
708
UpdateUserAccountData(const std::string & user_id,const UserAccountData & account_data)709 void UserManagerImpl::UpdateUserAccountData(
710 const std::string& user_id,
711 const UserAccountData& account_data) {
712 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
713
714 SaveUserDisplayName(user_id, account_data.display_name());
715
716 if (User* user = FindUserAndModify(user_id)) {
717 base::string16 given_name = account_data.given_name();
718 user->set_given_name(given_name);
719 if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
720 PrefService* local_state = g_browser_process->local_state();
721
722 DictionaryPrefUpdate given_name_update(local_state, kUserGivenName);
723 given_name_update->SetWithoutPathExpansion(
724 user_id,
725 new base::StringValue(given_name));
726 }
727 }
728
729 UpdateUserAccountLocale(user_id, account_data.locale());
730 }
731
732 // TODO(alemate): http://crbug.com/288941 : Respect preferred language list in
733 // the Google user profile.
734 //
735 // Returns true if callback will be called.
RespectLocalePreference(Profile * profile,const User * user,scoped_ptr<locale_util::SwitchLanguageCallback> callback) const736 bool UserManagerImpl::RespectLocalePreference(
737 Profile* profile,
738 const User* user,
739 scoped_ptr<locale_util::SwitchLanguageCallback> callback) const {
740 if (g_browser_process == NULL)
741 return false;
742 if ((user == NULL) || (user != GetPrimaryUser()) ||
743 (!user->is_profile_created()))
744 return false;
745
746 // In case of Multi Profile mode we don't apply profile locale because it is
747 // unsafe.
748 if (GetLoggedInUsers().size() != 1)
749 return false;
750 const PrefService* prefs = profile->GetPrefs();
751 if (prefs == NULL)
752 return false;
753
754 std::string pref_locale;
755 const std::string pref_app_locale =
756 prefs->GetString(prefs::kApplicationLocale);
757 const std::string pref_bkup_locale =
758 prefs->GetString(prefs::kApplicationLocaleBackup);
759
760 pref_locale = pref_app_locale;
761 if (pref_locale.empty())
762 pref_locale = pref_bkup_locale;
763
764 const std::string* account_locale = NULL;
765 if (pref_locale.empty() && user->has_gaia_account()) {
766 if (user->GetAccountLocale() == NULL)
767 return false; // wait until Account profile is loaded.
768 account_locale = user->GetAccountLocale();
769 pref_locale = *account_locale;
770 }
771 const std::string global_app_locale =
772 g_browser_process->GetApplicationLocale();
773 if (pref_locale.empty())
774 pref_locale = global_app_locale;
775 DCHECK(!pref_locale.empty());
776 LOG(WARNING) << "RespectLocalePreference: "
777 << "app_locale='" << pref_app_locale << "', "
778 << "bkup_locale='" << pref_bkup_locale << "', "
779 << (account_locale != NULL
780 ? (std::string("account_locale='") + (*account_locale) +
781 "'. ")
782 : (std::string("account_locale - unused. ")))
783 << " Selected '" << pref_locale << "'";
784 profile->ChangeAppLocale(pref_locale, Profile::APP_LOCALE_CHANGED_VIA_LOGIN);
785 // Here we don't enable keyboard layouts. Input methods are set up when
786 // the user first logs in. Then the user may customize the input methods.
787 // Hence changing input methods here, just because the user's UI language
788 // is different from the login screen UI language, is not desirable. Note
789 // that input method preferences are synced, so users can use their
790 // farovite input methods as soon as the preferences are synced.
791 locale_util::SwitchLanguage(pref_locale, false, callback.Pass());
792
793 return true;
794 }
795
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)796 void UserManagerImpl::Observe(int type,
797 const content::NotificationSource& source,
798 const content::NotificationDetails& details) {
799 switch (type) {
800 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED:
801 if (!device_local_account_policy_service_) {
802 device_local_account_policy_service_ =
803 g_browser_process->browser_policy_connector()->
804 GetDeviceLocalAccountPolicyService();
805 if (device_local_account_policy_service_)
806 device_local_account_policy_service_->AddObserver(this);
807 }
808 RetrieveTrustedDevicePolicies();
809 UpdateOwnership();
810 break;
811 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED:
812 if (IsUserLoggedIn() &&
813 !IsLoggedInAsGuest() &&
814 !IsLoggedInAsKioskApp()) {
815 Profile* profile = content::Details<Profile>(details).ptr();
816 if (!profile->IsOffTheRecord()) {
817 AuthSyncObserver* sync_observer =
818 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile);
819 sync_observer->StartObserving();
820 multi_profile_user_controller_->StartObserving(profile);
821 multi_profile_first_run_notification_->UserProfilePrepared(profile);
822 }
823 }
824 break;
825 case chrome::NOTIFICATION_PROFILE_CREATED: {
826 Profile* profile = content::Source<Profile>(source).ptr();
827 User* user = GetUserByProfile(profile);
828 if (user != NULL)
829 user->set_profile_is_created();
830
831 break;
832 }
833 default:
834 NOTREACHED();
835 }
836 }
837
OnPolicyUpdated(const std::string & user_id)838 void UserManagerImpl::OnPolicyUpdated(const std::string& user_id) {
839 UpdatePublicAccountDisplayName(user_id);
840 NotifyUserListChanged();
841 }
842
OnDeviceLocalAccountsChanged()843 void UserManagerImpl::OnDeviceLocalAccountsChanged() {
844 // No action needed here, changes to the list of device-local accounts get
845 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
846 }
847
IsCurrentUserOwner() const848 bool UserManagerImpl::IsCurrentUserOwner() const {
849 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
850 base::AutoLock lk(is_current_user_owner_lock_);
851 return is_current_user_owner_;
852 }
853
SetCurrentUserIsOwner(bool is_current_user_owner)854 void UserManagerImpl::SetCurrentUserIsOwner(bool is_current_user_owner) {
855 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
856 {
857 base::AutoLock lk(is_current_user_owner_lock_);
858 is_current_user_owner_ = is_current_user_owner;
859 }
860 UpdateLoginState();
861 }
862
IsCurrentUserNew() const863 bool UserManagerImpl::IsCurrentUserNew() const {
864 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
865 return is_current_user_new_;
866 }
867
IsCurrentUserNonCryptohomeDataEphemeral() const868 bool UserManagerImpl::IsCurrentUserNonCryptohomeDataEphemeral() const {
869 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
870 return IsUserLoggedIn() &&
871 IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email());
872 }
873
CanCurrentUserLock() const874 bool UserManagerImpl::CanCurrentUserLock() const {
875 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
876 return IsUserLoggedIn() && active_user_->can_lock();
877 }
878
IsUserLoggedIn() const879 bool UserManagerImpl::IsUserLoggedIn() const {
880 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
881 return active_user_;
882 }
883
IsLoggedInAsRegularUser() const884 bool UserManagerImpl::IsLoggedInAsRegularUser() const {
885 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
886 return IsUserLoggedIn() &&
887 active_user_->GetType() == User::USER_TYPE_REGULAR;
888 }
889
IsLoggedInAsDemoUser() const890 bool UserManagerImpl::IsLoggedInAsDemoUser() const {
891 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
892 return IsUserLoggedIn() &&
893 active_user_->GetType() == User::USER_TYPE_RETAIL_MODE;
894 }
895
IsLoggedInAsPublicAccount() const896 bool UserManagerImpl::IsLoggedInAsPublicAccount() const {
897 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
898 return IsUserLoggedIn() &&
899 active_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
900 }
901
IsLoggedInAsGuest() const902 bool UserManagerImpl::IsLoggedInAsGuest() const {
903 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
904 return IsUserLoggedIn() &&
905 active_user_->GetType() == User::USER_TYPE_GUEST;
906 }
907
IsLoggedInAsLocallyManagedUser() const908 bool UserManagerImpl::IsLoggedInAsLocallyManagedUser() const {
909 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
910 return IsUserLoggedIn() &&
911 active_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED;
912 }
913
IsLoggedInAsKioskApp() const914 bool UserManagerImpl::IsLoggedInAsKioskApp() const {
915 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
916 return IsUserLoggedIn() &&
917 active_user_->GetType() == User::USER_TYPE_KIOSK_APP;
918 }
919
IsLoggedInAsStub() const920 bool UserManagerImpl::IsLoggedInAsStub() const {
921 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
922 return IsUserLoggedIn() && active_user_->email() == kStubUser;
923 }
924
IsSessionStarted() const925 bool UserManagerImpl::IsSessionStarted() const {
926 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
927 return session_started_;
928 }
929
UserSessionsRestored() const930 bool UserManagerImpl::UserSessionsRestored() const {
931 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
932 return user_sessions_restored_;
933 }
934
HasBrowserRestarted() const935 bool UserManagerImpl::HasBrowserRestarted() const {
936 CommandLine* command_line = CommandLine::ForCurrentProcess();
937 return base::SysInfo::IsRunningOnChromeOS() &&
938 command_line->HasSwitch(switches::kLoginUser) &&
939 !command_line->HasSwitch(switches::kLoginPassword);
940 }
941
IsUserNonCryptohomeDataEphemeral(const std::string & user_id) const942 bool UserManagerImpl::IsUserNonCryptohomeDataEphemeral(
943 const std::string& user_id) const {
944 // Data belonging to the guest, retail mode and stub users is always
945 // ephemeral.
946 if (user_id == UserManager::kGuestUserName ||
947 user_id == UserManager::kRetailModeUserName ||
948 user_id == kStubUser) {
949 return true;
950 }
951
952 // Data belonging to the owner, anyone found on the user list and obsolete
953 // public accounts whose data has not been removed yet is not ephemeral.
954 if (user_id == owner_email_ || UserExistsInList(user_id) ||
955 user_id == g_browser_process->local_state()->
956 GetString(kPublicAccountPendingDataRemoval)) {
957 return false;
958 }
959
960 // Data belonging to the currently logged-in user is ephemeral when:
961 // a) The user logged into a regular account while the ephemeral users policy
962 // was enabled.
963 // - or -
964 // b) The user logged into any other account type.
965 if (IsUserLoggedIn() && (user_id == GetLoggedInUser()->email()) &&
966 (is_current_user_ephemeral_regular_user_ || !IsLoggedInAsRegularUser())) {
967 return true;
968 }
969
970 // Data belonging to any other user is ephemeral when:
971 // a) Going through the regular login flow and the ephemeral users policy is
972 // enabled.
973 // - or -
974 // b) The browser is restarting after a crash.
975 return AreEphemeralUsersEnabled() || HasBrowserRestarted();
976 }
977
AddObserver(UserManager::Observer * obs)978 void UserManagerImpl::AddObserver(UserManager::Observer* obs) {
979 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
980 observer_list_.AddObserver(obs);
981 }
982
RemoveObserver(UserManager::Observer * obs)983 void UserManagerImpl::RemoveObserver(UserManager::Observer* obs) {
984 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
985 observer_list_.RemoveObserver(obs);
986 }
987
AddSessionStateObserver(UserManager::UserSessionStateObserver * obs)988 void UserManagerImpl::AddSessionStateObserver(
989 UserManager::UserSessionStateObserver* obs) {
990 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
991 session_state_observer_list_.AddObserver(obs);
992 }
993
RemoveSessionStateObserver(UserManager::UserSessionStateObserver * obs)994 void UserManagerImpl::RemoveSessionStateObserver(
995 UserManager::UserSessionStateObserver* obs) {
996 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
997 session_state_observer_list_.RemoveObserver(obs);
998 }
999
NotifyLocalStateChanged()1000 void UserManagerImpl::NotifyLocalStateChanged() {
1001 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1002 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_,
1003 LocalStateChanged(this));
1004 }
1005
OnProfilePrepared(Profile * profile)1006 void UserManagerImpl::OnProfilePrepared(Profile* profile) {
1007 LoginUtils::Get()->DoBrowserLaunch(profile,
1008 NULL); // host_, not needed here
1009
1010 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) {
1011 // Did not log in (we crashed or are debugging), need to restore Sync.
1012 // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
1013 // users once it is fully multi-profile aware. http://crbug.com/238987
1014 // For now if we have other user pending sessions they'll override OAuth
1015 // session restore for previous users.
1016 LoginUtils::Get()->RestoreAuthenticationSession(profile);
1017 }
1018
1019 // Restore other user sessions if any.
1020 RestorePendingUserSessions();
1021 }
1022
EnsureUsersLoaded()1023 void UserManagerImpl::EnsureUsersLoaded() {
1024 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1025 if (!g_browser_process || !g_browser_process->local_state())
1026 return;
1027
1028 if (user_loading_stage_ != STAGE_NOT_LOADED)
1029 return;
1030 user_loading_stage_ = STAGE_LOADING;
1031 // Clean up user list first. All code down the path should be synchronous,
1032 // so that local state after transaction rollback is in consistent state.
1033 // This process also should not trigger EnsureUsersLoaded again.
1034 if (supervised_user_manager_->HasFailedUserCreationTransaction())
1035 supervised_user_manager_->RollbackUserCreationTransaction();
1036
1037 PrefService* local_state = g_browser_process->local_state();
1038 const ListValue* prefs_regular_users = local_state->GetList(kRegularUsers);
1039 const ListValue* prefs_public_accounts =
1040 local_state->GetList(kPublicAccounts);
1041 const DictionaryValue* prefs_display_names =
1042 local_state->GetDictionary(kUserDisplayName);
1043 const DictionaryValue* prefs_given_names =
1044 local_state->GetDictionary(kUserGivenName);
1045 const DictionaryValue* prefs_display_emails =
1046 local_state->GetDictionary(kUserDisplayEmail);
1047
1048 // Load regular users and locally managed users.
1049 std::vector<std::string> regular_users;
1050 std::set<std::string> regular_users_set;
1051 ParseUserList(*prefs_regular_users, std::set<std::string>(),
1052 ®ular_users, ®ular_users_set);
1053 for (std::vector<std::string>::const_iterator it = regular_users.begin();
1054 it != regular_users.end(); ++it) {
1055 User* user = NULL;
1056 const std::string domain = gaia::ExtractDomainName(*it);
1057 if (domain == UserManager::kLocallyManagedUserDomain)
1058 user = User::CreateLocallyManagedUser(*it);
1059 else
1060 user = User::CreateRegularUser(*it);
1061 user->set_oauth_token_status(LoadUserOAuthStatus(*it));
1062 users_.push_back(user);
1063
1064 base::string16 display_name;
1065 if (prefs_display_names->GetStringWithoutPathExpansion(*it,
1066 &display_name)) {
1067 user->set_display_name(display_name);
1068 }
1069
1070 base::string16 given_name;
1071 if (prefs_given_names->GetStringWithoutPathExpansion(*it, &given_name)) {
1072 user->set_given_name(given_name);
1073 }
1074
1075 std::string display_email;
1076 if (prefs_display_emails->GetStringWithoutPathExpansion(*it,
1077 &display_email)) {
1078 user->set_display_email(display_email);
1079 }
1080 }
1081
1082 // Load public accounts.
1083 std::vector<std::string> public_accounts;
1084 std::set<std::string> public_accounts_set;
1085 ParseUserList(*prefs_public_accounts, regular_users_set,
1086 &public_accounts, &public_accounts_set);
1087 for (std::vector<std::string>::const_iterator it = public_accounts.begin();
1088 it != public_accounts.end(); ++it) {
1089 users_.push_back(User::CreatePublicAccountUser(*it));
1090 UpdatePublicAccountDisplayName(*it);
1091 }
1092 user_loading_stage_ = STAGE_LOADED;
1093
1094 user_image_manager_->LoadUserImages(users_);
1095 }
1096
RetrieveTrustedDevicePolicies()1097 void UserManagerImpl::RetrieveTrustedDevicePolicies() {
1098 ephemeral_users_enabled_ = false;
1099 owner_email_ = "";
1100
1101 // Schedule a callback if device policy has not yet been verified.
1102 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
1103 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
1104 base::Unretained(this)))) {
1105 return;
1106 }
1107
1108 cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
1109 &ephemeral_users_enabled_);
1110 cros_settings_->GetString(kDeviceOwner, &owner_email_);
1111
1112 EnsureUsersLoaded();
1113
1114 bool changed = UpdateAndCleanUpPublicAccounts(
1115 policy::GetDeviceLocalAccounts(cros_settings_));
1116
1117 // If ephemeral users are enabled and we are on the login screen, take this
1118 // opportunity to clean up by removing all regular users except the owner.
1119 if (ephemeral_users_enabled_ && !IsUserLoggedIn()) {
1120 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1121 kRegularUsers);
1122 prefs_users_update->Clear();
1123 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1124 const std::string user_email = (*it)->email();
1125 if ((*it)->GetType() == User::USER_TYPE_REGULAR &&
1126 user_email != owner_email_) {
1127 RemoveNonCryptohomeData(user_email);
1128 delete *it;
1129 it = users_.erase(it);
1130 changed = true;
1131 } else {
1132 if ((*it)->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT)
1133 prefs_users_update->Append(new base::StringValue(user_email));
1134 ++it;
1135 }
1136 }
1137 }
1138
1139 if (changed)
1140 NotifyUserListChanged();
1141 }
1142
AreEphemeralUsersEnabled() const1143 bool UserManagerImpl::AreEphemeralUsersEnabled() const {
1144 return ephemeral_users_enabled_ &&
1145 (g_browser_process->browser_policy_connector()->IsEnterpriseManaged() ||
1146 !owner_email_.empty());
1147 }
1148
GetUsersAndModify()1149 UserList& UserManagerImpl::GetUsersAndModify() {
1150 EnsureUsersLoaded();
1151 return users_;
1152 }
1153
FindUserInList(const std::string & user_id) const1154 const User* UserManagerImpl::FindUserInList(const std::string& user_id) const {
1155 const UserList& users = GetUsers();
1156 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
1157 if ((*it)->email() == user_id)
1158 return *it;
1159 }
1160 return NULL;
1161 }
1162
UserExistsInList(const std::string & user_id) const1163 const bool UserManagerImpl::UserExistsInList(const std::string& user_id) const {
1164 PrefService* local_state = g_browser_process->local_state();
1165 const ListValue* user_list = local_state->GetList(kRegularUsers);
1166 for (size_t i = 0; i < user_list->GetSize(); ++i) {
1167 std::string email;
1168 if (user_list->GetString(i, &email) && (user_id == email))
1169 return true;
1170 }
1171 return false;
1172 }
1173
FindUserInListAndModify(const std::string & user_id)1174 User* UserManagerImpl::FindUserInListAndModify(const std::string& user_id) {
1175 UserList& users = GetUsersAndModify();
1176 for (UserList::iterator it = users.begin(); it != users.end(); ++it) {
1177 if ((*it)->email() == user_id)
1178 return *it;
1179 }
1180 return NULL;
1181 }
1182
GuestUserLoggedIn()1183 void UserManagerImpl::GuestUserLoggedIn() {
1184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1185 active_user_ = User::CreateGuestUser();
1186 // TODO(nkostylev): Add support for passing guest session cryptohome
1187 // mount point. Legacy (--login-profile) value will be used for now.
1188 // http://crosbug.com/230859
1189 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1190 // Initializes wallpaper after active_user_ is set.
1191 WallpaperManager::Get()->SetInitialUserWallpaper(UserManager::kGuestUserName,
1192 false);
1193 }
1194
AddUserRecord(User * user)1195 void UserManagerImpl::AddUserRecord(User* user) {
1196 // Add the user to the front of the user list.
1197 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1198 kRegularUsers);
1199 prefs_users_update->Insert(0, new base::StringValue(user->email()));
1200 users_.insert(users_.begin(), user);
1201 }
1202
RegularUserLoggedIn(const std::string & user_id)1203 void UserManagerImpl::RegularUserLoggedIn(const std::string& user_id) {
1204 // Remove the user from the user list.
1205 active_user_ = RemoveRegularOrLocallyManagedUserFromList(user_id);
1206
1207 // If the user was not found on the user list, create a new user.
1208 is_current_user_new_ = !active_user_;
1209 if (!active_user_) {
1210 active_user_ = User::CreateRegularUser(user_id);
1211 active_user_->set_oauth_token_status(LoadUserOAuthStatus(user_id));
1212 SaveUserDisplayName(active_user_->email(),
1213 UTF8ToUTF16(active_user_->GetAccountName(true)));
1214 WallpaperManager::Get()->SetInitialUserWallpaper(user_id, true);
1215 }
1216
1217 AddUserRecord(active_user_);
1218
1219 user_image_manager_->UserLoggedIn(user_id, is_current_user_new_, false);
1220
1221 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1222
1223 // Make sure that new data is persisted to Local State.
1224 g_browser_process->local_state()->CommitPendingWrite();
1225 }
1226
RegularUserLoggedInAsEphemeral(const std::string & user_id)1227 void UserManagerImpl::RegularUserLoggedInAsEphemeral(
1228 const std::string& user_id) {
1229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1230 is_current_user_new_ = true;
1231 is_current_user_ephemeral_regular_user_ = true;
1232 active_user_ = User::CreateRegularUser(user_id);
1233 user_image_manager_->UserLoggedIn(user_id, is_current_user_new_, false);
1234 WallpaperManager::Get()->SetInitialUserWallpaper(user_id, false);
1235 }
1236
LocallyManagedUserLoggedIn(const std::string & user_id)1237 void UserManagerImpl::LocallyManagedUserLoggedIn(
1238 const std::string& user_id) {
1239 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
1240
1241 // Remove the user from the user list.
1242 active_user_ = RemoveRegularOrLocallyManagedUserFromList(user_id);
1243 // If the user was not found on the user list, create a new user.
1244 if (!active_user_) {
1245 is_current_user_new_ = true;
1246 active_user_ = User::CreateLocallyManagedUser(user_id);
1247 // Leaving OAuth token status at the default state = unknown.
1248 WallpaperManager::Get()->SetInitialUserWallpaper(user_id, true);
1249 } else {
1250 if (supervised_user_manager_->CheckForFirstRun(user_id)) {
1251 is_current_user_new_ = true;
1252 WallpaperManager::Get()->SetInitialUserWallpaper(user_id, true);
1253 } else {
1254 is_current_user_new_ = false;
1255 }
1256 }
1257
1258 // Add the user to the front of the user list.
1259 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1260 kRegularUsers);
1261 prefs_users_update->Insert(0, new base::StringValue(user_id));
1262 users_.insert(users_.begin(), active_user_);
1263
1264 // Now that user is in the list, save display name.
1265 if (is_current_user_new_) {
1266 SaveUserDisplayName(active_user_->email(),
1267 active_user_->GetDisplayName());
1268 }
1269
1270 user_image_manager_->UserLoggedIn(user_id, is_current_user_new_, true);
1271 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1272
1273 // Make sure that new data is persisted to Local State.
1274 g_browser_process->local_state()->CommitPendingWrite();
1275 }
1276
PublicAccountUserLoggedIn(User * user)1277 void UserManagerImpl::PublicAccountUserLoggedIn(User* user) {
1278 is_current_user_new_ = true;
1279 active_user_ = user;
1280 // The UserImageManager chooses a random avatar picture when a user logs in
1281 // for the first time. Tell the UserImageManager that this user is not new to
1282 // prevent the avatar from getting changed.
1283 user_image_manager_->UserLoggedIn(user->email(), false, true);
1284 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1285 }
1286
KioskAppLoggedIn(const std::string & app_id)1287 void UserManagerImpl::KioskAppLoggedIn(const std::string& app_id) {
1288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1289 policy::DeviceLocalAccount::Type device_local_account_type;
1290 DCHECK(policy::IsDeviceLocalAccountUser(app_id,
1291 &device_local_account_type));
1292 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
1293 device_local_account_type);
1294
1295 active_user_ = User::CreateKioskAppUser(app_id);
1296 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1297 WallpaperManager::Get()->SetInitialUserWallpaper(app_id, false);
1298
1299 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
1300 // the kiosk_app_id in these objects, removing the need to re-parse the
1301 // device-local account list here to extract the kiosk_app_id.
1302 const std::vector<policy::DeviceLocalAccount> device_local_accounts =
1303 policy::GetDeviceLocalAccounts(cros_settings_);
1304 const policy::DeviceLocalAccount* account = NULL;
1305 for (std::vector<policy::DeviceLocalAccount>::const_iterator
1306 it = device_local_accounts.begin();
1307 it != device_local_accounts.end(); ++it) {
1308 if (it->user_id == app_id) {
1309 account = &*it;
1310 break;
1311 }
1312 }
1313 std::string kiosk_app_id;
1314 if (account) {
1315 kiosk_app_id = account->kiosk_app_id;
1316 } else {
1317 LOG(ERROR) << "Logged into nonexistent kiosk-app account: " << app_id;
1318 NOTREACHED();
1319 }
1320
1321 CommandLine* command_line = CommandLine::ForCurrentProcess();
1322 command_line->AppendSwitch(::switches::kForceAppMode);
1323 command_line->AppendSwitchASCII(::switches::kAppId, kiosk_app_id);
1324
1325 // TODO(hshi): re-enable ubercomp in kiosk mode. http://crbug.com/342061
1326 command_line->AppendSwitch(::switches::kDisableDelegatedRenderer);
1327
1328 // Disable window animation since kiosk app runs in a single full screen
1329 // window and window animation causes start-up janks.
1330 command_line->AppendSwitch(
1331 views::corewm::switches::kWindowAnimationsDisabled);
1332 }
1333
RetailModeUserLoggedIn()1334 void UserManagerImpl::RetailModeUserLoggedIn() {
1335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1336 is_current_user_new_ = true;
1337 active_user_ = User::CreateRetailModeUser();
1338 user_image_manager_->UserLoggedIn(UserManager::kRetailModeUserName,
1339 is_current_user_new_,
1340 true);
1341 WallpaperManager::Get()->SetInitialUserWallpaper(
1342 UserManager::kRetailModeUserName, false);
1343 }
1344
NotifyOnLogin()1345 void UserManagerImpl::NotifyOnLogin() {
1346 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1347 NotifyActiveUserHashChanged(active_user_->username_hash());
1348 NotifyActiveUserChanged(active_user_);
1349
1350 UpdateLoginState();
1351 // TODO(nkostylev): Deprecate this notification in favor of
1352 // ActiveUserChanged() observer call.
1353 content::NotificationService::current()->Notify(
1354 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
1355 content::Source<UserManager>(this),
1356 content::Details<const User>(active_user_));
1357
1358 // Owner must be first user in session. DeviceSettingsService can't deal with
1359 // multiple user and will mix up ownership, crbug.com/230018.
1360 if (GetLoggedInUsers().size() == 1) {
1361 // Indicate to DeviceSettingsService that the owner key may have become
1362 // available.
1363 DeviceSettingsService::Get()->SetUsername(active_user_->email());
1364 }
1365 }
1366
UpdateOwnership()1367 void UserManagerImpl::UpdateOwnership() {
1368 bool is_owner = DeviceSettingsService::Get()->HasPrivateOwnerKey();
1369 VLOG(1) << "Current user " << (is_owner ? "is owner" : "is not owner");
1370
1371 SetCurrentUserIsOwner(is_owner);
1372 }
1373
RemoveNonCryptohomeData(const std::string & user_id)1374 void UserManagerImpl::RemoveNonCryptohomeData(const std::string& user_id) {
1375 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id);
1376 user_image_manager_->DeleteUserImage(user_id);
1377
1378 PrefService* prefs = g_browser_process->local_state();
1379 DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
1380 int oauth_status;
1381 prefs_oauth_update->GetIntegerWithoutPathExpansion(user_id, &oauth_status);
1382 prefs_oauth_update->RemoveWithoutPathExpansion(user_id, NULL);
1383
1384 DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
1385 prefs_display_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1386
1387 DictionaryPrefUpdate prefs_given_name_update(prefs, kUserGivenName);
1388 prefs_given_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1389
1390 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
1391 prefs_display_email_update->RemoveWithoutPathExpansion(user_id, NULL);
1392
1393 supervised_user_manager_->RemoveNonCryptohomeData(user_id);
1394
1395 multi_profile_user_controller_->RemoveCachedValues(user_id);
1396 }
1397
RemoveRegularOrLocallyManagedUserFromList(const std::string & user_id)1398 User* UserManagerImpl::RemoveRegularOrLocallyManagedUserFromList(
1399 const std::string& user_id) {
1400 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1401 kRegularUsers);
1402 prefs_users_update->Clear();
1403 User* user = NULL;
1404 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1405 const std::string user_email = (*it)->email();
1406 if (user_email == user_id) {
1407 user = *it;
1408 it = users_.erase(it);
1409 } else {
1410 if ((*it)->GetType() == User::USER_TYPE_REGULAR ||
1411 (*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) {
1412 prefs_users_update->Append(new base::StringValue(user_email));
1413 }
1414 ++it;
1415 }
1416 }
1417 return user;
1418 }
1419
CleanUpPublicAccountNonCryptohomeDataPendingRemoval()1420 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
1421 PrefService* local_state = g_browser_process->local_state();
1422 const std::string public_account_pending_data_removal =
1423 local_state->GetString(kPublicAccountPendingDataRemoval);
1424 if (public_account_pending_data_removal.empty() ||
1425 (IsUserLoggedIn() &&
1426 public_account_pending_data_removal == GetActiveUser()->email())) {
1427 return;
1428 }
1429
1430 RemoveNonCryptohomeData(public_account_pending_data_removal);
1431 local_state->ClearPref(kPublicAccountPendingDataRemoval);
1432 }
1433
CleanUpPublicAccountNonCryptohomeData(const std::vector<std::string> & old_public_accounts)1434 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
1435 const std::vector<std::string>& old_public_accounts) {
1436 std::set<std::string> users;
1437 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it)
1438 users.insert((*it)->email());
1439
1440 // If the user is logged into a public account that has been removed from the
1441 // user list, mark the account's data as pending removal after logout.
1442 if (IsLoggedInAsPublicAccount()) {
1443 const std::string active_user_id = GetActiveUser()->email();
1444 if (users.find(active_user_id) == users.end()) {
1445 g_browser_process->local_state()->SetString(
1446 kPublicAccountPendingDataRemoval, active_user_id);
1447 users.insert(active_user_id);
1448 }
1449 }
1450
1451 // Remove the data belonging to any other public accounts that are no longer
1452 // found on the user list.
1453 for (std::vector<std::string>::const_iterator
1454 it = old_public_accounts.begin();
1455 it != old_public_accounts.end(); ++it) {
1456 if (users.find(*it) == users.end())
1457 RemoveNonCryptohomeData(*it);
1458 }
1459 }
1460
UpdateAndCleanUpPublicAccounts(const std::vector<policy::DeviceLocalAccount> & device_local_accounts)1461 bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
1462 const std::vector<policy::DeviceLocalAccount>& device_local_accounts) {
1463 // Try to remove any public account data marked as pending removal.
1464 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
1465
1466 // Get the current list of public accounts.
1467 std::vector<std::string> old_public_accounts;
1468 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it) {
1469 if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT)
1470 old_public_accounts.push_back((*it)->email());
1471 }
1472
1473 // Get the new list of public accounts from policy.
1474 std::vector<std::string> new_public_accounts;
1475 for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
1476 device_local_accounts.begin();
1477 it != device_local_accounts.end(); ++it) {
1478 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
1479 // standard login framework: http://crbug.com/234694
1480 if (it->type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
1481 new_public_accounts.push_back(it->user_id);
1482 }
1483
1484 // If the list of public accounts has not changed, return.
1485 if (new_public_accounts.size() == old_public_accounts.size()) {
1486 bool changed = false;
1487 for (size_t i = 0; i < new_public_accounts.size(); ++i) {
1488 if (new_public_accounts[i] != old_public_accounts[i]) {
1489 changed = true;
1490 break;
1491 }
1492 }
1493 if (!changed)
1494 return false;
1495 }
1496
1497 // Persist the new list of public accounts in a pref.
1498 ListPrefUpdate prefs_public_accounts_update(g_browser_process->local_state(),
1499 kPublicAccounts);
1500 prefs_public_accounts_update->Clear();
1501 for (std::vector<std::string>::const_iterator
1502 it = new_public_accounts.begin();
1503 it != new_public_accounts.end(); ++it) {
1504 prefs_public_accounts_update->AppendString(*it);
1505 }
1506
1507 // Remove the old public accounts from the user list.
1508 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1509 if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
1510 if (*it != GetLoggedInUser())
1511 delete *it;
1512 it = users_.erase(it);
1513 } else {
1514 ++it;
1515 }
1516 }
1517
1518 // Add the new public accounts to the front of the user list.
1519 for (std::vector<std::string>::const_reverse_iterator
1520 it = new_public_accounts.rbegin();
1521 it != new_public_accounts.rend(); ++it) {
1522 if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email())
1523 users_.insert(users_.begin(), GetLoggedInUser());
1524 else
1525 users_.insert(users_.begin(), User::CreatePublicAccountUser(*it));
1526 UpdatePublicAccountDisplayName(*it);
1527 }
1528
1529 user_image_manager_->LoadUserImages(
1530 UserList(users_.begin(), users_.begin() + new_public_accounts.size()));
1531
1532 // Remove data belonging to public accounts that are no longer found on the
1533 // user list.
1534 CleanUpPublicAccountNonCryptohomeData(old_public_accounts);
1535
1536 return true;
1537 }
1538
UpdatePublicAccountDisplayName(const std::string & user_id)1539 void UserManagerImpl::UpdatePublicAccountDisplayName(
1540 const std::string& user_id) {
1541 std::string display_name;
1542
1543 if (device_local_account_policy_service_) {
1544 policy::DeviceLocalAccountPolicyBroker* broker =
1545 device_local_account_policy_service_->GetBrokerForUser(user_id);
1546 if (broker)
1547 display_name = broker->GetDisplayName();
1548 }
1549
1550 // Set or clear the display name.
1551 SaveUserDisplayName(user_id, UTF8ToUTF16(display_name));
1552 }
1553
GetCurrentUserFlow() const1554 UserFlow* UserManagerImpl::GetCurrentUserFlow() const {
1555 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1556 if (!IsUserLoggedIn())
1557 return GetDefaultUserFlow();
1558 return GetUserFlow(GetLoggedInUser()->email());
1559 }
1560
GetUserFlow(const std::string & user_id) const1561 UserFlow* UserManagerImpl::GetUserFlow(const std::string& user_id) const {
1562 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1563 FlowMap::const_iterator it = specific_flows_.find(user_id);
1564 if (it != specific_flows_.end())
1565 return it->second;
1566 return GetDefaultUserFlow();
1567 }
1568
SetUserFlow(const std::string & user_id,UserFlow * flow)1569 void UserManagerImpl::SetUserFlow(const std::string& user_id, UserFlow* flow) {
1570 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1571 ResetUserFlow(user_id);
1572 specific_flows_[user_id] = flow;
1573 }
1574
ResetUserFlow(const std::string & user_id)1575 void UserManagerImpl::ResetUserFlow(const std::string& user_id) {
1576 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1577 FlowMap::iterator it = specific_flows_.find(user_id);
1578 if (it != specific_flows_.end()) {
1579 delete it->second;
1580 specific_flows_.erase(it);
1581 }
1582 }
1583
GetAppModeChromeClientOAuthInfo(std::string * chrome_client_id,std::string * chrome_client_secret)1584 bool UserManagerImpl::GetAppModeChromeClientOAuthInfo(
1585 std::string* chrome_client_id, std::string* chrome_client_secret) {
1586 if (!chrome::IsRunningInForcedAppMode() ||
1587 chrome_client_id_.empty() ||
1588 chrome_client_secret_.empty()) {
1589 return false;
1590 }
1591
1592 *chrome_client_id = chrome_client_id_;
1593 *chrome_client_secret = chrome_client_secret_;
1594 return true;
1595 }
1596
SetAppModeChromeClientOAuthInfo(const std::string & chrome_client_id,const std::string & chrome_client_secret)1597 void UserManagerImpl::SetAppModeChromeClientOAuthInfo(
1598 const std::string& chrome_client_id,
1599 const std::string& chrome_client_secret) {
1600 if (!chrome::IsRunningInForcedAppMode())
1601 return;
1602
1603 chrome_client_id_ = chrome_client_id;
1604 chrome_client_secret_ = chrome_client_secret;
1605 }
1606
AreLocallyManagedUsersAllowed() const1607 bool UserManagerImpl::AreLocallyManagedUsersAllowed() const {
1608 bool locally_managed_users_allowed = false;
1609 cros_settings_->GetBoolean(kAccountsPrefSupervisedUsersEnabled,
1610 &locally_managed_users_allowed);
1611 return locally_managed_users_allowed ||
1612 !g_browser_process->browser_policy_connector()->IsEnterpriseManaged();
1613 }
1614
GetUserProfileDir(const std::string & user_id) const1615 base::FilePath UserManagerImpl::GetUserProfileDir(
1616 const std::string& user_id) const {
1617 // TODO(dpolukhin): Remove Chrome OS specific profile path logic from
1618 // ProfileManager and use only this function to construct profile path.
1619 // TODO(nkostylev): Cleanup profile dir related code paths crbug.com/294233
1620 base::FilePath profile_dir;
1621 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1622 if (command_line.HasSwitch(::switches::kMultiProfiles)) {
1623 const User* user = FindUser(user_id);
1624 if (user && !user->username_hash().empty())
1625 profile_dir = ProfileHelper::GetUserProfileDir(user->username_hash());
1626 } else if (command_line.HasSwitch(chromeos::switches::kLoginProfile)) {
1627 profile_dir = ProfileHelper::GetProfileDirByLegacyLoginProfileSwitch();
1628 } else {
1629 // We should never be logged in with no profile dir unless
1630 // multi-profiles are enabled.
1631 NOTREACHED();
1632 profile_dir = base::FilePath();
1633 }
1634
1635 ProfileManager* profile_manager = g_browser_process->profile_manager();
1636 profile_dir = profile_manager->user_data_dir().Append(profile_dir);
1637
1638 return profile_dir;
1639 }
1640
GetDefaultUserFlow() const1641 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();
1646 }
1647
NotifyUserListChanged()1648 void UserManagerImpl::NotifyUserListChanged() {
1649 content::NotificationService::current()->Notify(
1650 chrome::NOTIFICATION_USER_LIST_CHANGED,
1651 content::Source<UserManager>(this),
1652 content::NotificationService::NoDetails());
1653 }
1654
NotifyActiveUserChanged(const User * active_user)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));
1660 }
1661
NotifyUserAddedToSession(const User * added_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));
1667 }
1668
NotifyActiveUserHashChanged(const std::string & hash)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));
1674 }
1675
NotifyPendingUserSessionsRestoreFinished()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());
1682 }
1683
UpdateLoginState()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;
1690
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;
1706 else
1707 login_user_type = LoginState::LOGGED_IN_USER_REGULAR;
1708
1709 LoginState::Get()->SetLoggedInState(logged_in_state, login_user_type);
1710 }
1711
SetLRUUser(User * user)1712 void UserManagerImpl::SetLRUUser(User* user) {
1713 UserList::iterator it = std::find(lru_logged_in_users_.begin(),
1714 lru_logged_in_users_.end(),
1715 user);
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);
1719 }
1720
OnRestoreActiveSessions(const SessionManagerClient::ActiveSessionsMap & sessions,bool success)1721 void UserManagerImpl::OnRestoreActiveSessions(
1722 const SessionManagerClient::ActiveSessionsMap& sessions,
1723 bool success) {
1724 if (!success) {
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();
1729 return;
1730 }
1731
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();
1736
1737 SessionManagerClient::ActiveSessionsMap::const_iterator it;
1738 for (it = sessions.begin(); it != sessions.end(); ++it) {
1739 if (active_user_id == it->first)
1740 continue;
1741 pending_user_sessions_[it->first] = it->second;
1742 }
1743 RestorePendingUserSessions();
1744 }
1745
RestorePendingUserSessions()1746 void UserManagerImpl::RestorePendingUserSessions() {
1747 if (pending_user_sessions_.empty()) {
1748 NotifyPendingUserSessionsRestoreFinished();
1749 return;
1750 }
1751
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);
1760
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;
1769 break;
1770 }
1771 }
1772 DCHECK(!user_already_logged_in);
1773
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
1779 user_id_hash,
1780 false), // using_oauth
1781 std::string(), // display_email
1782 false, // has_cookies
1783 true, // has_active_session
1784 this);
1785 } else {
1786 RestorePendingUserSessions();
1787 }
1788 }
1789
SendRegularUserLoginMetrics(const std::string & user_id)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);
1803 }
1804 }
1805 }
1806
OnUserNotAllowed()1807 void UserManagerImpl::OnUserNotAllowed() {
1808 LOG(ERROR) << "Shutdown session because a user is not allowed to be in the "
1809 "current session";
1810 chrome::AttemptUserExit();
1811 }
1812
UpdateUserAccountLocale(const std::string & user_id,const std::string & locale)1813 void UserManagerImpl::UpdateUserAccountLocale(const std::string& user_id,
1814 const std::string& locale) {
1815 if (!locale.empty() &&
1816 locale != g_browser_process->GetApplicationLocale()) {
1817 BrowserThread::PostBlockingPoolTask(
1818 FROM_HERE,
1819 base::Bind(ResolveLocale, locale,
1820 base::Bind(&UserManagerImpl::DoUpdateAccountLocale,
1821 base::Unretained(this),
1822 user_id)));
1823 } else {
1824 DoUpdateAccountLocale(user_id, locale);
1825 }
1826 }
1827
DoUpdateAccountLocale(const std::string & user_id,const std::string & resolved_locale)1828 void UserManagerImpl::DoUpdateAccountLocale(
1829 const std::string& user_id,
1830 const std::string& resolved_locale) {
1831 if (User* user = FindUserAndModify(user_id))
1832 user->SetAccountLocale(resolved_locale);
1833 }
1834
1835
1836 } // namespace chromeos
1837