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