Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: chrome/browser/chromeos/login/users/user_manager_impl.cc

Issue 417623002: user_manager component: Add UserManagerBase class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: check for LocalState, update test - make sure that policies are initialized on UserManager creation Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/login/users/user_manager_impl.h"
6
7 #include <cstddef>
8 #include <set>
9
10 #include "ash/multi_profile_uma.h"
11 #include "base/base_paths.h"
12 #include "base/bind.h"
13 #include "base/bind_helpers.h"
14 #include "base/command_line.h"
15 #include "base/compiler_specific.h"
16 #include "base/files/file_path.h"
17 #include "base/format_macros.h"
18 #include "base/logging.h"
19 #include "base/metrics/histogram.h"
20 #include "base/path_service.h"
21 #include "base/prefs/pref_registry_simple.h"
22 #include "base/prefs/pref_service.h"
23 #include "base/prefs/scoped_user_pref_update.h"
24 #include "base/rand_util.h"
25 #include "base/strings/string_util.h"
26 #include "base/strings/stringprintf.h"
27 #include "base/strings/utf_string_conversions.h"
28 #include "base/sys_info.h"
29 #include "base/threading/worker_pool.h"
30 #include "base/values.h"
31 #include "chrome/browser/browser_process.h"
32 #include "chrome/browser/chrome_notification_types.h"
33 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
34 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
35 #include "chrome/browser/chromeos/login/signin/auth_sync_observer.h"
36 #include "chrome/browser/chromeos/login/signin/auth_sync_observer_factory.h"
37 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h"
38 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
39 #include "chrome/browser/chromeos/login/users/remove_user_delegate.h"
40 #include "chrome/browser/chromeos/login/users/supervised_user_manager_impl.h"
41 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
42 #include "chrome/browser/chromeos/policy/device_local_account.h"
43 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog. h"
44 #include "chrome/browser/chromeos/profiles/profile_helper.h"
45 #include "chrome/browser/chromeos/session_length_limiter.h"
46 #include "chrome/browser/net/crl_set_fetcher.h"
47 #include "chrome/browser/profiles/profile.h"
48 #include "chrome/browser/supervised_user/chromeos/manager_password_service_facto ry.h"
49 #include "chrome/browser/supervised_user/chromeos/supervised_user_password_servi ce_factory.h"
50 #include "chrome/common/chrome_constants.h"
51 #include "chrome/common/chrome_paths.h"
52 #include "chrome/common/chrome_switches.h"
53 #include "chrome/common/crash_keys.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/auth/user_context.h"
59 #include "chromeos/login/login_state.h"
60 #include "chromeos/login/user_names.h"
61 #include "chromeos/settings/cros_settings_names.h"
62 #include "components/session_manager/core/session_manager.h"
63 #include "components/user_manager/user_image/user_image.h"
64 #include "components/user_manager/user_type.h"
65 #include "content/public/browser/browser_thread.h"
66 #include "content/public/browser/notification_service.h"
67 #include "google_apis/gaia/gaia_auth_util.h"
68 #include "google_apis/gaia/google_service_auth_error.h"
69 #include "grit/theme_resources.h"
70 #include "policy/policy_constants.h"
71 #include "ui/base/l10n/l10n_util.h"
72 #include "ui/base/resource/resource_bundle.h"
73 #include "ui/wm/core/wm_core_switches.h"
74
75 using content::BrowserThread;
76
77 namespace chromeos {
78 namespace {
79
80 // A vector pref of the the regular users known on this device, arranged in LRU
81 // order.
82 const char kRegularUsers[] = "LoggedInUsers";
83
84 // A vector pref of the public accounts defined on this device.
85 const char kPublicAccounts[] = "PublicAccounts";
86
87 // A string pref that gets set when a public account is removed but a user is
88 // currently logged into that account, requiring the account's data to be
89 // removed after logout.
90 const char kPublicAccountPendingDataRemoval[] =
91 "PublicAccountPendingDataRemoval";
92
93 // A dictionary that maps user IDs to the displayed name.
94 const char kUserDisplayName[] = "UserDisplayName";
95
96 // A dictionary that maps user IDs to the user's given name.
97 const char kUserGivenName[] = "UserGivenName";
98
99 // A dictionary that maps user IDs to the displayed (non-canonical) emails.
100 const char kUserDisplayEmail[] = "UserDisplayEmail";
101
102 // A dictionary that maps user IDs to OAuth token presence flag.
103 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus";
104
105 // A dictionary that maps user IDs to a flag indicating whether online
106 // authentication against GAIA should be enforced during the next sign-in.
107 const char kUserForceOnlineSignin[] = "UserForceOnlineSignin";
108
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";
113
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;
117
118 // Callback that is called after user removal is complete.
119 void OnRemoveUserComplete(const std::string& user_email,
120 bool success,
121 cryptohome::MountError return_code) {
122 // Log the error, but there's not much we can do.
123 if (!success) {
124 LOG(ERROR) << "Removal of cryptohome for " << user_email
125 << " failed, return code: " << return_code;
126 }
127 }
128
129 // Helper function that copies users from |users_list| to |users_vector| and
130 // |users_set|. Duplicates and users already present in |existing_users| are
131 // skipped.
132 void ParseUserList(const base::ListValue& users_list,
133 const std::set<std::string>& existing_users,
134 std::vector<std::string>* users_vector,
135 std::set<std::string>* users_set) {
136 users_vector->clear();
137 users_set->clear();
138 for (size_t i = 0; i < users_list.GetSize(); ++i) {
139 std::string email;
140 if (!users_list.GetString(i, &email) || email.empty()) {
141 LOG(ERROR) << "Corrupt entry in user list at index " << i << ".";
142 continue;
143 }
144 if (existing_users.find(email) != existing_users.end() ||
145 !users_set->insert(email).second) {
146 LOG(ERROR) << "Duplicate user: " << email;
147 continue;
148 }
149 users_vector->push_back(email);
150 }
151 }
152
153 // Runs on SequencedWorkerPool thread. Passes resolved locale to
154 // |on_resolve_callback| on UI thread.
155 void ResolveLocale(
156 const std::string& raw_locale,
157 base::Callback<void(const std::string&)> on_resolve_callback) {
158 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
159 std::string resolved_locale;
160 // Ignore result
161 l10n_util::CheckAndResolveLocale(raw_locale, &resolved_locale);
162 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
163 base::Bind(on_resolve_callback, resolved_locale));
164 }
165
166 } // namespace
167
168 // static
169 void UserManager::RegisterPrefs(PrefRegistrySimple* registry) {
170 registry->RegisterListPref(kRegularUsers);
171 registry->RegisterListPref(kPublicAccounts);
172 registry->RegisterStringPref(kPublicAccountPendingDataRemoval, "");
173 registry->RegisterStringPref(kLastLoggedInRegularUser, "");
174 registry->RegisterDictionaryPref(kUserDisplayName);
175 registry->RegisterDictionaryPref(kUserGivenName);
176 registry->RegisterDictionaryPref(kUserDisplayEmail);
177 registry->RegisterDictionaryPref(kUserOAuthTokenStatus);
178 registry->RegisterDictionaryPref(kUserForceOnlineSignin);
179 SupervisedUserManager::RegisterPrefs(registry);
180 SessionLengthLimiter::RegisterPrefs(registry);
181 }
182
183 UserManagerImpl::UserManagerImpl()
184 : cros_settings_(CrosSettings::Get()),
185 device_local_account_policy_service_(NULL),
186 user_loading_stage_(STAGE_NOT_LOADED),
187 active_user_(NULL),
188 primary_user_(NULL),
189 session_started_(false),
190 is_current_user_owner_(false),
191 is_current_user_new_(false),
192 is_current_user_ephemeral_regular_user_(false),
193 ephemeral_users_enabled_(false),
194 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
195 manager_creation_time_(base::TimeTicks::Now()) {
196 UpdateNumberOfUsers();
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 multi_profile_user_controller_.reset(new MultiProfileUserController(
212 this, g_browser_process->local_state()));
213
214 policy::BrowserPolicyConnectorChromeOS* connector =
215 g_browser_process->platform_part()->browser_policy_connector_chromeos();
216 avatar_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
217 cros_settings_,
218 connector->GetDeviceLocalAccountPolicyService(),
219 policy::key::kUserAvatarImage,
220 this));
221 avatar_policy_observer_->Init();
222
223 wallpaper_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
224 cros_settings_,
225 connector->GetDeviceLocalAccountPolicyService(),
226 policy::key::kWallpaperImage,
227 this));
228 wallpaper_policy_observer_->Init();
229
230 UpdateLoginState();
231 }
232
233 UserManagerImpl::~UserManagerImpl() {
234 // Can't use STLDeleteElements because of the private destructor of User.
235 for (user_manager::UserList::iterator it = users_.begin(); it != users_.end();
236 it = users_.erase(it)) {
237 DeleteUser(*it);
238 }
239 // These are pointers to the same User instances that were in users_ list.
240 logged_in_users_.clear();
241 lru_logged_in_users_.clear();
242
243 DeleteUser(active_user_);
244 }
245
246 void UserManagerImpl::Shutdown() {
247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
248 local_accounts_subscription_.reset();
249 // Stop the session length limiter.
250 session_length_limiter_.reset();
251
252 if (device_local_account_policy_service_)
253 device_local_account_policy_service_->RemoveObserver(this);
254
255 for (UserImageManagerMap::iterator it = user_image_managers_.begin(),
256 ie = user_image_managers_.end();
257 it != ie; ++it) {
258 it->second->Shutdown();
259 }
260 multi_profile_user_controller_.reset();
261 avatar_policy_observer_.reset();
262 wallpaper_policy_observer_.reset();
263 registrar_.RemoveAll();
264 }
265
266 MultiProfileUserController* UserManagerImpl::GetMultiProfileUserController() {
267 return multi_profile_user_controller_.get();
268 }
269
270 UserImageManager* UserManagerImpl::GetUserImageManager(
271 const std::string& user_id) {
272 UserImageManagerMap::iterator ui = user_image_managers_.find(user_id);
273 if (ui != user_image_managers_.end())
274 return ui->second.get();
275 linked_ptr<UserImageManagerImpl> mgr(new UserImageManagerImpl(user_id, this));
276 user_image_managers_[user_id] = mgr;
277 return mgr.get();
278 }
279
280 SupervisedUserManager* UserManagerImpl::GetSupervisedUserManager() {
281 return supervised_user_manager_.get();
282 }
283
284 const user_manager::UserList& UserManagerImpl::GetUsers() const {
285 const_cast<UserManagerImpl*>(this)->EnsureUsersLoaded();
286 return users_;
287 }
288
289 user_manager::UserList UserManagerImpl::GetUsersAdmittedForMultiProfile()
290 const {
291 // Supervised users are not allowed to use multi-profiles.
292 if (logged_in_users_.size() == 1 &&
293 GetPrimaryUser()->GetType() != user_manager::USER_TYPE_REGULAR) {
294 return user_manager::UserList();
295 }
296
297 user_manager::UserList result;
298 const user_manager::UserList& users = GetUsers();
299 for (user_manager::UserList::const_iterator it = users.begin();
300 it != users.end();
301 ++it) {
302 if ((*it)->GetType() == user_manager::USER_TYPE_REGULAR &&
303 !(*it)->is_logged_in()) {
304 MultiProfileUserController::UserAllowedInSessionResult check =
305 multi_profile_user_controller_->
306 IsUserAllowedInSession((*it)->email());
307 if (check == MultiProfileUserController::
308 NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS) {
309 return user_manager::UserList();
310 }
311
312 // Users with a policy that prevents them being added to a session will be
313 // shown in login UI but will be grayed out.
314 // Same applies to owner account (see http://crbug.com/385034).
315 if (check == MultiProfileUserController::ALLOWED ||
316 check == MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS ||
317 check == MultiProfileUserController::NOT_ALLOWED_OWNER_AS_SECONDARY) {
318 result.push_back(*it);
319 }
320 }
321 }
322
323 return result;
324 }
325
326 const user_manager::UserList& UserManagerImpl::GetLoggedInUsers() const {
327 return logged_in_users_;
328 }
329
330 const user_manager::UserList& UserManagerImpl::GetLRULoggedInUsers() {
331 // If there is no user logged in, we return the active user as the only one.
332 if (lru_logged_in_users_.empty() && active_user_) {
333 temp_single_logged_in_users_.clear();
334 temp_single_logged_in_users_.insert(temp_single_logged_in_users_.begin(),
335 active_user_);
336 return temp_single_logged_in_users_;
337 }
338 return lru_logged_in_users_;
339 }
340
341 user_manager::UserList UserManagerImpl::GetUnlockUsers() const {
342 const user_manager::UserList& logged_in_users = GetLoggedInUsers();
343 if (logged_in_users.empty())
344 return user_manager::UserList();
345
346 user_manager::UserList unlock_users;
347 Profile* profile = ProfileHelper::Get()->GetProfileByUser(primary_user_);
348 std::string primary_behavior =
349 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
350
351 // Specific case: only one logged in user or
352 // primary user has primary-only multi-profile policy.
353 if (logged_in_users.size() == 1 ||
354 primary_behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
355 if (primary_user_->can_lock())
356 unlock_users.push_back(primary_user_);
357 } else {
358 // Fill list of potential unlock users based on multi-profile policy state.
359 for (user_manager::UserList::const_iterator it = logged_in_users.begin();
360 it != logged_in_users.end();
361 ++it) {
362 user_manager::User* user = (*it);
363 Profile* profile = ProfileHelper::Get()->GetProfileByUser(user);
364 const std::string behavior =
365 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
366 if (behavior == MultiProfileUserController::kBehaviorUnrestricted &&
367 user->can_lock()) {
368 unlock_users.push_back(user);
369 } else if (behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
370 NOTREACHED()
371 << "Spotted primary-only multi-profile policy for non-primary user";
372 }
373 }
374 }
375
376 return unlock_users;
377 }
378
379 const std::string& UserManagerImpl::GetOwnerEmail() {
380 return owner_email_;
381 }
382
383 void UserManagerImpl::UserLoggedIn(const std::string& user_id,
384 const std::string& username_hash,
385 bool browser_restart) {
386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
387
388 user_manager::User* user = FindUserInListAndModify(user_id);
389 if (active_user_ && user) {
390 user->set_is_logged_in(true);
391 user->set_username_hash(username_hash);
392 logged_in_users_.push_back(user);
393 lru_logged_in_users_.push_back(user);
394 // Reset the new user flag if the user already exists.
395 is_current_user_new_ = false;
396 NotifyUserAddedToSession(user);
397 // Remember that we need to switch to this user as soon as profile ready.
398 pending_user_switch_ = user_id;
399 return;
400 }
401
402 policy::DeviceLocalAccount::Type device_local_account_type;
403 if (user_id == chromeos::login::kGuestUserName) {
404 GuestUserLoggedIn();
405 } else if (user_id == chromeos::login::kRetailModeUserName) {
406 RetailModeUserLoggedIn();
407 } else if (policy::IsDeviceLocalAccountUser(user_id,
408 &device_local_account_type) &&
409 device_local_account_type ==
410 policy::DeviceLocalAccount::TYPE_KIOSK_APP) {
411 KioskAppLoggedIn(user_id);
412 } else if (DemoAppLauncher::IsDemoAppSession(user_id)) {
413 DemoAccountLoggedIn();
414 } else {
415 EnsureUsersLoaded();
416
417 if (user && user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
418 PublicAccountUserLoggedIn(user);
419 } else if ((user &&
420 user->GetType() == user_manager::USER_TYPE_SUPERVISED) ||
421 (!user &&
422 gaia::ExtractDomainName(user_id) ==
423 chromeos::login::kSupervisedUserDomain)) {
424 SupervisedUserLoggedIn(user_id);
425 } else if (browser_restart && user_id == g_browser_process->local_state()->
426 GetString(kPublicAccountPendingDataRemoval)) {
427 PublicAccountUserLoggedIn(
428 user_manager::User::CreatePublicAccountUser(user_id));
429 } else if (user_id != owner_email_ && !user &&
430 (AreEphemeralUsersEnabled() || browser_restart)) {
431 RegularUserLoggedInAsEphemeral(user_id);
432 } else {
433 RegularUserLoggedIn(user_id);
434 }
435
436 // Initialize the session length limiter and start it only if
437 // session limit is defined by the policy.
438 session_length_limiter_.reset(new SessionLengthLimiter(NULL,
439 browser_restart));
440 }
441 DCHECK(active_user_);
442 active_user_->set_is_logged_in(true);
443 active_user_->set_is_active(true);
444 active_user_->set_username_hash(username_hash);
445
446 // Place user who just signed in to the top of the logged in users.
447 logged_in_users_.insert(logged_in_users_.begin(), active_user_);
448 SetLRUUser(active_user_);
449
450 if (!primary_user_) {
451 // Register CRLSet now that the home dir is mounted.
452 if (!username_hash.empty()) {
453 base::FilePath path;
454 path =
455 chromeos::ProfileHelper::GetProfilePathByUserIdHash(username_hash);
456 component_updater::ComponentUpdateService* cus =
457 g_browser_process->component_updater();
458 CRLSetFetcher* crl_set = g_browser_process->crl_set_fetcher();
459 if (crl_set && cus)
460 crl_set->StartInitialLoad(cus, path);
461 }
462 primary_user_ = active_user_;
463 if (primary_user_->GetType() == user_manager::USER_TYPE_REGULAR)
464 SendRegularUserLoginMetrics(user_id);
465 }
466
467 UMA_HISTOGRAM_ENUMERATION("UserManager.LoginUserType",
468 active_user_->GetType(),
469 user_manager::NUM_USER_TYPES);
470
471 g_browser_process->local_state()->SetString(
472 kLastLoggedInRegularUser,
473 (active_user_->GetType() == user_manager::USER_TYPE_REGULAR) ? user_id
474 : "");
475
476 NotifyOnLogin();
477 }
478
479 void UserManagerImpl::SwitchActiveUser(const std::string& user_id) {
480 user_manager::User* user = FindUserAndModify(user_id);
481 if (!user) {
482 NOTREACHED() << "Switching to a non-existing user";
483 return;
484 }
485 if (user == active_user_) {
486 NOTREACHED() << "Switching to a user who is already active";
487 return;
488 }
489 if (!user->is_logged_in()) {
490 NOTREACHED() << "Switching to a user that is not logged in";
491 return;
492 }
493 if (user->GetType() != user_manager::USER_TYPE_REGULAR) {
494 NOTREACHED() << "Switching to a non-regular user";
495 return;
496 }
497 if (user->username_hash().empty()) {
498 NOTREACHED() << "Switching to a user that doesn't have username_hash set";
499 return;
500 }
501
502 DCHECK(active_user_);
503 active_user_->set_is_active(false);
504 user->set_is_active(true);
505 active_user_ = user;
506
507 // Move the user to the front.
508 SetLRUUser(active_user_);
509
510 NotifyActiveUserHashChanged(active_user_->username_hash());
511 NotifyActiveUserChanged(active_user_);
512 }
513
514 void UserManagerImpl::SessionStarted() {
515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
516 session_started_ = true;
517
518 UpdateLoginState();
519 g_browser_process->platform_part()->SessionManager()->SetSessionState(
520 session_manager::SESSION_STATE_ACTIVE);
521
522 content::NotificationService::current()->Notify(
523 chrome::NOTIFICATION_SESSION_STARTED,
524 content::Source<UserManager>(this),
525 content::Details<const user_manager::User>(active_user_));
526 if (is_current_user_new_) {
527 // Make sure that the new user's data is persisted to Local State.
528 g_browser_process->local_state()->CommitPendingWrite();
529 }
530 }
531
532 void UserManagerImpl::RemoveUser(const std::string& user_id,
533 RemoveUserDelegate* delegate) {
534 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
535
536 const user_manager::User* user = FindUser(user_id);
537 if (!user || (user->GetType() != user_manager::USER_TYPE_REGULAR &&
538 user->GetType() != user_manager::USER_TYPE_SUPERVISED))
539 return;
540
541 // Sanity check: we must not remove single user unless it's an enterprise
542 // device. This check may seem redundant at a first sight because
543 // this single user must be an owner and we perform special check later
544 // in order not to remove an owner. However due to non-instant nature of
545 // ownership assignment this later check may sometimes fail.
546 // See http://crosbug.com/12723
547 policy::BrowserPolicyConnectorChromeOS* connector =
548 g_browser_process->platform_part()
549 ->browser_policy_connector_chromeos();
550 if (users_.size() < 2 && !connector->IsEnterpriseManaged())
551 return;
552
553 // Sanity check: do not allow any of the the logged in users to be removed.
554 for (user_manager::UserList::const_iterator it = logged_in_users_.begin();
555 it != logged_in_users_.end();
556 ++it) {
557 if ((*it)->email() == user_id)
558 return;
559 }
560
561 RemoveUserInternal(user_id, delegate);
562 }
563
564 void UserManagerImpl::RemoveUserInternal(const std::string& user_email,
565 RemoveUserDelegate* delegate) {
566 CrosSettings* cros_settings = CrosSettings::Get();
567
568 // Ensure the value of owner email has been fetched.
569 if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues(
570 base::Bind(&UserManagerImpl::RemoveUserInternal,
571 base::Unretained(this),
572 user_email, delegate))) {
573 // Value of owner email is not fetched yet. RemoveUserInternal will be
574 // called again after fetch completion.
575 return;
576 }
577 std::string owner;
578 cros_settings->GetString(kDeviceOwner, &owner);
579 if (user_email == owner) {
580 // Owner is not allowed to be removed from the device.
581 return;
582 }
583 RemoveNonOwnerUserInternal(user_email, delegate);
584 }
585
586 void UserManagerImpl::RemoveNonOwnerUserInternal(const std::string& user_email,
587 RemoveUserDelegate* delegate) {
588 if (delegate)
589 delegate->OnBeforeUserRemoved(user_email);
590 RemoveUserFromList(user_email);
591 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
592 user_email, base::Bind(&OnRemoveUserComplete, user_email));
593
594 if (delegate)
595 delegate->OnUserRemoved(user_email);
596 }
597
598 void UserManagerImpl::RemoveUserFromList(const std::string& user_id) {
599 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
600 RemoveNonCryptohomeData(user_id);
601 if (user_loading_stage_ == STAGE_LOADED) {
602 DeleteUser(RemoveRegularOrSupervisedUserFromList(user_id));
603 } else if (user_loading_stage_ == STAGE_LOADING) {
604 DCHECK(gaia::ExtractDomainName(user_id) ==
605 chromeos::login::kSupervisedUserDomain);
606 // Special case, removing partially-constructed supervised user during user
607 // list loading.
608 ListPrefUpdate users_update(g_browser_process->local_state(),
609 kRegularUsers);
610 users_update->Remove(base::StringValue(user_id), NULL);
611 } else {
612 NOTREACHED() << "Users are not loaded yet.";
613 return;
614 }
615 // Make sure that new data is persisted to Local State.
616 g_browser_process->local_state()->CommitPendingWrite();
617 }
618
619 bool UserManagerImpl::IsKnownUser(const std::string& user_id) const {
620 return FindUser(user_id) != NULL;
621 }
622
623 const user_manager::User* UserManagerImpl::FindUser(
624 const std::string& user_id) const {
625 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
626 if (active_user_ && active_user_->email() == user_id)
627 return active_user_;
628 return FindUserInList(user_id);
629 }
630
631 user_manager::User* UserManagerImpl::FindUserAndModify(
632 const std::string& user_id) {
633 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
634 if (active_user_ && active_user_->email() == user_id)
635 return active_user_;
636 return FindUserInListAndModify(user_id);
637 }
638
639 const user_manager::User* UserManagerImpl::GetLoggedInUser() const {
640 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
641 return active_user_;
642 }
643
644 user_manager::User* UserManagerImpl::GetLoggedInUser() {
645 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
646 return active_user_;
647 }
648
649 const user_manager::User* UserManagerImpl::GetActiveUser() const {
650 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
651 return active_user_;
652 }
653
654 user_manager::User* UserManagerImpl::GetActiveUser() {
655 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
656 return active_user_;
657 }
658
659 const user_manager::User* UserManagerImpl::GetPrimaryUser() const {
660 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
661 return primary_user_;
662 }
663
664 void UserManagerImpl::SaveUserOAuthStatus(
665 const std::string& user_id,
666 user_manager::User::OAuthTokenStatus oauth_token_status) {
667 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
668
669 DVLOG(1) << "Saving user OAuth token status in Local State";
670 user_manager::User* user = FindUserAndModify(user_id);
671 if (user)
672 user->set_oauth_token_status(oauth_token_status);
673
674 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(oauth_token_status);
675
676 // Do not update local state if data stored or cached outside the user's
677 // cryptohome is to be treated as ephemeral.
678 if (IsUserNonCryptohomeDataEphemeral(user_id))
679 return;
680
681 PrefService* local_state = g_browser_process->local_state();
682
683 DictionaryPrefUpdate oauth_status_update(local_state, kUserOAuthTokenStatus);
684 oauth_status_update->SetWithoutPathExpansion(user_id,
685 new base::FundamentalValue(static_cast<int>(oauth_token_status)));
686 }
687
688 void UserManagerImpl::SaveForceOnlineSignin(const std::string& user_id,
689 bool force_online_signin) {
690 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
691
692 // Do not update local state if data stored or cached outside the user's
693 // cryptohome is to be treated as ephemeral.
694 if (IsUserNonCryptohomeDataEphemeral(user_id))
695 return;
696
697 DictionaryPrefUpdate force_online_update(g_browser_process->local_state(),
698 kUserForceOnlineSignin);
699 force_online_update->SetBooleanWithoutPathExpansion(user_id,
700 force_online_signin);
701 }
702
703 void UserManagerImpl::SaveUserDisplayName(const std::string& user_id,
704 const base::string16& display_name) {
705 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
706
707 if (user_manager::User* user = FindUserAndModify(user_id)) {
708 user->set_display_name(display_name);
709
710 // Do not update local state if data stored or cached outside the user's
711 // cryptohome is to be treated as ephemeral.
712 if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
713 PrefService* local_state = g_browser_process->local_state();
714
715 DictionaryPrefUpdate display_name_update(local_state, kUserDisplayName);
716 display_name_update->SetWithoutPathExpansion(
717 user_id,
718 new base::StringValue(display_name));
719
720 supervised_user_manager_->UpdateManagerName(user_id, display_name);
721 }
722 }
723 }
724
725 base::string16 UserManagerImpl::GetUserDisplayName(
726 const std::string& user_id) const {
727 const user_manager::User* user = FindUser(user_id);
728 return user ? user->display_name() : base::string16();
729 }
730
731 void UserManagerImpl::SaveUserDisplayEmail(const std::string& user_id,
732 const std::string& display_email) {
733 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
734
735 user_manager::User* user = FindUserAndModify(user_id);
736 if (!user)
737 return; // Ignore if there is no such user.
738
739 user->set_display_email(display_email);
740
741 // Do not update local state if data stored or cached outside the user's
742 // cryptohome is to be treated as ephemeral.
743 if (IsUserNonCryptohomeDataEphemeral(user_id))
744 return;
745
746 PrefService* local_state = g_browser_process->local_state();
747
748 DictionaryPrefUpdate display_email_update(local_state, kUserDisplayEmail);
749 display_email_update->SetWithoutPathExpansion(
750 user_id,
751 new base::StringValue(display_email));
752 }
753
754 std::string UserManagerImpl::GetUserDisplayEmail(
755 const std::string& user_id) const {
756 const user_manager::User* user = FindUser(user_id);
757 return user ? user->display_email() : user_id;
758 }
759
760 void UserManagerImpl::UpdateUserAccountData(
761 const std::string& user_id,
762 const UserAccountData& account_data) {
763 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
764
765 SaveUserDisplayName(user_id, account_data.display_name());
766
767 if (user_manager::User* user = FindUserAndModify(user_id)) {
768 base::string16 given_name = account_data.given_name();
769 user->set_given_name(given_name);
770 if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
771 PrefService* local_state = g_browser_process->local_state();
772
773 DictionaryPrefUpdate given_name_update(local_state, kUserGivenName);
774 given_name_update->SetWithoutPathExpansion(
775 user_id,
776 new base::StringValue(given_name));
777 }
778 }
779
780 UpdateUserAccountLocale(user_id, account_data.locale());
781 }
782
783 void UserManagerImpl::StopPolicyObserverForTesting() {
784 avatar_policy_observer_.reset();
785 wallpaper_policy_observer_.reset();
786 }
787
788 void UserManagerImpl::Observe(int type,
789 const content::NotificationSource& source,
790 const content::NotificationDetails& details) {
791 switch (type) {
792 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED:
793 if (!device_local_account_policy_service_) {
794 policy::BrowserPolicyConnectorChromeOS* connector =
795 g_browser_process->platform_part()
796 ->browser_policy_connector_chromeos();
797 device_local_account_policy_service_ =
798 connector->GetDeviceLocalAccountPolicyService();
799 if (device_local_account_policy_service_)
800 device_local_account_policy_service_->AddObserver(this);
801 }
802 RetrieveTrustedDevicePolicies();
803 UpdateOwnership();
804 break;
805 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: {
806 Profile* profile = content::Details<Profile>(details).ptr();
807 if (IsUserLoggedIn() &&
808 !IsLoggedInAsGuest() &&
809 !IsLoggedInAsKioskApp()) {
810 if (IsLoggedInAsSupervisedUser())
811 SupervisedUserPasswordServiceFactory::GetForProfile(profile);
812 if (IsLoggedInAsRegularUser())
813 ManagerPasswordServiceFactory::GetForProfile(profile);
814
815 if (!profile->IsOffTheRecord()) {
816 AuthSyncObserver* sync_observer =
817 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile);
818 sync_observer->StartObserving();
819 multi_profile_user_controller_->StartObserving(profile);
820 }
821 }
822 break;
823 }
824 case chrome::NOTIFICATION_PROFILE_CREATED: {
825 Profile* profile = content::Source<Profile>(source).ptr();
826 user_manager::User* user =
827 ProfileHelper::Get()->GetUserByProfile(profile);
828 if (user != NULL)
829 user->set_profile_is_created();
830 // If there is pending user switch, do it now.
831 if (!pending_user_switch_.empty()) {
832 // Call SwitchActiveUser async because otherwise it may cause
833 // ProfileManager::GetProfile before the profile gets registered
834 // in ProfileManager. It happens in case of sync profile load when
835 // NOTIFICATION_PROFILE_CREATED is called synchronously.
836 base::MessageLoop::current()->PostTask(FROM_HERE,
837 base::Bind(&UserManagerImpl::SwitchActiveUser,
838 base::Unretained(this),
839 pending_user_switch_));
840 pending_user_switch_.clear();
841 }
842 break;
843 }
844 default:
845 NOTREACHED();
846 }
847 }
848
849 void UserManagerImpl::OnExternalDataSet(const std::string& policy,
850 const std::string& user_id) {
851 if (policy == policy::key::kUserAvatarImage)
852 GetUserImageManager(user_id)->OnExternalDataSet(policy);
853 else if (policy == policy::key::kWallpaperImage)
854 WallpaperManager::Get()->OnPolicySet(policy, user_id);
855 else
856 NOTREACHED();
857 }
858
859 void UserManagerImpl::OnExternalDataCleared(const std::string& policy,
860 const std::string& user_id) {
861 if (policy == policy::key::kUserAvatarImage)
862 GetUserImageManager(user_id)->OnExternalDataCleared(policy);
863 else if (policy == policy::key::kWallpaperImage)
864 WallpaperManager::Get()->OnPolicyCleared(policy, user_id);
865 else
866 NOTREACHED();
867 }
868
869 void UserManagerImpl::OnExternalDataFetched(const std::string& policy,
870 const std::string& user_id,
871 scoped_ptr<std::string> data) {
872 if (policy == policy::key::kUserAvatarImage)
873 GetUserImageManager(user_id)->OnExternalDataFetched(policy, data.Pass());
874 else if (policy == policy::key::kWallpaperImage)
875 WallpaperManager::Get()->OnPolicyFetched(policy, user_id, data.Pass());
876 else
877 NOTREACHED();
878 }
879
880 void UserManagerImpl::OnPolicyUpdated(const std::string& user_id) {
881 const user_manager::User* user = FindUserInList(user_id);
882 if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
883 return;
884 UpdatePublicAccountDisplayName(user_id);
885 NotifyUserListChanged();
886 }
887
888 void UserManagerImpl::OnDeviceLocalAccountsChanged() {
889 // No action needed here, changes to the list of device-local accounts get
890 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
891 }
892
893 bool UserManagerImpl::IsCurrentUserOwner() const {
894 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
895 base::AutoLock lk(is_current_user_owner_lock_);
896 return is_current_user_owner_;
897 }
898
899 void UserManagerImpl::SetCurrentUserIsOwner(bool is_current_user_owner) {
900 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
901 {
902 base::AutoLock lk(is_current_user_owner_lock_);
903 is_current_user_owner_ = is_current_user_owner;
904 }
905 UpdateLoginState();
906 }
907
908 bool UserManagerImpl::IsCurrentUserNew() const {
909 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
910 return is_current_user_new_;
911 }
912
913 bool UserManagerImpl::IsCurrentUserNonCryptohomeDataEphemeral() const {
914 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
915 return IsUserLoggedIn() &&
916 IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email());
917 }
918
919 bool UserManagerImpl::CanCurrentUserLock() const {
920 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
921 return IsUserLoggedIn() && active_user_->can_lock() &&
922 GetCurrentUserFlow()->CanLockScreen();
923 }
924
925 bool UserManagerImpl::IsUserLoggedIn() const {
926 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
927 return active_user_;
928 }
929
930 bool UserManagerImpl::IsLoggedInAsRegularUser() const {
931 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
932 return IsUserLoggedIn() &&
933 active_user_->GetType() == user_manager::USER_TYPE_REGULAR;
934 }
935
936 bool UserManagerImpl::IsLoggedInAsDemoUser() const {
937 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
938 return IsUserLoggedIn() &&
939 active_user_->GetType() == user_manager::USER_TYPE_RETAIL_MODE;
940 }
941
942 bool UserManagerImpl::IsLoggedInAsPublicAccount() const {
943 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
944 return IsUserLoggedIn() &&
945 active_user_->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT;
946 }
947
948 bool UserManagerImpl::IsLoggedInAsGuest() const {
949 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
950 return IsUserLoggedIn() &&
951 active_user_->GetType() == user_manager::USER_TYPE_GUEST;
952 }
953
954 bool UserManagerImpl::IsLoggedInAsSupervisedUser() const {
955 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
956 return IsUserLoggedIn() &&
957 active_user_->GetType() == user_manager::USER_TYPE_SUPERVISED;
958 }
959
960 bool UserManagerImpl::IsLoggedInAsKioskApp() const {
961 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
962 return IsUserLoggedIn() &&
963 active_user_->GetType() == user_manager::USER_TYPE_KIOSK_APP;
964 }
965
966 bool UserManagerImpl::IsLoggedInAsStub() const {
967 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
968 return IsUserLoggedIn() && active_user_->email() == login::kStubUser;
969 }
970
971 bool UserManagerImpl::IsSessionStarted() const {
972 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
973 return session_started_;
974 }
975
976 bool UserManagerImpl::IsUserNonCryptohomeDataEphemeral(
977 const std::string& user_id) const {
978 // Data belonging to the guest, retail mode and stub users is always
979 // ephemeral.
980 if (user_id == login::kGuestUserName ||
981 user_id == login::kRetailModeUserName || user_id == login::kStubUser) {
982 return true;
983 }
984
985 // Data belonging to the owner, anyone found on the user list and obsolete
986 // public accounts whose data has not been removed yet is not ephemeral.
987 if (user_id == owner_email_ || UserExistsInList(user_id) ||
988 user_id == g_browser_process->local_state()->
989 GetString(kPublicAccountPendingDataRemoval)) {
990 return false;
991 }
992
993 // Data belonging to the currently logged-in user is ephemeral when:
994 // a) The user logged into a regular account while the ephemeral users policy
995 // was enabled.
996 // - or -
997 // b) The user logged into any other account type.
998 if (IsUserLoggedIn() && (user_id == GetLoggedInUser()->email()) &&
999 (is_current_user_ephemeral_regular_user_ || !IsLoggedInAsRegularUser())) {
1000 return true;
1001 }
1002
1003 // Data belonging to any other user is ephemeral when:
1004 // a) Going through the regular login flow and the ephemeral users policy is
1005 // enabled.
1006 // - or -
1007 // b) The browser is restarting after a crash.
1008 return AreEphemeralUsersEnabled() ||
1009 UserSessionManager::GetInstance()->HasBrowserRestarted();
1010 }
1011
1012 void UserManagerImpl::AddObserver(UserManager::Observer* obs) {
1013 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1014 observer_list_.AddObserver(obs);
1015 }
1016
1017 void UserManagerImpl::RemoveObserver(UserManager::Observer* obs) {
1018 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1019 observer_list_.RemoveObserver(obs);
1020 }
1021
1022 void UserManagerImpl::AddSessionStateObserver(
1023 UserManager::UserSessionStateObserver* obs) {
1024 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1025 session_state_observer_list_.AddObserver(obs);
1026 }
1027
1028 void UserManagerImpl::RemoveSessionStateObserver(
1029 UserManager::UserSessionStateObserver* obs) {
1030 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1031 session_state_observer_list_.RemoveObserver(obs);
1032 }
1033
1034 void UserManagerImpl::NotifyLocalStateChanged() {
1035 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1036 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_,
1037 LocalStateChanged(this));
1038 }
1039
1040 void UserManagerImpl::EnsureUsersLoaded() {
1041 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1042 if (!g_browser_process || !g_browser_process->local_state())
1043 return;
1044
1045 if (user_loading_stage_ != STAGE_NOT_LOADED)
1046 return;
1047 user_loading_stage_ = STAGE_LOADING;
1048 // Clean up user list first. All code down the path should be synchronous,
1049 // so that local state after transaction rollback is in consistent state.
1050 // This process also should not trigger EnsureUsersLoaded again.
1051 if (supervised_user_manager_->HasFailedUserCreationTransaction())
1052 supervised_user_manager_->RollbackUserCreationTransaction();
1053
1054 PrefService* local_state = g_browser_process->local_state();
1055 const base::ListValue* prefs_regular_users =
1056 local_state->GetList(kRegularUsers);
1057 const base::ListValue* prefs_public_sessions =
1058 local_state->GetList(kPublicAccounts);
1059 const base::DictionaryValue* prefs_display_names =
1060 local_state->GetDictionary(kUserDisplayName);
1061 const base::DictionaryValue* prefs_given_names =
1062 local_state->GetDictionary(kUserGivenName);
1063 const base::DictionaryValue* prefs_display_emails =
1064 local_state->GetDictionary(kUserDisplayEmail);
1065
1066 // Load public sessions first.
1067 std::vector<std::string> public_sessions;
1068 std::set<std::string> public_sessions_set;
1069 ParseUserList(*prefs_public_sessions, std::set<std::string>(),
1070 &public_sessions, &public_sessions_set);
1071 for (std::vector<std::string>::const_iterator it = public_sessions.begin();
1072 it != public_sessions.end(); ++it) {
1073 users_.push_back(user_manager::User::CreatePublicAccountUser(*it));
1074 UpdatePublicAccountDisplayName(*it);
1075 }
1076
1077 // Load regular users and supervised users.
1078 std::vector<std::string> regular_users;
1079 std::set<std::string> regular_users_set;
1080 ParseUserList(*prefs_regular_users, public_sessions_set,
1081 &regular_users, &regular_users_set);
1082 for (std::vector<std::string>::const_iterator it = regular_users.begin();
1083 it != regular_users.end(); ++it) {
1084 user_manager::User* user = NULL;
1085 const std::string domain = gaia::ExtractDomainName(*it);
1086 if (domain == chromeos::login::kSupervisedUserDomain)
1087 user = user_manager::User::CreateSupervisedUser(*it);
1088 else
1089 user = user_manager::User::CreateRegularUser(*it);
1090 user->set_oauth_token_status(LoadUserOAuthStatus(*it));
1091 user->set_force_online_signin(LoadForceOnlineSignin(*it));
1092 users_.push_back(user);
1093
1094 base::string16 display_name;
1095 if (prefs_display_names->GetStringWithoutPathExpansion(*it,
1096 &display_name)) {
1097 user->set_display_name(display_name);
1098 }
1099
1100 base::string16 given_name;
1101 if (prefs_given_names->GetStringWithoutPathExpansion(*it, &given_name)) {
1102 user->set_given_name(given_name);
1103 }
1104
1105 std::string display_email;
1106 if (prefs_display_emails->GetStringWithoutPathExpansion(*it,
1107 &display_email)) {
1108 user->set_display_email(display_email);
1109 }
1110 }
1111
1112 user_loading_stage_ = STAGE_LOADED;
1113
1114 for (user_manager::UserList::iterator ui = users_.begin(), ue = users_.end();
1115 ui != ue;
1116 ++ui) {
1117 GetUserImageManager((*ui)->email())->LoadUserImage();
1118 }
1119 }
1120
1121 void UserManagerImpl::RetrieveTrustedDevicePolicies() {
1122 ephemeral_users_enabled_ = false;
1123 owner_email_.clear();
1124
1125 // Schedule a callback if device policy has not yet been verified.
1126 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
1127 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
1128 base::Unretained(this)))) {
1129 return;
1130 }
1131
1132 cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
1133 &ephemeral_users_enabled_);
1134 cros_settings_->GetString(kDeviceOwner, &owner_email_);
1135
1136 EnsureUsersLoaded();
1137
1138 bool changed = UpdateAndCleanUpPublicAccounts(
1139 policy::GetDeviceLocalAccounts(cros_settings_));
1140
1141 // If ephemeral users are enabled and we are on the login screen, take this
1142 // opportunity to clean up by removing all regular users except the owner.
1143 if (ephemeral_users_enabled_ && !IsUserLoggedIn()) {
1144 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1145 kRegularUsers);
1146 prefs_users_update->Clear();
1147 for (user_manager::UserList::iterator it = users_.begin();
1148 it != users_.end();) {
1149 const std::string user_email = (*it)->email();
1150 if ((*it)->GetType() == user_manager::USER_TYPE_REGULAR &&
1151 user_email != owner_email_) {
1152 RemoveNonCryptohomeData(user_email);
1153 DeleteUser(*it);
1154 it = users_.erase(it);
1155 changed = true;
1156 } else {
1157 if ((*it)->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
1158 prefs_users_update->Append(new base::StringValue(user_email));
1159 ++it;
1160 }
1161 }
1162 }
1163
1164 if (changed)
1165 NotifyUserListChanged();
1166 }
1167
1168 bool UserManagerImpl::AreEphemeralUsersEnabled() const {
1169 policy::BrowserPolicyConnectorChromeOS* connector =
1170 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1171 return ephemeral_users_enabled_ &&
1172 (connector->IsEnterpriseManaged() || !owner_email_.empty());
1173 }
1174
1175 user_manager::UserList& UserManagerImpl::GetUsersAndModify() {
1176 EnsureUsersLoaded();
1177 return users_;
1178 }
1179
1180 const user_manager::User* UserManagerImpl::FindUserInList(
1181 const std::string& user_id) const {
1182 const user_manager::UserList& users = GetUsers();
1183 for (user_manager::UserList::const_iterator it = users.begin();
1184 it != users.end();
1185 ++it) {
1186 if ((*it)->email() == user_id)
1187 return *it;
1188 }
1189 return NULL;
1190 }
1191
1192 const bool UserManagerImpl::UserExistsInList(const std::string& user_id) const {
1193 PrefService* local_state = g_browser_process->local_state();
1194 const base::ListValue* user_list = local_state->GetList(kRegularUsers);
1195 for (size_t i = 0; i < user_list->GetSize(); ++i) {
1196 std::string email;
1197 if (user_list->GetString(i, &email) && (user_id == email))
1198 return true;
1199 }
1200 return false;
1201 }
1202
1203 user_manager::User* UserManagerImpl::FindUserInListAndModify(
1204 const std::string& user_id) {
1205 user_manager::UserList& users = GetUsersAndModify();
1206 for (user_manager::UserList::iterator it = users.begin(); it != users.end();
1207 ++it) {
1208 if ((*it)->email() == user_id)
1209 return *it;
1210 }
1211 return NULL;
1212 }
1213
1214 void UserManagerImpl::GuestUserLoggedIn() {
1215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1216 active_user_ = user_manager::User::CreateGuestUser();
1217 // TODO(nkostylev): Add support for passing guest session cryptohome
1218 // mount point. Legacy (--login-profile) value will be used for now.
1219 // http://crosbug.com/230859
1220 active_user_->SetStubImage(
1221 user_manager::UserImage(
1222 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
1223 IDR_PROFILE_PICTURE_LOADING)),
1224 user_manager::User::USER_IMAGE_INVALID,
1225 false);
1226 // Initializes wallpaper after active_user_ is set.
1227 WallpaperManager::Get()->SetUserWallpaperNow(chromeos::login::kGuestUserName);
1228 }
1229
1230 void UserManagerImpl::AddUserRecord(user_manager::User* user) {
1231 // Add the user to the front of the user list.
1232 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1233 kRegularUsers);
1234 prefs_users_update->Insert(0, new base::StringValue(user->email()));
1235 users_.insert(users_.begin(), user);
1236 }
1237
1238 void UserManagerImpl::RegularUserLoggedIn(const std::string& user_id) {
1239 // Remove the user from the user list.
1240 active_user_ = RemoveRegularOrSupervisedUserFromList(user_id);
1241
1242 // If the user was not found on the user list, create a new user.
1243 is_current_user_new_ = !active_user_;
1244 if (!active_user_) {
1245 active_user_ = user_manager::User::CreateRegularUser(user_id);
1246 active_user_->set_oauth_token_status(LoadUserOAuthStatus(user_id));
1247 SaveUserDisplayName(active_user_->email(),
1248 base::UTF8ToUTF16(active_user_->GetAccountName(true)));
1249 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1250 }
1251
1252 AddUserRecord(active_user_);
1253
1254 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, false);
1255
1256 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1257
1258 // Make sure that new data is persisted to Local State.
1259 g_browser_process->local_state()->CommitPendingWrite();
1260 }
1261
1262 void UserManagerImpl::RegularUserLoggedInAsEphemeral(
1263 const std::string& user_id) {
1264 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1265 is_current_user_new_ = true;
1266 is_current_user_ephemeral_regular_user_ = true;
1267 active_user_ = user_manager::User::CreateRegularUser(user_id);
1268 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, false);
1269 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1270 }
1271
1272 void UserManagerImpl::SupervisedUserLoggedIn(
1273 const std::string& user_id) {
1274 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
1275
1276 // Remove the user from the user list.
1277 active_user_ = RemoveRegularOrSupervisedUserFromList(user_id);
1278 // If the user was not found on the user list, create a new user.
1279 if (!active_user_) {
1280 is_current_user_new_ = true;
1281 active_user_ = user_manager::User::CreateSupervisedUser(user_id);
1282 // Leaving OAuth token status at the default state = unknown.
1283 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1284 } else {
1285 if (supervised_user_manager_->CheckForFirstRun(user_id)) {
1286 is_current_user_new_ = true;
1287 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1288 } else {
1289 is_current_user_new_ = false;
1290 }
1291 }
1292
1293 // Add the user to the front of the user list.
1294 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1295 kRegularUsers);
1296 prefs_users_update->Insert(0, new base::StringValue(user_id));
1297 users_.insert(users_.begin(), active_user_);
1298
1299 // Now that user is in the list, save display name.
1300 if (is_current_user_new_) {
1301 SaveUserDisplayName(active_user_->email(),
1302 active_user_->GetDisplayName());
1303 }
1304
1305 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, true);
1306 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1307
1308 // Make sure that new data is persisted to Local State.
1309 g_browser_process->local_state()->CommitPendingWrite();
1310 }
1311
1312 void UserManagerImpl::PublicAccountUserLoggedIn(user_manager::User* user) {
1313 is_current_user_new_ = true;
1314 active_user_ = user;
1315 // The UserImageManager chooses a random avatar picture when a user logs in
1316 // for the first time. Tell the UserImageManager that this user is not new to
1317 // prevent the avatar from getting changed.
1318 GetUserImageManager(user->email())->UserLoggedIn(false, true);
1319 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1320 }
1321
1322 void UserManagerImpl::KioskAppLoggedIn(const std::string& app_id) {
1323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1324 policy::DeviceLocalAccount::Type device_local_account_type;
1325 DCHECK(policy::IsDeviceLocalAccountUser(app_id,
1326 &device_local_account_type));
1327 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
1328 device_local_account_type);
1329
1330 active_user_ = user_manager::User::CreateKioskAppUser(app_id);
1331 active_user_->SetStubImage(
1332 user_manager::UserImage(
1333 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
1334 IDR_PROFILE_PICTURE_LOADING)),
1335 user_manager::User::USER_IMAGE_INVALID,
1336 false);
1337
1338 WallpaperManager::Get()->SetUserWallpaperNow(app_id);
1339
1340 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
1341 // the kiosk_app_id in these objects, removing the need to re-parse the
1342 // device-local account list here to extract the kiosk_app_id.
1343 const std::vector<policy::DeviceLocalAccount> device_local_accounts =
1344 policy::GetDeviceLocalAccounts(cros_settings_);
1345 const policy::DeviceLocalAccount* account = NULL;
1346 for (std::vector<policy::DeviceLocalAccount>::const_iterator
1347 it = device_local_accounts.begin();
1348 it != device_local_accounts.end(); ++it) {
1349 if (it->user_id == app_id) {
1350 account = &*it;
1351 break;
1352 }
1353 }
1354 std::string kiosk_app_id;
1355 if (account) {
1356 kiosk_app_id = account->kiosk_app_id;
1357 } else {
1358 LOG(ERROR) << "Logged into nonexistent kiosk-app account: " << app_id;
1359 NOTREACHED();
1360 }
1361
1362 CommandLine* command_line = CommandLine::ForCurrentProcess();
1363 command_line->AppendSwitch(::switches::kForceAppMode);
1364 command_line->AppendSwitchASCII(::switches::kAppId, kiosk_app_id);
1365
1366 // Disable window animation since kiosk app runs in a single full screen
1367 // window and window animation causes start-up janks.
1368 command_line->AppendSwitch(
1369 wm::switches::kWindowAnimationsDisabled);
1370 }
1371
1372 void UserManagerImpl::DemoAccountLoggedIn() {
1373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1374 active_user_ =
1375 user_manager::User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName);
1376 active_user_->SetStubImage(
1377 user_manager::UserImage(
1378 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
1379 IDR_PROFILE_PICTURE_LOADING)),
1380 user_manager::User::USER_IMAGE_INVALID,
1381 false);
1382 WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName);
1383
1384 CommandLine* command_line = CommandLine::ForCurrentProcess();
1385 command_line->AppendSwitch(::switches::kForceAppMode);
1386 command_line->AppendSwitchASCII(::switches::kAppId,
1387 DemoAppLauncher::kDemoAppId);
1388
1389 // Disable window animation since the demo app runs in a single full screen
1390 // window and window animation causes start-up janks.
1391 CommandLine::ForCurrentProcess()->AppendSwitch(
1392 wm::switches::kWindowAnimationsDisabled);
1393 }
1394
1395 void UserManagerImpl::RetailModeUserLoggedIn() {
1396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1397 is_current_user_new_ = true;
1398 active_user_ = user_manager::User::CreateRetailModeUser();
1399 GetUserImageManager(chromeos::login::kRetailModeUserName)
1400 ->UserLoggedIn(is_current_user_new_, true);
1401 WallpaperManager::Get()->SetUserWallpaperNow(
1402 chromeos::login::kRetailModeUserName);
1403 }
1404
1405 void UserManagerImpl::NotifyOnLogin() {
1406 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1407
1408 UserSessionManager::OverrideHomedir();
1409
1410 UpdateNumberOfUsers();
1411 NotifyActiveUserHashChanged(active_user_->username_hash());
1412 NotifyActiveUserChanged(active_user_);
1413 UpdateLoginState();
1414
1415 // TODO(nkostylev): Deprecate this notification in favor of
1416 // ActiveUserChanged() observer call.
1417 content::NotificationService::current()->Notify(
1418 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
1419 content::Source<UserManager>(this),
1420 content::Details<const user_manager::User>(active_user_));
1421
1422 UserSessionManager::GetInstance()->PerformPostUserLoggedInActions();
1423 }
1424
1425 user_manager::User::OAuthTokenStatus UserManagerImpl::LoadUserOAuthStatus(
1426 const std::string& user_id) const {
1427 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1428
1429 PrefService* local_state = g_browser_process->local_state();
1430 const base::DictionaryValue* prefs_oauth_status =
1431 local_state->GetDictionary(kUserOAuthTokenStatus);
1432 int oauth_token_status = user_manager::User::OAUTH_TOKEN_STATUS_UNKNOWN;
1433 if (prefs_oauth_status &&
1434 prefs_oauth_status->GetIntegerWithoutPathExpansion(
1435 user_id, &oauth_token_status)) {
1436 user_manager::User::OAuthTokenStatus result =
1437 static_cast<user_manager::User::OAuthTokenStatus>(oauth_token_status);
1438 if (result == user_manager::User::OAUTH2_TOKEN_STATUS_INVALID)
1439 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(result);
1440 return result;
1441 }
1442 return user_manager::User::OAUTH_TOKEN_STATUS_UNKNOWN;
1443 }
1444
1445 bool UserManagerImpl::LoadForceOnlineSignin(const std::string& user_id) const {
1446 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1447
1448 PrefService* local_state = g_browser_process->local_state();
1449 const base::DictionaryValue* prefs_force_online =
1450 local_state->GetDictionary(kUserForceOnlineSignin);
1451 bool force_online_signin = false;
1452 if (prefs_force_online) {
1453 prefs_force_online->GetBooleanWithoutPathExpansion(user_id,
1454 &force_online_signin);
1455 }
1456 return force_online_signin;
1457 }
1458
1459 void UserManagerImpl::UpdateOwnership() {
1460 bool is_owner = DeviceSettingsService::Get()->HasPrivateOwnerKey();
1461 VLOG(1) << "Current user " << (is_owner ? "is owner" : "is not owner");
1462
1463 SetCurrentUserIsOwner(is_owner);
1464 }
1465
1466 void UserManagerImpl::RemoveNonCryptohomeData(const std::string& user_id) {
1467 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id);
1468 GetUserImageManager(user_id)->DeleteUserImage();
1469
1470 PrefService* prefs = g_browser_process->local_state();
1471 DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
1472 prefs_display_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1473
1474 DictionaryPrefUpdate prefs_given_name_update(prefs, kUserGivenName);
1475 prefs_given_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1476
1477 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
1478 prefs_display_email_update->RemoveWithoutPathExpansion(user_id, NULL);
1479
1480 DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
1481 prefs_oauth_update->RemoveWithoutPathExpansion(user_id, NULL);
1482
1483 DictionaryPrefUpdate prefs_force_online_update(prefs, kUserForceOnlineSignin);
1484 prefs_force_online_update->RemoveWithoutPathExpansion(user_id, NULL);
1485
1486 supervised_user_manager_->RemoveNonCryptohomeData(user_id);
1487
1488 multi_profile_user_controller_->RemoveCachedValues(user_id);
1489 }
1490
1491 user_manager::User* UserManagerImpl::RemoveRegularOrSupervisedUserFromList(
1492 const std::string& user_id) {
1493 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1494 kRegularUsers);
1495 prefs_users_update->Clear();
1496 user_manager::User* user = NULL;
1497 for (user_manager::UserList::iterator it = users_.begin();
1498 it != users_.end();) {
1499 const std::string user_email = (*it)->email();
1500 if (user_email == user_id) {
1501 user = *it;
1502 it = users_.erase(it);
1503 } else {
1504 if ((*it)->GetType() == user_manager::USER_TYPE_REGULAR ||
1505 (*it)->GetType() == user_manager::USER_TYPE_SUPERVISED) {
1506 prefs_users_update->Append(new base::StringValue(user_email));
1507 }
1508 ++it;
1509 }
1510 }
1511 return user;
1512 }
1513
1514 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
1515 PrefService* local_state = g_browser_process->local_state();
1516 const std::string public_account_pending_data_removal =
1517 local_state->GetString(kPublicAccountPendingDataRemoval);
1518 if (public_account_pending_data_removal.empty() ||
1519 (IsUserLoggedIn() &&
1520 public_account_pending_data_removal == GetActiveUser()->email())) {
1521 return;
1522 }
1523
1524 RemoveNonCryptohomeData(public_account_pending_data_removal);
1525 local_state->ClearPref(kPublicAccountPendingDataRemoval);
1526 }
1527
1528 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
1529 const std::vector<std::string>& old_public_accounts) {
1530 std::set<std::string> users;
1531 for (user_manager::UserList::const_iterator it = users_.begin();
1532 it != users_.end();
1533 ++it)
1534 users.insert((*it)->email());
1535
1536 // If the user is logged into a public account that has been removed from the
1537 // user list, mark the account's data as pending removal after logout.
1538 if (IsLoggedInAsPublicAccount()) {
1539 const std::string active_user_id = GetActiveUser()->email();
1540 if (users.find(active_user_id) == users.end()) {
1541 g_browser_process->local_state()->SetString(
1542 kPublicAccountPendingDataRemoval, active_user_id);
1543 users.insert(active_user_id);
1544 }
1545 }
1546
1547 // Remove the data belonging to any other public accounts that are no longer
1548 // found on the user list.
1549 for (std::vector<std::string>::const_iterator
1550 it = old_public_accounts.begin();
1551 it != old_public_accounts.end(); ++it) {
1552 if (users.find(*it) == users.end())
1553 RemoveNonCryptohomeData(*it);
1554 }
1555 }
1556
1557 bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
1558 const std::vector<policy::DeviceLocalAccount>& device_local_accounts) {
1559 // Try to remove any public account data marked as pending removal.
1560 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
1561
1562 // Get the current list of public accounts.
1563 std::vector<std::string> old_public_accounts;
1564 for (user_manager::UserList::const_iterator it = users_.begin();
1565 it != users_.end();
1566 ++it) {
1567 if ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT)
1568 old_public_accounts.push_back((*it)->email());
1569 }
1570
1571 // Get the new list of public accounts from policy.
1572 std::vector<std::string> new_public_accounts;
1573 for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
1574 device_local_accounts.begin();
1575 it != device_local_accounts.end(); ++it) {
1576 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
1577 // standard login framework: http://crbug.com/234694
1578 if (it->type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
1579 new_public_accounts.push_back(it->user_id);
1580 }
1581
1582 // If the list of public accounts has not changed, return.
1583 if (new_public_accounts.size() == old_public_accounts.size()) {
1584 bool changed = false;
1585 for (size_t i = 0; i < new_public_accounts.size(); ++i) {
1586 if (new_public_accounts[i] != old_public_accounts[i]) {
1587 changed = true;
1588 break;
1589 }
1590 }
1591 if (!changed)
1592 return false;
1593 }
1594
1595 // Persist the new list of public accounts in a pref.
1596 ListPrefUpdate prefs_public_accounts_update(g_browser_process->local_state(),
1597 kPublicAccounts);
1598 prefs_public_accounts_update->Clear();
1599 for (std::vector<std::string>::const_iterator it =
1600 new_public_accounts.begin();
1601 it != new_public_accounts.end(); ++it) {
1602 prefs_public_accounts_update->AppendString(*it);
1603 }
1604
1605 // Remove the old public accounts from the user list.
1606 for (user_manager::UserList::iterator it = users_.begin();
1607 it != users_.end();) {
1608 if ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
1609 if (*it != GetLoggedInUser())
1610 DeleteUser(*it);
1611 it = users_.erase(it);
1612 } else {
1613 ++it;
1614 }
1615 }
1616
1617 // Add the new public accounts to the front of the user list.
1618 for (std::vector<std::string>::const_reverse_iterator it =
1619 new_public_accounts.rbegin();
1620 it != new_public_accounts.rend(); ++it) {
1621 if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email())
1622 users_.insert(users_.begin(), GetLoggedInUser());
1623 else
1624 users_.insert(users_.begin(),
1625 user_manager::User::CreatePublicAccountUser(*it));
1626 UpdatePublicAccountDisplayName(*it);
1627 }
1628
1629 for (user_manager::UserList::iterator
1630 ui = users_.begin(),
1631 ue = users_.begin() + new_public_accounts.size();
1632 ui != ue;
1633 ++ui) {
1634 GetUserImageManager((*ui)->email())->LoadUserImage();
1635 }
1636
1637 // Remove data belonging to public accounts that are no longer found on the
1638 // user list.
1639 CleanUpPublicAccountNonCryptohomeData(old_public_accounts);
1640
1641 return true;
1642 }
1643
1644 void UserManagerImpl::UpdatePublicAccountDisplayName(
1645 const std::string& user_id) {
1646 std::string display_name;
1647
1648 if (device_local_account_policy_service_) {
1649 policy::DeviceLocalAccountPolicyBroker* broker =
1650 device_local_account_policy_service_->GetBrokerForUser(user_id);
1651 if (broker)
1652 display_name = broker->GetDisplayName();
1653 }
1654
1655 // Set or clear the display name.
1656 SaveUserDisplayName(user_id, base::UTF8ToUTF16(display_name));
1657 }
1658
1659 UserFlow* UserManagerImpl::GetCurrentUserFlow() const {
1660 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1661 if (!IsUserLoggedIn())
1662 return GetDefaultUserFlow();
1663 return GetUserFlow(GetLoggedInUser()->email());
1664 }
1665
1666 UserFlow* UserManagerImpl::GetUserFlow(const std::string& user_id) const {
1667 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1668 FlowMap::const_iterator it = specific_flows_.find(user_id);
1669 if (it != specific_flows_.end())
1670 return it->second;
1671 return GetDefaultUserFlow();
1672 }
1673
1674 void UserManagerImpl::SetUserFlow(const std::string& user_id, UserFlow* flow) {
1675 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1676 ResetUserFlow(user_id);
1677 specific_flows_[user_id] = flow;
1678 }
1679
1680 void UserManagerImpl::ResetUserFlow(const std::string& user_id) {
1681 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1682 FlowMap::iterator it = specific_flows_.find(user_id);
1683 if (it != specific_flows_.end()) {
1684 delete it->second;
1685 specific_flows_.erase(it);
1686 }
1687 }
1688
1689 bool UserManagerImpl::AreSupervisedUsersAllowed() const {
1690 bool supervised_users_allowed = false;
1691 cros_settings_->GetBoolean(kAccountsPrefSupervisedUsersEnabled,
1692 &supervised_users_allowed);
1693 return supervised_users_allowed;
1694 }
1695
1696 UserFlow* UserManagerImpl::GetDefaultUserFlow() const {
1697 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1698 if (!default_flow_.get())
1699 default_flow_.reset(new DefaultUserFlow());
1700 return default_flow_.get();
1701 }
1702
1703 void UserManagerImpl::NotifyUserListChanged() {
1704 content::NotificationService::current()->Notify(
1705 chrome::NOTIFICATION_USER_LIST_CHANGED,
1706 content::Source<UserManager>(this),
1707 content::NotificationService::NoDetails());
1708 }
1709
1710 void UserManagerImpl::NotifyActiveUserChanged(
1711 const user_manager::User* active_user) {
1712 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1713 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1714 session_state_observer_list_,
1715 ActiveUserChanged(active_user));
1716 }
1717
1718 void UserManagerImpl::NotifyUserAddedToSession(
1719 const user_manager::User* added_user) {
1720 UpdateNumberOfUsers();
1721 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1722 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1723 session_state_observer_list_,
1724 UserAddedToSession(added_user));
1725 }
1726
1727 void UserManagerImpl::NotifyActiveUserHashChanged(const std::string& hash) {
1728 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1729 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1730 session_state_observer_list_,
1731 ActiveUserHashChanged(hash));
1732 }
1733
1734 void UserManagerImpl::UpdateLoginState() {
1735 if (!LoginState::IsInitialized())
1736 return; // LoginState may not be intialized in tests.
1737 LoginState::LoggedInState logged_in_state;
1738 logged_in_state = active_user_ ? LoginState::LOGGED_IN_ACTIVE
1739 : LoginState::LOGGED_IN_NONE;
1740
1741 LoginState::LoggedInUserType login_user_type;
1742 if (logged_in_state == LoginState::LOGGED_IN_NONE)
1743 login_user_type = LoginState::LOGGED_IN_USER_NONE;
1744 else if (is_current_user_owner_)
1745 login_user_type = LoginState::LOGGED_IN_USER_OWNER;
1746 else if (active_user_->GetType() == user_manager::USER_TYPE_GUEST)
1747 login_user_type = LoginState::LOGGED_IN_USER_GUEST;
1748 else if (active_user_->GetType() == user_manager::USER_TYPE_RETAIL_MODE)
1749 login_user_type = LoginState::LOGGED_IN_USER_RETAIL_MODE;
1750 else if (active_user_->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT)
1751 login_user_type = LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT;
1752 else if (active_user_->GetType() == user_manager::USER_TYPE_SUPERVISED)
1753 login_user_type = LoginState::LOGGED_IN_USER_SUPERVISED;
1754 else if (active_user_->GetType() == user_manager::USER_TYPE_KIOSK_APP)
1755 login_user_type = LoginState::LOGGED_IN_USER_KIOSK_APP;
1756 else
1757 login_user_type = LoginState::LOGGED_IN_USER_REGULAR;
1758
1759 if (primary_user_) {
1760 LoginState::Get()->SetLoggedInStateAndPrimaryUser(
1761 logged_in_state, login_user_type, primary_user_->username_hash());
1762 } else {
1763 LoginState::Get()->SetLoggedInState(logged_in_state, login_user_type);
1764 }
1765 }
1766
1767 void UserManagerImpl::SetLRUUser(user_manager::User* user) {
1768 user_manager::UserList::iterator it =
1769 std::find(lru_logged_in_users_.begin(), lru_logged_in_users_.end(), user);
1770 if (it != lru_logged_in_users_.end())
1771 lru_logged_in_users_.erase(it);
1772 lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user);
1773 }
1774
1775 void UserManagerImpl::SendRegularUserLoginMetrics(const std::string& user_id) {
1776 // If this isn't the first time Chrome was run after the system booted,
1777 // assume that Chrome was restarted because a previous session ended.
1778 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1779 switches::kFirstExecAfterBoot)) {
1780 const std::string last_email =
1781 g_browser_process->local_state()->GetString(kLastLoggedInRegularUser);
1782 const base::TimeDelta time_to_login =
1783 base::TimeTicks::Now() - manager_creation_time_;
1784 if (!last_email.empty() && user_id != last_email &&
1785 time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) {
1786 UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay",
1787 time_to_login.InSeconds(), 0, kLogoutToLoginDelayMaxSec, 50);
1788 }
1789 }
1790 }
1791
1792 void UserManagerImpl::OnUserNotAllowed(const std::string& user_email) {
1793 LOG(ERROR) << "Shutdown session because a user is not allowed to be in the "
1794 "current session";
1795 chromeos::ShowMultiprofilesSessionAbortedDialog(user_email);
1796 }
1797
1798 void UserManagerImpl::UpdateUserAccountLocale(const std::string& user_id,
1799 const std::string& locale) {
1800 if (!locale.empty() &&
1801 locale != g_browser_process->GetApplicationLocale()) {
1802 BrowserThread::PostBlockingPoolTask(
1803 FROM_HERE,
1804 base::Bind(ResolveLocale, locale,
1805 base::Bind(&UserManagerImpl::DoUpdateAccountLocale,
1806 base::Unretained(this),
1807 user_id)));
1808 } else {
1809 DoUpdateAccountLocale(user_id, locale);
1810 }
1811 }
1812
1813 void UserManagerImpl::DoUpdateAccountLocale(
1814 const std::string& user_id,
1815 const std::string& resolved_locale) {
1816 if (user_manager::User* user = FindUserAndModify(user_id))
1817 user->SetAccountLocale(resolved_locale);
1818 }
1819
1820 void UserManagerImpl::UpdateNumberOfUsers() {
1821 size_t users = GetLoggedInUsers().size();
1822 if (users) {
1823 // Write the user number as UMA stat when a multi user session is possible.
1824 if ((users + GetUsersAdmittedForMultiProfile().size()) > 1)
1825 ash::MultiProfileUMA::RecordUserCount(users);
1826 }
1827
1828 base::debug::SetCrashKeyValue(crash_keys::kNumberOfUsers,
1829 base::StringPrintf("%" PRIuS, GetLoggedInUsers().size()));
1830 }
1831
1832 void UserManagerImpl::DeleteUser(user_manager::User* user) {
1833 const bool is_active_user = (user == active_user_);
1834 delete user;
1835 if (is_active_user)
1836 active_user_ = NULL;
1837 }
1838
1839 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/users/user_manager_impl.h ('k') | chrome/browser/chromeos/login/users/user_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698