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 |