| OLD | NEW |
| 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/user_manager_impl.h" | 5 #include "chrome/browser/chromeos/login/users/user_manager_impl.h" |
| 6 | 6 |
| 7 #include <cstddef> | 7 #include <cstddef> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "ash/multi_profile_uma.h" | 10 #include "ash/multi_profile_uma.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 #include "chrome/browser/browser_process.h" | 31 #include "chrome/browser/browser_process.h" |
| 32 #include "chrome/browser/chrome_notification_types.h" | 32 #include "chrome/browser/chrome_notification_types.h" |
| 33 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h" | 33 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h" |
| 34 #include "chrome/browser/chromeos/login/session/user_session_manager.h" | 34 #include "chrome/browser/chromeos/login/session/user_session_manager.h" |
| 35 #include "chrome/browser/chromeos/login/signin/auth_sync_observer.h" | 35 #include "chrome/browser/chromeos/login/signin/auth_sync_observer.h" |
| 36 #include "chrome/browser/chromeos/login/signin/auth_sync_observer_factory.h" | 36 #include "chrome/browser/chromeos/login/signin/auth_sync_observer_factory.h" |
| 37 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h" | 37 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h" |
| 38 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h" | 38 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h" |
| 39 #include "chrome/browser/chromeos/login/users/remove_user_delegate.h" | 39 #include "chrome/browser/chromeos/login/users/remove_user_delegate.h" |
| 40 #include "chrome/browser/chromeos/login/users/supervised_user_manager_impl.h" | 40 #include "chrome/browser/chromeos/login/users/supervised_user_manager_impl.h" |
| 41 #include "chrome/browser/chromeos/login/wizard_controller.h" | |
| 42 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" | 41 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" |
| 43 #include "chrome/browser/chromeos/policy/device_local_account.h" | 42 #include "chrome/browser/chromeos/policy/device_local_account.h" |
| 44 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog.
h" | 43 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog.
h" |
| 45 #include "chrome/browser/chromeos/profiles/profile_helper.h" | 44 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| 46 #include "chrome/browser/chromeos/session_length_limiter.h" | 45 #include "chrome/browser/chromeos/session_length_limiter.h" |
| 47 #include "chrome/browser/profiles/profile.h" | 46 #include "chrome/browser/profiles/profile.h" |
| 48 #include "chrome/browser/profiles/profile_manager.h" | |
| 49 #include "chrome/browser/supervised_user/chromeos/manager_password_service_facto
ry.h" | 47 #include "chrome/browser/supervised_user/chromeos/manager_password_service_facto
ry.h" |
| 50 #include "chrome/browser/supervised_user/chromeos/supervised_user_password_servi
ce_factory.h" | 48 #include "chrome/browser/supervised_user/chromeos/supervised_user_password_servi
ce_factory.h" |
| 51 #include "chrome/common/chrome_constants.h" | 49 #include "chrome/common/chrome_constants.h" |
| 52 #include "chrome/common/chrome_paths.h" | 50 #include "chrome/common/chrome_paths.h" |
| 53 #include "chrome/common/chrome_switches.h" | 51 #include "chrome/common/chrome_switches.h" |
| 54 #include "chrome/common/crash_keys.h" | 52 #include "chrome/common/crash_keys.h" |
| 55 #include "chrome/common/pref_names.h" | 53 #include "chrome/common/pref_names.h" |
| 56 #include "chromeos/chromeos_switches.h" | 54 #include "chromeos/chromeos_switches.h" |
| 57 #include "chromeos/cryptohome/async_method_caller.h" | 55 #include "chromeos/cryptohome/async_method_caller.h" |
| 58 #include "chromeos/dbus/dbus_thread_manager.h" | 56 #include "chromeos/dbus/dbus_thread_manager.h" |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 SessionLengthLimiter::RegisterPrefs(registry); | 175 SessionLengthLimiter::RegisterPrefs(registry); |
| 178 } | 176 } |
| 179 | 177 |
| 180 UserManagerImpl::UserManagerImpl() | 178 UserManagerImpl::UserManagerImpl() |
| 181 : cros_settings_(CrosSettings::Get()), | 179 : cros_settings_(CrosSettings::Get()), |
| 182 device_local_account_policy_service_(NULL), | 180 device_local_account_policy_service_(NULL), |
| 183 user_loading_stage_(STAGE_NOT_LOADED), | 181 user_loading_stage_(STAGE_NOT_LOADED), |
| 184 active_user_(NULL), | 182 active_user_(NULL), |
| 185 primary_user_(NULL), | 183 primary_user_(NULL), |
| 186 session_started_(false), | 184 session_started_(false), |
| 187 user_sessions_restored_(false), | |
| 188 is_current_user_owner_(false), | 185 is_current_user_owner_(false), |
| 189 is_current_user_new_(false), | 186 is_current_user_new_(false), |
| 190 is_current_user_ephemeral_regular_user_(false), | 187 is_current_user_ephemeral_regular_user_(false), |
| 191 ephemeral_users_enabled_(false), | 188 ephemeral_users_enabled_(false), |
| 192 supervised_user_manager_(new SupervisedUserManagerImpl(this)), | 189 supervised_user_manager_(new SupervisedUserManagerImpl(this)), |
| 193 manager_creation_time_(base::TimeTicks::Now()) { | 190 manager_creation_time_(base::TimeTicks::Now()) { |
| 194 UpdateNumberOfUsers(); | 191 UpdateNumberOfUsers(); |
| 195 // UserManager instance should be used only on UI thread. | 192 // UserManager instance should be used only on UI thread. |
| 196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 197 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, | 194 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 user->set_is_active(true); | 483 user->set_is_active(true); |
| 487 active_user_ = user; | 484 active_user_ = user; |
| 488 | 485 |
| 489 // Move the user to the front. | 486 // Move the user to the front. |
| 490 SetLRUUser(active_user_); | 487 SetLRUUser(active_user_); |
| 491 | 488 |
| 492 NotifyActiveUserHashChanged(active_user_->username_hash()); | 489 NotifyActiveUserHashChanged(active_user_->username_hash()); |
| 493 NotifyActiveUserChanged(active_user_); | 490 NotifyActiveUserChanged(active_user_); |
| 494 } | 491 } |
| 495 | 492 |
| 496 void UserManagerImpl::RestoreActiveSessions() { | |
| 497 DBusThreadManager::Get()->GetSessionManagerClient()->RetrieveActiveSessions( | |
| 498 base::Bind(&UserManagerImpl::OnRestoreActiveSessions, | |
| 499 base::Unretained(this))); | |
| 500 } | |
| 501 | |
| 502 void UserManagerImpl::SessionStarted() { | 493 void UserManagerImpl::SessionStarted() { |
| 503 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 494 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 504 session_started_ = true; | 495 session_started_ = true; |
| 505 UpdateLoginState(); | 496 UpdateLoginState(); |
| 506 content::NotificationService::current()->Notify( | 497 content::NotificationService::current()->Notify( |
| 507 chrome::NOTIFICATION_SESSION_STARTED, | 498 chrome::NOTIFICATION_SESSION_STARTED, |
| 508 content::Source<UserManager>(this), | 499 content::Source<UserManager>(this), |
| 509 content::Details<const User>(active_user_)); | 500 content::Details<const User>(active_user_)); |
| 510 if (is_current_user_new_) { | 501 if (is_current_user_new_) { |
| 511 // Make sure that the new user's data is persisted to Local State. | 502 // Make sure that the new user's data is persisted to Local State. |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 946 bool UserManagerImpl::IsLoggedInAsStub() const { | 937 bool UserManagerImpl::IsLoggedInAsStub() const { |
| 947 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 938 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 948 return IsUserLoggedIn() && active_user_->email() == login::kStubUser; | 939 return IsUserLoggedIn() && active_user_->email() == login::kStubUser; |
| 949 } | 940 } |
| 950 | 941 |
| 951 bool UserManagerImpl::IsSessionStarted() const { | 942 bool UserManagerImpl::IsSessionStarted() const { |
| 952 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 943 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 953 return session_started_; | 944 return session_started_; |
| 954 } | 945 } |
| 955 | 946 |
| 956 bool UserManagerImpl::UserSessionsRestored() const { | |
| 957 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 958 return user_sessions_restored_; | |
| 959 } | |
| 960 | |
| 961 bool UserManagerImpl::IsUserNonCryptohomeDataEphemeral( | 947 bool UserManagerImpl::IsUserNonCryptohomeDataEphemeral( |
| 962 const std::string& user_id) const { | 948 const std::string& user_id) const { |
| 963 // Data belonging to the guest, retail mode and stub users is always | 949 // Data belonging to the guest, retail mode and stub users is always |
| 964 // ephemeral. | 950 // ephemeral. |
| 965 if (user_id == login::kGuestUserName || | 951 if (user_id == login::kGuestUserName || |
| 966 user_id == login::kRetailModeUserName || user_id == login::kStubUser) { | 952 user_id == login::kRetailModeUserName || user_id == login::kStubUser) { |
| 967 return true; | 953 return true; |
| 968 } | 954 } |
| 969 | 955 |
| 970 // Data belonging to the owner, anyone found on the user list and obsolete | 956 // Data belonging to the owner, anyone found on the user list and obsolete |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1001 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1016 session_state_observer_list_.RemoveObserver(obs); | 1002 session_state_observer_list_.RemoveObserver(obs); |
| 1017 } | 1003 } |
| 1018 | 1004 |
| 1019 void UserManagerImpl::NotifyLocalStateChanged() { | 1005 void UserManagerImpl::NotifyLocalStateChanged() { |
| 1020 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1006 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1021 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_, | 1007 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_, |
| 1022 LocalStateChanged(this)); | 1008 LocalStateChanged(this)); |
| 1023 } | 1009 } |
| 1024 | 1010 |
| 1025 void UserManagerImpl::OnProfilePrepared(Profile* profile) { | |
| 1026 LoginUtils::Get()->DoBrowserLaunch(profile, | |
| 1027 NULL); // host_, not needed here | |
| 1028 | |
| 1029 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) { | |
| 1030 // Did not log in (we crashed or are debugging), need to restore Sync. | |
| 1031 // TODO(nkostylev): Make sure that OAuth state is restored correctly for all | |
| 1032 // users once it is fully multi-profile aware. http://crbug.com/238987 | |
| 1033 // For now if we have other user pending sessions they'll override OAuth | |
| 1034 // session restore for previous users. | |
| 1035 UserSessionManager::GetInstance()->RestoreAuthenticationSession(profile); | |
| 1036 } | |
| 1037 | |
| 1038 // Restore other user sessions if any. | |
| 1039 RestorePendingUserSessions(); | |
| 1040 } | |
| 1041 | |
| 1042 void UserManagerImpl::EnsureUsersLoaded() { | 1011 void UserManagerImpl::EnsureUsersLoaded() { |
| 1043 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1012 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1044 if (!g_browser_process || !g_browser_process->local_state()) | 1013 if (!g_browser_process || !g_browser_process->local_state()) |
| 1045 return; | 1014 return; |
| 1046 | 1015 |
| 1047 if (user_loading_stage_ != STAGE_NOT_LOADED) | 1016 if (user_loading_stage_ != STAGE_NOT_LOADED) |
| 1048 return; | 1017 return; |
| 1049 user_loading_stage_ = STAGE_LOADING; | 1018 user_loading_stage_ = STAGE_LOADING; |
| 1050 // Clean up user list first. All code down the path should be synchronous, | 1019 // Clean up user list first. All code down the path should be synchronous, |
| 1051 // so that local state after transaction rollback is in consistent state. | 1020 // so that local state after transaction rollback is in consistent state. |
| (...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1692 UserAddedToSession(added_user)); | 1661 UserAddedToSession(added_user)); |
| 1693 } | 1662 } |
| 1694 | 1663 |
| 1695 void UserManagerImpl::NotifyActiveUserHashChanged(const std::string& hash) { | 1664 void UserManagerImpl::NotifyActiveUserHashChanged(const std::string& hash) { |
| 1696 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1665 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1697 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver, | 1666 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver, |
| 1698 session_state_observer_list_, | 1667 session_state_observer_list_, |
| 1699 ActiveUserHashChanged(hash)); | 1668 ActiveUserHashChanged(hash)); |
| 1700 } | 1669 } |
| 1701 | 1670 |
| 1702 void UserManagerImpl::NotifyPendingUserSessionsRestoreFinished() { | |
| 1703 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 1704 user_sessions_restored_ = true; | |
| 1705 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver, | |
| 1706 session_state_observer_list_, | |
| 1707 PendingUserSessionsRestoreFinished()); | |
| 1708 } | |
| 1709 | |
| 1710 void UserManagerImpl::UpdateLoginState() { | 1671 void UserManagerImpl::UpdateLoginState() { |
| 1711 if (!LoginState::IsInitialized()) | 1672 if (!LoginState::IsInitialized()) |
| 1712 return; // LoginState may not be intialized in tests. | 1673 return; // LoginState may not be intialized in tests. |
| 1713 LoginState::LoggedInState logged_in_state; | 1674 LoginState::LoggedInState logged_in_state; |
| 1714 logged_in_state = active_user_ ? LoginState::LOGGED_IN_ACTIVE | 1675 logged_in_state = active_user_ ? LoginState::LOGGED_IN_ACTIVE |
| 1715 : LoginState::LOGGED_IN_NONE; | 1676 : LoginState::LOGGED_IN_NONE; |
| 1716 | 1677 |
| 1717 LoginState::LoggedInUserType login_user_type; | 1678 LoginState::LoggedInUserType login_user_type; |
| 1718 if (logged_in_state == LoginState::LOGGED_IN_NONE) | 1679 if (logged_in_state == LoginState::LOGGED_IN_NONE) |
| 1719 login_user_type = LoginState::LOGGED_IN_USER_NONE; | 1680 login_user_type = LoginState::LOGGED_IN_USER_NONE; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1742 | 1703 |
| 1743 void UserManagerImpl::SetLRUUser(User* user) { | 1704 void UserManagerImpl::SetLRUUser(User* user) { |
| 1744 UserList::iterator it = std::find(lru_logged_in_users_.begin(), | 1705 UserList::iterator it = std::find(lru_logged_in_users_.begin(), |
| 1745 lru_logged_in_users_.end(), | 1706 lru_logged_in_users_.end(), |
| 1746 user); | 1707 user); |
| 1747 if (it != lru_logged_in_users_.end()) | 1708 if (it != lru_logged_in_users_.end()) |
| 1748 lru_logged_in_users_.erase(it); | 1709 lru_logged_in_users_.erase(it); |
| 1749 lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user); | 1710 lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user); |
| 1750 } | 1711 } |
| 1751 | 1712 |
| 1752 void UserManagerImpl::OnRestoreActiveSessions( | |
| 1753 const SessionManagerClient::ActiveSessionsMap& sessions, | |
| 1754 bool success) { | |
| 1755 if (!success) { | |
| 1756 LOG(ERROR) << "Could not get list of active user sessions after crash."; | |
| 1757 // If we could not get list of active user sessions it is safer to just | |
| 1758 // sign out so that we don't get in the inconsistent state. | |
| 1759 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession(); | |
| 1760 return; | |
| 1761 } | |
| 1762 | |
| 1763 // One profile has been already loaded on browser start. | |
| 1764 DCHECK(GetLoggedInUsers().size() == 1); | |
| 1765 DCHECK(GetActiveUser()); | |
| 1766 std::string active_user_id = GetActiveUser()->email(); | |
| 1767 | |
| 1768 SessionManagerClient::ActiveSessionsMap::const_iterator it; | |
| 1769 for (it = sessions.begin(); it != sessions.end(); ++it) { | |
| 1770 if (active_user_id == it->first) | |
| 1771 continue; | |
| 1772 pending_user_sessions_[it->first] = it->second; | |
| 1773 } | |
| 1774 RestorePendingUserSessions(); | |
| 1775 } | |
| 1776 | |
| 1777 void UserManagerImpl::RestorePendingUserSessions() { | |
| 1778 if (pending_user_sessions_.empty()) { | |
| 1779 NotifyPendingUserSessionsRestoreFinished(); | |
| 1780 return; | |
| 1781 } | |
| 1782 | |
| 1783 // Get next user to restore sessions and delete it from list. | |
| 1784 SessionManagerClient::ActiveSessionsMap::const_iterator it = | |
| 1785 pending_user_sessions_.begin(); | |
| 1786 std::string user_id = it->first; | |
| 1787 std::string user_id_hash = it->second; | |
| 1788 DCHECK(!user_id.empty()); | |
| 1789 DCHECK(!user_id_hash.empty()); | |
| 1790 pending_user_sessions_.erase(user_id); | |
| 1791 | |
| 1792 // Check that this user is not logged in yet. | |
| 1793 UserList logged_in_users = GetLoggedInUsers(); | |
| 1794 bool user_already_logged_in = false; | |
| 1795 for (UserList::const_iterator it = logged_in_users.begin(); | |
| 1796 it != logged_in_users.end(); ++it) { | |
| 1797 const User* user = (*it); | |
| 1798 if (user->email() == user_id) { | |
| 1799 user_already_logged_in = true; | |
| 1800 break; | |
| 1801 } | |
| 1802 } | |
| 1803 DCHECK(!user_already_logged_in); | |
| 1804 | |
| 1805 if (!user_already_logged_in) { | |
| 1806 UserContext user_context(user_id); | |
| 1807 user_context.SetUserIDHash(user_id_hash); | |
| 1808 user_context.SetIsUsingOAuth(false); | |
| 1809 // Will call OnProfilePrepared() once profile has been loaded. | |
| 1810 LoginUtils::Get()->PrepareProfile(user_context, | |
| 1811 false, // has_auth_cookies | |
| 1812 true, // has_active_session | |
| 1813 this); | |
| 1814 } else { | |
| 1815 RestorePendingUserSessions(); | |
| 1816 } | |
| 1817 } | |
| 1818 | |
| 1819 void UserManagerImpl::SendRegularUserLoginMetrics(const std::string& user_id) { | 1713 void UserManagerImpl::SendRegularUserLoginMetrics(const std::string& user_id) { |
| 1820 // If this isn't the first time Chrome was run after the system booted, | 1714 // If this isn't the first time Chrome was run after the system booted, |
| 1821 // assume that Chrome was restarted because a previous session ended. | 1715 // assume that Chrome was restarted because a previous session ended. |
| 1822 if (!CommandLine::ForCurrentProcess()->HasSwitch( | 1716 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
| 1823 switches::kFirstExecAfterBoot)) { | 1717 switches::kFirstExecAfterBoot)) { |
| 1824 const std::string last_email = | 1718 const std::string last_email = |
| 1825 g_browser_process->local_state()->GetString(kLastLoggedInRegularUser); | 1719 g_browser_process->local_state()->GetString(kLastLoggedInRegularUser); |
| 1826 const base::TimeDelta time_to_login = | 1720 const base::TimeDelta time_to_login = |
| 1827 base::TimeTicks::Now() - manager_creation_time_; | 1721 base::TimeTicks::Now() - manager_creation_time_; |
| 1828 if (!last_email.empty() && user_id != last_email && | 1722 if (!last_email.empty() && user_id != last_email && |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1874 } | 1768 } |
| 1875 | 1769 |
| 1876 void UserManagerImpl::DeleteUser(User* user) { | 1770 void UserManagerImpl::DeleteUser(User* user) { |
| 1877 const bool is_active_user = (user == active_user_); | 1771 const bool is_active_user = (user == active_user_); |
| 1878 delete user; | 1772 delete user; |
| 1879 if (is_active_user) | 1773 if (is_active_user) |
| 1880 active_user_ = NULL; | 1774 active_user_ = NULL; |
| 1881 } | 1775 } |
| 1882 | 1776 |
| 1883 } // namespace chromeos | 1777 } // namespace chromeos |
| OLD | NEW |