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

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

Issue 444903002: [cros] user_manager component - move UserManagerBase and UserManager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: similarity 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" 5 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
6 6 #include "components/user_manager/user_manager.h"
7 #include <cstddef>
8 #include <set>
9
10 #include "ash/multi_profile_uma.h"
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/command_line.h"
14 #include "base/compiler_specific.h"
15 #include "base/format_macros.h"
16 #include "base/logging.h"
17 #include "base/metrics/histogram.h"
18 #include "base/prefs/pref_registry_simple.h"
19 #include "base/prefs/pref_service.h"
20 #include "base/prefs/scoped_user_pref_update.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/values.h"
25 #include "chrome/browser/browser_process.h"
26 #include "chrome/browser/chrome_notification_types.h"
27 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
28 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
29 #include "chrome/browser/chromeos/login/signin/auth_sync_observer.h"
30 #include "chrome/browser/chromeos/login/signin/auth_sync_observer_factory.h"
31 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h"
32 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
33 #include "chrome/browser/chromeos/login/users/remove_user_delegate.h"
34 #include "chrome/browser/chromeos/login/users/supervised_user_manager_impl.h"
35 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
36 #include "chrome/browser/chromeos/policy/device_local_account.h"
37 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog. h"
38 #include "chrome/browser/chromeos/profiles/profile_helper.h"
39 #include "chrome/browser/chromeos/session_length_limiter.h"
40 #include "chrome/browser/profiles/profile.h"
41 #include "chrome/browser/supervised_user/chromeos/manager_password_service_facto ry.h"
42 #include "chrome/browser/supervised_user/chromeos/supervised_user_password_servi ce_factory.h"
43 #include "chrome/common/chrome_constants.h"
44 #include "chrome/common/chrome_switches.h"
45 #include "chrome/common/crash_keys.h"
46 #include "chrome/common/pref_names.h"
47 #include "chrome/grit/theme_resources.h"
48 #include "chromeos/chromeos_switches.h"
49 #include "chromeos/login/user_names.h"
50 #include "chromeos/settings/cros_settings_names.h"
51 #include "components/session_manager/core/session_manager.h"
52 #include "components/user_manager/user_image/user_image.h"
53 #include "components/user_manager/user_type.h"
54 #include "content/public/browser/browser_thread.h"
55 #include "content/public/browser/notification_service.h"
56 #include "policy/policy_constants.h"
57 #include "ui/base/resource/resource_bundle.h"
58 #include "ui/wm/core/wm_core_switches.h"
59
60 using content::BrowserThread;
61 7
62 namespace chromeos { 8 namespace chromeos {
63 namespace {
64 9
65 // A vector pref of the the regular users known on this device, arranged in LRU 10 ChromeUserManager::ChromeUserManager() {
66 // order.
67 const char kRegularUsers[] = "LoggedInUsers";
68
69 // A vector pref of the public accounts defined on this device.
70 const char kPublicAccounts[] = "PublicAccounts";
71
72 // A string pref that gets set when a public account is removed but a user is
73 // currently logged into that account, requiring the account's data to be
74 // removed after logout.
75 const char kPublicAccountPendingDataRemoval[] =
76 "PublicAccountPendingDataRemoval";
77
78 } // namespace
79
80 // static
81 void UserManager::RegisterPrefs(PrefRegistrySimple* registry) {
82 UserManagerBase::RegisterPrefs(registry);
83
84 registry->RegisterListPref(kPublicAccounts);
85 registry->RegisterStringPref(kPublicAccountPendingDataRemoval, std::string());
86 SupervisedUserManager::RegisterPrefs(registry);
87 SessionLengthLimiter::RegisterPrefs(registry);
88 }
89
90 ChromeUserManager::ChromeUserManager()
91 : cros_settings_(CrosSettings::Get()),
92 device_local_account_policy_service_(NULL),
93 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
94 weak_factory_(this) {
95 UpdateNumberOfUsers();
96
97 // UserManager instance should be used only on UI thread.
98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
99 registrar_.Add(this,
100 chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
101 content::NotificationService::AllSources());
102 registrar_.Add(this,
103 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
104 content::NotificationService::AllSources());
105 registrar_.Add(this,
106 chrome::NOTIFICATION_PROFILE_CREATED,
107 content::NotificationService::AllSources());
108
109 // Since we're in ctor postpone any actions till this is fully created.
110 if (base::MessageLoop::current()) {
111 base::MessageLoop::current()->PostTask(
112 FROM_HERE,
113 base::Bind(&ChromeUserManager::RetrieveTrustedDevicePolicies,
114 weak_factory_.GetWeakPtr()));
115 }
116
117 local_accounts_subscription_ = cros_settings_->AddSettingsObserver(
118 kAccountsPrefDeviceLocalAccounts,
119 base::Bind(&ChromeUserManager::RetrieveTrustedDevicePolicies,
120 weak_factory_.GetWeakPtr()));
121 multi_profile_user_controller_.reset(
122 new MultiProfileUserController(this, GetLocalState()));
123
124 policy::BrowserPolicyConnectorChromeOS* connector =
125 g_browser_process->platform_part()->browser_policy_connector_chromeos();
126 avatar_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
127 cros_settings_,
128 connector->GetDeviceLocalAccountPolicyService(),
129 policy::key::kUserAvatarImage,
130 this));
131 avatar_policy_observer_->Init();
132
133 wallpaper_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
134 cros_settings_,
135 connector->GetDeviceLocalAccountPolicyService(),
136 policy::key::kWallpaperImage,
137 this));
138 wallpaper_policy_observer_->Init();
139 } 11 }
140 12
141 ChromeUserManager::~ChromeUserManager() { 13 ChromeUserManager::~ChromeUserManager() {
142 } 14 }
143 15
144 void ChromeUserManager::Shutdown() { 16 // static
145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 17 ChromeUserManager* ChromeUserManager::Get() {
146 UserManagerBase::Shutdown(); 18 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
147 19 return user_manager ? static_cast<ChromeUserManager*>(user_manager) : NULL;
148 local_accounts_subscription_.reset();
149
150 // Stop the session length limiter.
151 session_length_limiter_.reset();
152
153 if (device_local_account_policy_service_)
154 device_local_account_policy_service_->RemoveObserver(this);
155
156 for (UserImageManagerMap::iterator it = user_image_managers_.begin(),
157 ie = user_image_managers_.end();
158 it != ie;
159 ++it) {
160 it->second->Shutdown();
161 }
162 multi_profile_user_controller_.reset();
163 avatar_policy_observer_.reset();
164 wallpaper_policy_observer_.reset();
165 registrar_.RemoveAll();
166 }
167
168 MultiProfileUserController* ChromeUserManager::GetMultiProfileUserController() {
169 return multi_profile_user_controller_.get();
170 }
171
172 UserImageManager* ChromeUserManager::GetUserImageManager(
173 const std::string& user_id) {
174 UserImageManagerMap::iterator ui = user_image_managers_.find(user_id);
175 if (ui != user_image_managers_.end())
176 return ui->second.get();
177 linked_ptr<UserImageManagerImpl> mgr(new UserImageManagerImpl(user_id, this));
178 user_image_managers_[user_id] = mgr;
179 return mgr.get();
180 }
181
182 SupervisedUserManager* ChromeUserManager::GetSupervisedUserManager() {
183 return supervised_user_manager_.get();
184 }
185
186 user_manager::UserList ChromeUserManager::GetUsersAdmittedForMultiProfile()
187 const {
188 // Supervised users are not allowed to use multi-profiles.
189 if (GetLoggedInUsers().size() == 1 &&
190 GetPrimaryUser()->GetType() != user_manager::USER_TYPE_REGULAR) {
191 return user_manager::UserList();
192 }
193
194 user_manager::UserList result;
195 const user_manager::UserList& users = GetUsers();
196 for (user_manager::UserList::const_iterator it = users.begin();
197 it != users.end();
198 ++it) {
199 if ((*it)->GetType() == user_manager::USER_TYPE_REGULAR &&
200 !(*it)->is_logged_in()) {
201 MultiProfileUserController::UserAllowedInSessionReason check;
202 multi_profile_user_controller_->IsUserAllowedInSession((*it)->email(),
203 &check);
204 if (check ==
205 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS) {
206 return user_manager::UserList();
207 }
208
209 // Users with a policy that prevents them being added to a session will be
210 // shown in login UI but will be grayed out.
211 // Same applies to owner account (see http://crbug.com/385034).
212 if (check == MultiProfileUserController::ALLOWED ||
213 check == MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS ||
214 check == MultiProfileUserController::NOT_ALLOWED_OWNER_AS_SECONDARY) {
215 result.push_back(*it);
216 }
217 }
218 }
219
220 return result;
221 }
222
223 user_manager::UserList ChromeUserManager::GetUnlockUsers() const {
224 const user_manager::UserList& logged_in_users = GetLoggedInUsers();
225 if (logged_in_users.empty())
226 return user_manager::UserList();
227
228 user_manager::UserList unlock_users;
229 Profile* profile = ProfileHelper::Get()->GetProfileByUser(GetPrimaryUser());
230 std::string primary_behavior =
231 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
232
233 // Specific case: only one logged in user or
234 // primary user has primary-only multi-profile policy.
235 if (logged_in_users.size() == 1 ||
236 primary_behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
237 if (GetPrimaryUser()->can_lock())
238 unlock_users.push_back(primary_user_);
239 } else {
240 // Fill list of potential unlock users based on multi-profile policy state.
241 for (user_manager::UserList::const_iterator it = logged_in_users.begin();
242 it != logged_in_users.end();
243 ++it) {
244 user_manager::User* user = (*it);
245 Profile* profile = ProfileHelper::Get()->GetProfileByUser(user);
246 const std::string behavior =
247 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
248 if (behavior == MultiProfileUserController::kBehaviorUnrestricted &&
249 user->can_lock()) {
250 unlock_users.push_back(user);
251 } else if (behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
252 NOTREACHED()
253 << "Spotted primary-only multi-profile policy for non-primary user";
254 }
255 }
256 }
257
258 return unlock_users;
259 }
260
261 void ChromeUserManager::SessionStarted() {
262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
263 UserManagerBase::SessionStarted();
264
265 content::NotificationService::current()->Notify(
266 chrome::NOTIFICATION_SESSION_STARTED,
267 content::Source<UserManager>(this),
268 content::Details<const user_manager::User>(GetActiveUser()));
269 }
270
271 void ChromeUserManager::RemoveUserInternal(const std::string& user_email,
272 RemoveUserDelegate* delegate) {
273 CrosSettings* cros_settings = CrosSettings::Get();
274
275 const base::Closure& callback =
276 base::Bind(&ChromeUserManager::RemoveUserInternal,
277 weak_factory_.GetWeakPtr(),
278 user_email,
279 delegate);
280
281 // Ensure the value of owner email has been fetched.
282 if (CrosSettingsProvider::TRUSTED !=
283 cros_settings->PrepareTrustedValues(callback)) {
284 // Value of owner email is not fetched yet. RemoveUserInternal will be
285 // called again after fetch completion.
286 return;
287 }
288 std::string owner;
289 cros_settings->GetString(kDeviceOwner, &owner);
290 if (user_email == owner) {
291 // Owner is not allowed to be removed from the device.
292 return;
293 }
294 RemoveNonOwnerUserInternal(user_email, delegate);
295 }
296
297 void ChromeUserManager::SaveUserOAuthStatus(
298 const std::string& user_id,
299 user_manager::User::OAuthTokenStatus oauth_token_status) {
300 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
301 UserManagerBase::SaveUserOAuthStatus(user_id, oauth_token_status);
302
303 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(oauth_token_status);
304 }
305
306 void ChromeUserManager::SaveUserDisplayName(
307 const std::string& user_id,
308 const base::string16& display_name) {
309 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
310 UserManagerBase::SaveUserDisplayName(user_id, display_name);
311
312 // Do not update local state if data stored or cached outside the user's
313 // cryptohome is to be treated as ephemeral.
314 if (!IsUserNonCryptohomeDataEphemeral(user_id))
315 supervised_user_manager_->UpdateManagerName(user_id, display_name);
316 }
317
318 void ChromeUserManager::StopPolicyObserverForTesting() {
319 avatar_policy_observer_.reset();
320 wallpaper_policy_observer_.reset();
321 }
322
323 void ChromeUserManager::Observe(int type,
324 const content::NotificationSource& source,
325 const content::NotificationDetails& details) {
326 switch (type) {
327 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED:
328 if (!device_local_account_policy_service_) {
329 policy::BrowserPolicyConnectorChromeOS* connector =
330 g_browser_process->platform_part()
331 ->browser_policy_connector_chromeos();
332 device_local_account_policy_service_ =
333 connector->GetDeviceLocalAccountPolicyService();
334 if (device_local_account_policy_service_)
335 device_local_account_policy_service_->AddObserver(this);
336 }
337 RetrieveTrustedDevicePolicies();
338 UpdateOwnership();
339 break;
340 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: {
341 Profile* profile = content::Details<Profile>(details).ptr();
342 if (IsUserLoggedIn() && !IsLoggedInAsGuest() && !IsLoggedInAsKioskApp()) {
343 if (IsLoggedInAsSupervisedUser())
344 SupervisedUserPasswordServiceFactory::GetForProfile(profile);
345 if (IsLoggedInAsRegularUser())
346 ManagerPasswordServiceFactory::GetForProfile(profile);
347
348 if (!profile->IsOffTheRecord()) {
349 AuthSyncObserver* sync_observer =
350 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile);
351 sync_observer->StartObserving();
352 multi_profile_user_controller_->StartObserving(profile);
353 }
354 }
355 break;
356 }
357 case chrome::NOTIFICATION_PROFILE_CREATED: {
358 Profile* profile = content::Source<Profile>(source).ptr();
359 user_manager::User* user =
360 ProfileHelper::Get()->GetUserByProfile(profile);
361 if (user != NULL)
362 user->set_profile_is_created();
363
364 // If there is pending user switch, do it now.
365 if (!GetPendingUserSwitchID().empty()) {
366 // Call SwitchActiveUser async because otherwise it may cause
367 // ProfileManager::GetProfile before the profile gets registered
368 // in ProfileManager. It happens in case of sync profile load when
369 // NOTIFICATION_PROFILE_CREATED is called synchronously.
370 base::MessageLoop::current()->PostTask(
371 FROM_HERE,
372 base::Bind(&ChromeUserManager::SwitchActiveUser,
373 weak_factory_.GetWeakPtr(),
374 GetPendingUserSwitchID()));
375 SetPendingUserSwitchID(std::string());
376 }
377 break;
378 }
379 default:
380 NOTREACHED();
381 }
382 }
383
384 void ChromeUserManager::OnExternalDataSet(const std::string& policy,
385 const std::string& user_id) {
386 if (policy == policy::key::kUserAvatarImage)
387 GetUserImageManager(user_id)->OnExternalDataSet(policy);
388 else if (policy == policy::key::kWallpaperImage)
389 WallpaperManager::Get()->OnPolicySet(policy, user_id);
390 else
391 NOTREACHED();
392 }
393
394 void ChromeUserManager::OnExternalDataCleared(const std::string& policy,
395 const std::string& user_id) {
396 if (policy == policy::key::kUserAvatarImage)
397 GetUserImageManager(user_id)->OnExternalDataCleared(policy);
398 else if (policy == policy::key::kWallpaperImage)
399 WallpaperManager::Get()->OnPolicyCleared(policy, user_id);
400 else
401 NOTREACHED();
402 }
403
404 void ChromeUserManager::OnExternalDataFetched(const std::string& policy,
405 const std::string& user_id,
406 scoped_ptr<std::string> data) {
407 if (policy == policy::key::kUserAvatarImage)
408 GetUserImageManager(user_id)->OnExternalDataFetched(policy, data.Pass());
409 else if (policy == policy::key::kWallpaperImage)
410 WallpaperManager::Get()->OnPolicyFetched(policy, user_id, data.Pass());
411 else
412 NOTREACHED();
413 }
414
415 void ChromeUserManager::OnPolicyUpdated(const std::string& user_id) {
416 const user_manager::User* user = FindUser(user_id);
417 if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
418 return;
419 UpdatePublicAccountDisplayName(user_id);
420 }
421
422 void ChromeUserManager::OnDeviceLocalAccountsChanged() {
423 // No action needed here, changes to the list of device-local accounts get
424 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
425 }
426
427 bool ChromeUserManager::CanCurrentUserLock() const {
428 return UserManagerBase::CanCurrentUserLock() &&
429 GetCurrentUserFlow()->CanLockScreen();
430 }
431
432 bool ChromeUserManager::IsUserNonCryptohomeDataEphemeral(
433 const std::string& user_id) const {
434 // Data belonging to the obsolete public accounts whose data has not been
435 // removed yet is not ephemeral.
436 bool is_obsolete_public_account = IsPublicAccountMarkedForRemoval(user_id);
437
438 return !is_obsolete_public_account &&
439 UserManagerBase::IsUserNonCryptohomeDataEphemeral(user_id);
440 }
441
442 bool ChromeUserManager::AreEphemeralUsersEnabled() const {
443 policy::BrowserPolicyConnectorChromeOS* connector =
444 g_browser_process->platform_part()->browser_policy_connector_chromeos();
445 return GetEphemeralUsersEnabled() &&
446 (connector->IsEnterpriseManaged() || !GetOwnerEmail().empty());
447 }
448
449 const std::string& ChromeUserManager::GetApplicationLocale() const {
450 return g_browser_process->GetApplicationLocale();
451 }
452
453 PrefService* ChromeUserManager::GetLocalState() const {
454 return g_browser_process ? g_browser_process->local_state() : NULL;
455 }
456
457 bool ChromeUserManager::IsEnterpriseManaged() const {
458 policy::BrowserPolicyConnectorChromeOS* connector =
459 g_browser_process->platform_part()->browser_policy_connector_chromeos();
460 return connector->IsEnterpriseManaged();
461 }
462
463 void ChromeUserManager::LoadPublicAccounts(
464 std::set<std::string>* public_sessions_set) {
465 const base::ListValue* prefs_public_sessions =
466 GetLocalState()->GetList(kPublicAccounts);
467 std::vector<std::string> public_sessions;
468 ParseUserList(*prefs_public_sessions,
469 std::set<std::string>(),
470 &public_sessions,
471 public_sessions_set);
472 for (std::vector<std::string>::const_iterator it = public_sessions.begin();
473 it != public_sessions.end();
474 ++it) {
475 users_.push_back(user_manager::User::CreatePublicAccountUser(*it));
476 UpdatePublicAccountDisplayName(*it);
477 }
478 }
479
480 void ChromeUserManager::PerformPreUserListLoadingActions() {
481 // Clean up user list first. All code down the path should be synchronous,
482 // so that local state after transaction rollback is in consistent state.
483 // This process also should not trigger EnsureUsersLoaded again.
484 if (supervised_user_manager_->HasFailedUserCreationTransaction())
485 supervised_user_manager_->RollbackUserCreationTransaction();
486 }
487
488 void ChromeUserManager::PerformPostUserListLoadingActions() {
489 for (user_manager::UserList::iterator ui = users_.begin(), ue = users_.end();
490 ui != ue;
491 ++ui) {
492 GetUserImageManager((*ui)->email())->LoadUserImage();
493 }
494 }
495
496 void ChromeUserManager::PerformPostUserLoggedInActions(bool browser_restart) {
497 // Initialize the session length limiter and start it only if
498 // session limit is defined by the policy.
499 session_length_limiter_.reset(
500 new SessionLengthLimiter(NULL, browser_restart));
501 }
502
503 bool ChromeUserManager::IsDemoApp(const std::string& user_id) const {
504 return DemoAppLauncher::IsDemoAppSession(user_id);
505 }
506
507 bool ChromeUserManager::IsKioskApp(const std::string& user_id) const {
508 policy::DeviceLocalAccount::Type device_local_account_type;
509 return policy::IsDeviceLocalAccountUser(user_id,
510 &device_local_account_type) &&
511 device_local_account_type ==
512 policy::DeviceLocalAccount::TYPE_KIOSK_APP;
513 }
514
515 bool ChromeUserManager::IsPublicAccountMarkedForRemoval(
516 const std::string& user_id) const {
517 return user_id ==
518 GetLocalState()->GetString(kPublicAccountPendingDataRemoval);
519 }
520
521 void ChromeUserManager::RetrieveTrustedDevicePolicies() {
522 // Local state may not be initialized in unit_tests.
523 if (!GetLocalState())
524 return;
525
526 SetEphemeralUsersEnabled(false);
527 SetOwnerEmail(std::string());
528
529 // Schedule a callback if device policy has not yet been verified.
530 if (CrosSettingsProvider::TRUSTED !=
531 cros_settings_->PrepareTrustedValues(
532 base::Bind(&ChromeUserManager::RetrieveTrustedDevicePolicies,
533 weak_factory_.GetWeakPtr()))) {
534 return;
535 }
536
537 bool ephemeral_users_enabled = false;
538 cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
539 &ephemeral_users_enabled);
540 SetEphemeralUsersEnabled(ephemeral_users_enabled);
541
542 std::string owner_email;
543 cros_settings_->GetString(kDeviceOwner, &owner_email);
544 SetOwnerEmail(owner_email);
545
546 EnsureUsersLoaded();
547
548 bool changed = UpdateAndCleanUpPublicAccounts(
549 policy::GetDeviceLocalAccounts(cros_settings_));
550
551 // If ephemeral users are enabled and we are on the login screen, take this
552 // opportunity to clean up by removing all regular users except the owner.
553 if (GetEphemeralUsersEnabled() && !IsUserLoggedIn()) {
554 ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
555 prefs_users_update->Clear();
556 for (user_manager::UserList::iterator it = users_.begin();
557 it != users_.end();) {
558 const std::string user_email = (*it)->email();
559 if ((*it)->GetType() == user_manager::USER_TYPE_REGULAR &&
560 user_email != GetOwnerEmail()) {
561 RemoveNonCryptohomeData(user_email);
562 DeleteUser(*it);
563 it = users_.erase(it);
564 changed = true;
565 } else {
566 if ((*it)->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
567 prefs_users_update->Append(new base::StringValue(user_email));
568 ++it;
569 }
570 }
571 }
572
573 if (changed)
574 NotifyUserListChanged();
575 }
576
577 void ChromeUserManager::GuestUserLoggedIn() {
578 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
579 UserManagerBase::GuestUserLoggedIn();
580
581 // TODO(nkostylev): Add support for passing guest session cryptohome
582 // mount point. Legacy (--login-profile) value will be used for now.
583 // http://crosbug.com/230859
584 active_user_->SetStubImage(
585 user_manager::UserImage(
586 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
587 IDR_PROFILE_PICTURE_LOADING)),
588 user_manager::User::USER_IMAGE_INVALID,
589 false);
590
591 // Initializes wallpaper after active_user_ is set.
592 WallpaperManager::Get()->SetUserWallpaperNow(chromeos::login::kGuestUserName);
593 }
594
595 void ChromeUserManager::RegularUserLoggedIn(const std::string& user_id) {
596 UserManagerBase::RegularUserLoggedIn(user_id);
597
598 if (IsCurrentUserNew())
599 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
600
601 GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), false);
602
603 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
604
605 // Make sure that new data is persisted to Local State.
606 GetLocalState()->CommitPendingWrite();
607 }
608
609 void ChromeUserManager::RegularUserLoggedInAsEphemeral(
610 const std::string& user_id) {
611 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
612 UserManagerBase::RegularUserLoggedInAsEphemeral(user_id);
613
614 GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), false);
615 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
616 }
617
618 void ChromeUserManager::SupervisedUserLoggedIn(const std::string& user_id) {
619 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
620
621 // Remove the user from the user list.
622 active_user_ = RemoveRegularOrSupervisedUserFromList(user_id);
623
624 // If the user was not found on the user list, create a new user.
625 if (!GetActiveUser()) {
626 SetIsCurrentUserNew(true);
627 active_user_ = user_manager::User::CreateSupervisedUser(user_id);
628 // Leaving OAuth token status at the default state = unknown.
629 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
630 } else {
631 if (supervised_user_manager_->CheckForFirstRun(user_id)) {
632 SetIsCurrentUserNew(true);
633 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
634 } else {
635 SetIsCurrentUserNew(false);
636 }
637 }
638
639 // Add the user to the front of the user list.
640 ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
641 prefs_users_update->Insert(0, new base::StringValue(user_id));
642 users_.insert(users_.begin(), active_user_);
643
644 // Now that user is in the list, save display name.
645 if (IsCurrentUserNew()) {
646 SaveUserDisplayName(GetActiveUser()->email(),
647 GetActiveUser()->GetDisplayName());
648 }
649
650 GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), true);
651 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
652
653 // Make sure that new data is persisted to Local State.
654 GetLocalState()->CommitPendingWrite();
655 }
656
657 void ChromeUserManager::PublicAccountUserLoggedIn(user_manager::User* user) {
658 SetIsCurrentUserNew(true);
659 active_user_ = user;
660
661 // The UserImageManager chooses a random avatar picture when a user logs in
662 // for the first time. Tell the UserImageManager that this user is not new to
663 // prevent the avatar from getting changed.
664 GetUserImageManager(user->email())->UserLoggedIn(false, true);
665 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
666 }
667
668 void ChromeUserManager::KioskAppLoggedIn(const std::string& app_id) {
669 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
670 policy::DeviceLocalAccount::Type device_local_account_type;
671 DCHECK(policy::IsDeviceLocalAccountUser(app_id, &device_local_account_type));
672 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
673 device_local_account_type);
674
675 active_user_ = user_manager::User::CreateKioskAppUser(app_id);
676 active_user_->SetStubImage(
677 user_manager::UserImage(
678 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
679 IDR_PROFILE_PICTURE_LOADING)),
680 user_manager::User::USER_IMAGE_INVALID,
681 false);
682
683 WallpaperManager::Get()->SetUserWallpaperNow(app_id);
684
685 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
686 // the kiosk_app_id in these objects, removing the need to re-parse the
687 // device-local account list here to extract the kiosk_app_id.
688 const std::vector<policy::DeviceLocalAccount> device_local_accounts =
689 policy::GetDeviceLocalAccounts(cros_settings_);
690 const policy::DeviceLocalAccount* account = NULL;
691 for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
692 device_local_accounts.begin();
693 it != device_local_accounts.end();
694 ++it) {
695 if (it->user_id == app_id) {
696 account = &*it;
697 break;
698 }
699 }
700 std::string kiosk_app_id;
701 if (account) {
702 kiosk_app_id = account->kiosk_app_id;
703 } else {
704 LOG(ERROR) << "Logged into nonexistent kiosk-app account: " << app_id;
705 NOTREACHED();
706 }
707
708 CommandLine* command_line = CommandLine::ForCurrentProcess();
709 command_line->AppendSwitch(::switches::kForceAppMode);
710 command_line->AppendSwitchASCII(::switches::kAppId, kiosk_app_id);
711
712 // Disable window animation since kiosk app runs in a single full screen
713 // window and window animation causes start-up janks.
714 command_line->AppendSwitch(wm::switches::kWindowAnimationsDisabled);
715 }
716
717 void ChromeUserManager::DemoAccountLoggedIn() {
718 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
719 active_user_ =
720 user_manager::User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName);
721 active_user_->SetStubImage(
722 user_manager::UserImage(
723 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
724 IDR_PROFILE_PICTURE_LOADING)),
725 user_manager::User::USER_IMAGE_INVALID,
726 false);
727 WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName);
728
729 CommandLine* command_line = CommandLine::ForCurrentProcess();
730 command_line->AppendSwitch(::switches::kForceAppMode);
731 command_line->AppendSwitchASCII(::switches::kAppId,
732 DemoAppLauncher::kDemoAppId);
733
734 // Disable window animation since the demo app runs in a single full screen
735 // window and window animation causes start-up janks.
736 CommandLine::ForCurrentProcess()->AppendSwitch(
737 wm::switches::kWindowAnimationsDisabled);
738 }
739
740 void ChromeUserManager::RetailModeUserLoggedIn() {
741 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
742 SetIsCurrentUserNew(true);
743 active_user_ = user_manager::User::CreateRetailModeUser();
744 GetUserImageManager(chromeos::login::kRetailModeUserName)
745 ->UserLoggedIn(IsCurrentUserNew(), true);
746 WallpaperManager::Get()->SetUserWallpaperNow(
747 chromeos::login::kRetailModeUserName);
748 }
749
750 void ChromeUserManager::NotifyOnLogin() {
751 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
752
753 UserSessionManager::OverrideHomedir();
754 UpdateNumberOfUsers();
755
756 UserManagerBase::NotifyOnLogin();
757
758 // TODO(nkostylev): Deprecate this notification in favor of
759 // ActiveUserChanged() observer call.
760 content::NotificationService::current()->Notify(
761 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
762 content::Source<UserManager>(this),
763 content::Details<const user_manager::User>(GetActiveUser()));
764
765 UserSessionManager::GetInstance()->PerformPostUserLoggedInActions();
766 }
767
768 void ChromeUserManager::UpdateOwnership() {
769 bool is_owner = DeviceSettingsService::Get()->HasPrivateOwnerKey();
770 VLOG(1) << "Current user " << (is_owner ? "is owner" : "is not owner");
771
772 SetCurrentUserIsOwner(is_owner);
773 }
774
775 void ChromeUserManager::RemoveNonCryptohomeData(const std::string& user_id) {
776 UserManagerBase::RemoveNonCryptohomeData(user_id);
777
778 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id);
779 GetUserImageManager(user_id)->DeleteUserImage();
780
781 supervised_user_manager_->RemoveNonCryptohomeData(user_id);
782
783 multi_profile_user_controller_->RemoveCachedValues(user_id);
784 }
785
786 void ChromeUserManager::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
787 PrefService* local_state = GetLocalState();
788 const std::string public_account_pending_data_removal =
789 local_state->GetString(kPublicAccountPendingDataRemoval);
790 if (public_account_pending_data_removal.empty() ||
791 (IsUserLoggedIn() &&
792 public_account_pending_data_removal == GetActiveUser()->email())) {
793 return;
794 }
795
796 RemoveNonCryptohomeData(public_account_pending_data_removal);
797 local_state->ClearPref(kPublicAccountPendingDataRemoval);
798 }
799
800 void ChromeUserManager::CleanUpPublicAccountNonCryptohomeData(
801 const std::vector<std::string>& old_public_accounts) {
802 std::set<std::string> users;
803 for (user_manager::UserList::const_iterator it = users_.begin();
804 it != users_.end();
805 ++it)
806 users.insert((*it)->email());
807
808 // If the user is logged into a public account that has been removed from the
809 // user list, mark the account's data as pending removal after logout.
810 if (IsLoggedInAsPublicAccount()) {
811 const std::string active_user_id = GetActiveUser()->email();
812 if (users.find(active_user_id) == users.end()) {
813 GetLocalState()->SetString(kPublicAccountPendingDataRemoval,
814 active_user_id);
815 users.insert(active_user_id);
816 }
817 }
818
819 // Remove the data belonging to any other public accounts that are no longer
820 // found on the user list.
821 for (std::vector<std::string>::const_iterator it =
822 old_public_accounts.begin();
823 it != old_public_accounts.end();
824 ++it) {
825 if (users.find(*it) == users.end())
826 RemoveNonCryptohomeData(*it);
827 }
828 }
829
830 bool ChromeUserManager::UpdateAndCleanUpPublicAccounts(
831 const std::vector<policy::DeviceLocalAccount>& device_local_accounts) {
832 // Try to remove any public account data marked as pending removal.
833 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
834
835 // Get the current list of public accounts.
836 std::vector<std::string> old_public_accounts;
837 for (user_manager::UserList::const_iterator it = users_.begin();
838 it != users_.end();
839 ++it) {
840 if ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT)
841 old_public_accounts.push_back((*it)->email());
842 }
843
844 // Get the new list of public accounts from policy.
845 std::vector<std::string> new_public_accounts;
846 for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
847 device_local_accounts.begin();
848 it != device_local_accounts.end();
849 ++it) {
850 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
851 // standard login framework: http://crbug.com/234694
852 if (it->type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
853 new_public_accounts.push_back(it->user_id);
854 }
855
856 // If the list of public accounts has not changed, return.
857 if (new_public_accounts.size() == old_public_accounts.size()) {
858 bool changed = false;
859 for (size_t i = 0; i < new_public_accounts.size(); ++i) {
860 if (new_public_accounts[i] != old_public_accounts[i]) {
861 changed = true;
862 break;
863 }
864 }
865 if (!changed)
866 return false;
867 }
868
869 // Persist the new list of public accounts in a pref.
870 ListPrefUpdate prefs_public_accounts_update(GetLocalState(), kPublicAccounts);
871 prefs_public_accounts_update->Clear();
872 for (std::vector<std::string>::const_iterator it =
873 new_public_accounts.begin();
874 it != new_public_accounts.end();
875 ++it) {
876 prefs_public_accounts_update->AppendString(*it);
877 }
878
879 // Remove the old public accounts from the user list.
880 for (user_manager::UserList::iterator it = users_.begin();
881 it != users_.end();) {
882 if ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
883 if (*it != GetLoggedInUser())
884 DeleteUser(*it);
885 it = users_.erase(it);
886 } else {
887 ++it;
888 }
889 }
890
891 // Add the new public accounts to the front of the user list.
892 for (std::vector<std::string>::const_reverse_iterator it =
893 new_public_accounts.rbegin();
894 it != new_public_accounts.rend();
895 ++it) {
896 if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email())
897 users_.insert(users_.begin(), GetLoggedInUser());
898 else
899 users_.insert(users_.begin(),
900 user_manager::User::CreatePublicAccountUser(*it));
901 UpdatePublicAccountDisplayName(*it);
902 }
903
904 for (user_manager::UserList::iterator
905 ui = users_.begin(),
906 ue = users_.begin() + new_public_accounts.size();
907 ui != ue;
908 ++ui) {
909 GetUserImageManager((*ui)->email())->LoadUserImage();
910 }
911
912 // Remove data belonging to public accounts that are no longer found on the
913 // user list.
914 CleanUpPublicAccountNonCryptohomeData(old_public_accounts);
915
916 return true;
917 }
918
919 void ChromeUserManager::UpdatePublicAccountDisplayName(
920 const std::string& user_id) {
921 std::string display_name;
922
923 if (device_local_account_policy_service_) {
924 policy::DeviceLocalAccountPolicyBroker* broker =
925 device_local_account_policy_service_->GetBrokerForUser(user_id);
926 if (broker)
927 display_name = broker->GetDisplayName();
928 }
929
930 // Set or clear the display name.
931 SaveUserDisplayName(user_id, base::UTF8ToUTF16(display_name));
932 }
933
934 UserFlow* ChromeUserManager::GetCurrentUserFlow() const {
935 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
936 if (!IsUserLoggedIn())
937 return GetDefaultUserFlow();
938 return GetUserFlow(GetLoggedInUser()->email());
939 }
940
941 UserFlow* ChromeUserManager::GetUserFlow(const std::string& user_id) const {
942 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
943 FlowMap::const_iterator it = specific_flows_.find(user_id);
944 if (it != specific_flows_.end())
945 return it->second;
946 return GetDefaultUserFlow();
947 }
948
949 void ChromeUserManager::SetUserFlow(const std::string& user_id,
950 UserFlow* flow) {
951 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
952 ResetUserFlow(user_id);
953 specific_flows_[user_id] = flow;
954 }
955
956 void ChromeUserManager::ResetUserFlow(const std::string& user_id) {
957 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
958 FlowMap::iterator it = specific_flows_.find(user_id);
959 if (it != specific_flows_.end()) {
960 delete it->second;
961 specific_flows_.erase(it);
962 }
963 }
964
965 bool ChromeUserManager::AreSupervisedUsersAllowed() const {
966 bool supervised_users_allowed = false;
967 cros_settings_->GetBoolean(kAccountsPrefSupervisedUsersEnabled,
968 &supervised_users_allowed);
969 return supervised_users_allowed;
970 }
971
972 UserFlow* ChromeUserManager::GetDefaultUserFlow() const {
973 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
974 if (!default_flow_.get())
975 default_flow_.reset(new DefaultUserFlow());
976 return default_flow_.get();
977 }
978
979 void ChromeUserManager::NotifyUserListChanged() {
980 content::NotificationService::current()->Notify(
981 chrome::NOTIFICATION_USER_LIST_CHANGED,
982 content::Source<UserManager>(this),
983 content::NotificationService::NoDetails());
984 }
985
986 void ChromeUserManager::NotifyUserAddedToSession(
987 const user_manager::User* added_user,
988 bool user_switch_pending) {
989 if (user_switch_pending)
990 SetPendingUserSwitchID(added_user->email());
991
992 UpdateNumberOfUsers();
993 UserManagerBase::NotifyUserAddedToSession(added_user, user_switch_pending);
994 }
995
996 void ChromeUserManager::OnUserNotAllowed(const std::string& user_email) {
997 LOG(ERROR) << "Shutdown session because a user is not allowed to be in the "
998 "current session";
999 chromeos::ShowMultiprofilesSessionAbortedDialog(user_email);
1000 }
1001
1002 void ChromeUserManager::UpdateNumberOfUsers() {
1003 size_t users = GetLoggedInUsers().size();
1004 if (users) {
1005 // Write the user number as UMA stat when a multi user session is possible.
1006 if ((users + GetUsersAdmittedForMultiProfile().size()) > 1)
1007 ash::MultiProfileUMA::RecordUserCount(users);
1008 }
1009
1010 base::debug::SetCrashKeyValue(
1011 crash_keys::kNumberOfUsers,
1012 base::StringPrintf("%" PRIuS, GetLoggedInUsers().size()));
1013 } 20 }
1014 21
1015 } // namespace chromeos 22 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698