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

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

Powered by Google App Engine
This is Rietveld 408576698