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/session/user_session_manager.h" | 5 #include "chrome/browser/chromeos/login/session/user_session_manager.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/base_paths.h" | 9 #include "base/base_paths.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 #include "chromeos/cert_loader.h" | 49 #include "chromeos/cert_loader.h" |
50 #include "chromeos/chromeos_switches.h" | 50 #include "chromeos/chromeos_switches.h" |
51 #include "chromeos/cryptohome/cryptohome_util.h" | 51 #include "chromeos/cryptohome/cryptohome_util.h" |
52 #include "chromeos/dbus/cryptohome_client.h" | 52 #include "chromeos/dbus/cryptohome_client.h" |
53 #include "chromeos/dbus/dbus_thread_manager.h" | 53 #include "chromeos/dbus/dbus_thread_manager.h" |
54 #include "chromeos/dbus/session_manager_client.h" | 54 #include "chromeos/dbus/session_manager_client.h" |
55 #include "chromeos/ime/input_method_manager.h" | 55 #include "chromeos/ime/input_method_manager.h" |
56 #include "chromeos/network/portal_detector/network_portal_detector.h" | 56 #include "chromeos/network/portal_detector/network_portal_detector.h" |
57 #include "chromeos/network/portal_detector/network_portal_detector_strategy.h" | 57 #include "chromeos/network/portal_detector/network_portal_detector_strategy.h" |
58 #include "components/signin/core/browser/signin_manager_base.h" | 58 #include "components/signin/core/browser/signin_manager_base.h" |
| 59 #include "content/public/browser/browser_thread.h" |
59 #include "content/public/browser/notification_service.h" | 60 #include "content/public/browser/notification_service.h" |
60 | 61 |
61 namespace chromeos { | 62 namespace chromeos { |
62 | 63 |
63 namespace { | 64 namespace { |
64 | 65 |
65 void InitLocaleAndInputMethodsForNewUser(PrefService* prefs) { | 66 void InitLocaleAndInputMethodsForNewUser(PrefService* prefs) { |
66 // First, we'll set kLanguagePreloadEngines. | 67 // First, we'll set kLanguagePreloadEngines. |
67 std::string locale = g_browser_process->GetApplicationLocale(); | 68 std::string locale = g_browser_process->GetApplicationLocale(); |
68 input_method::InputMethodManager* manager = | 69 input_method::InputMethodManager* manager = |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 // provided NSS database. It must be called for primary user only. | 123 // provided NSS database. It must be called for primary user only. |
123 void OnGetNSSCertDatabaseForUser(net::NSSCertDatabase* database) { | 124 void OnGetNSSCertDatabaseForUser(net::NSSCertDatabase* database) { |
124 if (!CertLoader::IsInitialized()) | 125 if (!CertLoader::IsInitialized()) |
125 return; | 126 return; |
126 | 127 |
127 CertLoader::Get()->StartWithNSSDB(database); | 128 CertLoader::Get()->StartWithNSSDB(database); |
128 } | 129 } |
129 | 130 |
130 } // namespace | 131 } // namespace |
131 | 132 |
| 133 #if defined(ENABLE_RLZ) |
| 134 void UserSessionManagerDelegate::OnRlzInitialized() { |
| 135 } |
| 136 #endif |
| 137 |
| 138 UserSessionManagerDelegate::~UserSessionManagerDelegate() { |
| 139 } |
| 140 |
| 141 void UserSessionStateObserver::PendingUserSessionsRestoreFinished() { |
| 142 } |
| 143 |
| 144 UserSessionStateObserver::~UserSessionStateObserver() { |
| 145 } |
| 146 |
132 // static | 147 // static |
133 UserSessionManager* UserSessionManager::GetInstance() { | 148 UserSessionManager* UserSessionManager::GetInstance() { |
134 return Singleton<UserSessionManager, | 149 return Singleton<UserSessionManager, |
135 DefaultSingletonTraits<UserSessionManager> >::get(); | 150 DefaultSingletonTraits<UserSessionManager> >::get(); |
136 } | 151 } |
137 | 152 |
138 // static | 153 // static |
139 void UserSessionManager::OverrideHomedir() { | 154 void UserSessionManager::OverrideHomedir() { |
140 // Override user homedir, check for ProfileManager being initialized as | 155 // Override user homedir, check for ProfileManager being initialized as |
141 // it may not exist in unit tests. | 156 // it may not exist in unit tests. |
(...skipping 14 matching lines...) Expand all Loading... |
156 | 171 |
157 // static | 172 // static |
158 void UserSessionManager::RegisterPrefs(PrefRegistrySimple* registry) { | 173 void UserSessionManager::RegisterPrefs(PrefRegistrySimple* registry) { |
159 registry->RegisterStringPref(prefs::kRLZBrand, std::string()); | 174 registry->RegisterStringPref(prefs::kRLZBrand, std::string()); |
160 registry->RegisterBooleanPref(prefs::kRLZDisabled, false); | 175 registry->RegisterBooleanPref(prefs::kRLZDisabled, false); |
161 } | 176 } |
162 | 177 |
163 UserSessionManager::UserSessionManager() | 178 UserSessionManager::UserSessionManager() |
164 : delegate_(NULL), | 179 : delegate_(NULL), |
165 has_auth_cookies_(false), | 180 has_auth_cookies_(false), |
| 181 user_sessions_restored_(false), |
166 exit_after_session_restore_(false), | 182 exit_after_session_restore_(false), |
167 session_restore_strategy_( | 183 session_restore_strategy_( |
168 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN) { | 184 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN) { |
169 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); | 185 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); |
170 } | 186 } |
171 | 187 |
172 UserSessionManager::~UserSessionManager() { | 188 UserSessionManager::~UserSessionManager() { |
173 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | 189 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); |
174 } | 190 } |
175 | 191 |
176 void UserSessionManager::StartSession(const UserContext& user_context, | 192 void UserSessionManager::StartSession( |
177 scoped_refptr<Authenticator> authenticator, | 193 const UserContext& user_context, |
178 bool has_auth_cookies, | 194 scoped_refptr<Authenticator> authenticator, |
179 bool has_active_session, | 195 bool has_auth_cookies, |
180 Delegate* delegate) { | 196 bool has_active_session, |
| 197 UserSessionManagerDelegate* delegate) { |
181 authenticator_ = authenticator; | 198 authenticator_ = authenticator; |
182 delegate_ = delegate; | 199 delegate_ = delegate; |
183 | 200 |
184 VLOG(1) << "Starting session for " << user_context.GetUserID(); | 201 VLOG(1) << "Starting session for " << user_context.GetUserID(); |
185 | 202 |
186 PreStartSession(); | 203 PreStartSession(); |
187 CreateUserSession(user_context, has_auth_cookies); | 204 CreateUserSession(user_context, has_auth_cookies); |
188 | 205 |
189 if (!has_active_session) | 206 if (!has_active_session) |
190 StartCrosSession(); | 207 StartCrosSession(); |
(...skipping 29 matching lines...) Expand all Loading... |
220 // explicitly disabled for it. | 237 // explicitly disabled for it. |
221 if (!user_manager->IsUserLoggedIn() || | 238 if (!user_manager->IsUserLoggedIn() || |
222 !user_manager->IsLoggedInAsRegularUser() || | 239 !user_manager->IsLoggedInAsRegularUser() || |
223 user_manager->IsLoggedInAsStub()) { | 240 user_manager->IsLoggedInAsStub()) { |
224 return; | 241 return; |
225 } | 242 } |
226 | 243 |
227 User* user = ProfileHelper::Get()->GetUserByProfile(user_profile); | 244 User* user = ProfileHelper::Get()->GetUserByProfile(user_profile); |
228 DCHECK(user); | 245 DCHECK(user); |
229 if (!net::NetworkChangeNotifier::IsOffline()) { | 246 if (!net::NetworkChangeNotifier::IsOffline()) { |
230 pending_restore_sessions_.erase(user->email()); | 247 pending_signin_restore_sessions_.erase(user->email()); |
231 RestoreAuthSessionImpl(user_profile, false /* has_auth_cookies */); | 248 RestoreAuthSessionImpl(user_profile, false /* has_auth_cookies */); |
232 } else { | 249 } else { |
233 // Even if we're online we should wait till initial | 250 // Even if we're online we should wait till initial |
234 // OnConnectionTypeChanged() call. Otherwise starting fetchers too early may | 251 // OnConnectionTypeChanged() call. Otherwise starting fetchers too early may |
235 // end up canceling all request when initial network connection type is | 252 // end up canceling all request when initial network connection type is |
236 // processed. See http://crbug.com/121643. | 253 // processed. See http://crbug.com/121643. |
237 pending_restore_sessions_.insert(user->email()); | 254 pending_signin_restore_sessions_.insert(user->email()); |
238 } | 255 } |
239 } | 256 } |
240 | 257 |
| 258 void UserSessionManager::RestoreActiveSessions() { |
| 259 DBusThreadManager::Get()->GetSessionManagerClient()->RetrieveActiveSessions( |
| 260 base::Bind(&UserSessionManager::OnRestoreActiveSessions, |
| 261 base::Unretained(this))); |
| 262 } |
| 263 |
| 264 bool UserSessionManager::UserSessionsRestored() const { |
| 265 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 266 return user_sessions_restored_; |
| 267 } |
| 268 |
241 void UserSessionManager::InitRlz(Profile* profile) { | 269 void UserSessionManager::InitRlz(Profile* profile) { |
242 #if defined(ENABLE_RLZ) | 270 #if defined(ENABLE_RLZ) |
243 if (!g_browser_process->local_state()->HasPrefPath(prefs::kRLZBrand)) { | 271 if (!g_browser_process->local_state()->HasPrefPath(prefs::kRLZBrand)) { |
244 // Read brand code asynchronously from an OEM data and repost ourselves. | 272 // Read brand code asynchronously from an OEM data and repost ourselves. |
245 google_brand::chromeos::InitBrand( | 273 google_brand::chromeos::InitBrand( |
246 base::Bind(&UserSessionManager::InitRlz, AsWeakPtr(), profile)); | 274 base::Bind(&UserSessionManager::InitRlz, AsWeakPtr(), profile)); |
247 return; | 275 return; |
248 } | 276 } |
249 base::PostTaskAndReplyWithResult( | 277 base::PostTaskAndReplyWithResult( |
250 base::WorkerPool::GetTaskRunner(false), | 278 base::WorkerPool::GetTaskRunner(false), |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 // So input methods should be enabled somewhere. | 388 // So input methods should be enabled somewhere. |
361 const bool enable_layouts = UserManager::Get()->IsLoggedInAsGuest(); | 389 const bool enable_layouts = UserManager::Get()->IsLoggedInAsGuest(); |
362 locale_util::SwitchLanguage(pref_locale, | 390 locale_util::SwitchLanguage(pref_locale, |
363 enable_layouts, | 391 enable_layouts, |
364 false /* login_layouts_only */, | 392 false /* login_layouts_only */, |
365 callback.Pass()); | 393 callback.Pass()); |
366 | 394 |
367 return true; | 395 return true; |
368 } | 396 } |
369 | 397 |
| 398 void UserSessionManager::AddSessionStateObserver( |
| 399 UserSessionStateObserver* observer) { |
| 400 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 401 session_state_observer_list_.AddObserver(observer); |
| 402 } |
| 403 |
| 404 void UserSessionManager::RemoveSessionStateObserver( |
| 405 UserSessionStateObserver* observer) { |
| 406 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 407 session_state_observer_list_.RemoveObserver(observer); |
| 408 } |
| 409 |
370 void UserSessionManager::OnSessionRestoreStateChanged( | 410 void UserSessionManager::OnSessionRestoreStateChanged( |
371 Profile* user_profile, | 411 Profile* user_profile, |
372 OAuth2LoginManager::SessionRestoreState state) { | 412 OAuth2LoginManager::SessionRestoreState state) { |
373 User::OAuthTokenStatus user_status = User::OAUTH_TOKEN_STATUS_UNKNOWN; | 413 User::OAuthTokenStatus user_status = User::OAUTH_TOKEN_STATUS_UNKNOWN; |
374 OAuth2LoginManager* login_manager = | 414 OAuth2LoginManager* login_manager = |
375 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile); | 415 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile); |
376 | 416 |
377 bool connection_error = false; | 417 bool connection_error = false; |
378 switch (state) { | 418 switch (state) { |
379 case OAuth2LoginManager::SESSION_RESTORE_DONE: | 419 case OAuth2LoginManager::SESSION_RESTORE_DONE: |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 } | 475 } |
436 | 476 |
437 // Need to iterate over all users and their OAuth2 session state. | 477 // Need to iterate over all users and their OAuth2 session state. |
438 const UserList& users = user_manager->GetLoggedInUsers(); | 478 const UserList& users = user_manager->GetLoggedInUsers(); |
439 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) { | 479 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) { |
440 if (!(*it)->is_profile_created()) | 480 if (!(*it)->is_profile_created()) |
441 continue; | 481 continue; |
442 | 482 |
443 Profile* user_profile = ProfileHelper::Get()->GetProfileByUser(*it); | 483 Profile* user_profile = ProfileHelper::Get()->GetProfileByUser(*it); |
444 bool should_restore_session = | 484 bool should_restore_session = |
445 pending_restore_sessions_.find((*it)->email()) != | 485 pending_signin_restore_sessions_.find((*it)->email()) != |
446 pending_restore_sessions_.end(); | 486 pending_signin_restore_sessions_.end(); |
447 OAuth2LoginManager* login_manager = | 487 OAuth2LoginManager* login_manager = |
448 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile); | 488 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile); |
449 if (login_manager->state() == | 489 if (login_manager->state() == |
450 OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) { | 490 OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) { |
451 // If we come online for the first time after successful offline login, | 491 // If we come online for the first time after successful offline login, |
452 // we need to kick off OAuth token verification process again. | 492 // we need to kick off OAuth token verification process again. |
453 login_manager->ContinueSessionRestore(); | 493 login_manager->ContinueSessionRestore(); |
454 } else if (should_restore_session) { | 494 } else if (should_restore_session) { |
455 pending_restore_sessions_.erase((*it)->email()); | 495 pending_signin_restore_sessions_.erase((*it)->email()); |
456 RestoreAuthSessionImpl(user_profile, false /* has_auth_cookies */); | 496 RestoreAuthSessionImpl(user_profile, false /* has_auth_cookies */); |
457 } | 497 } |
458 } | 498 } |
459 } | 499 } |
460 | 500 |
| 501 void UserSessionManager::OnProfilePrepared(Profile* profile) { |
| 502 LoginUtils::Get()->DoBrowserLaunch(profile, NULL); // host_, not needed here |
| 503 |
| 504 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) { |
| 505 // Did not log in (we crashed or are debugging), need to restore Sync. |
| 506 // TODO(nkostylev): Make sure that OAuth state is restored correctly for all |
| 507 // users once it is fully multi-profile aware. http://crbug.com/238987 |
| 508 // For now if we have other user pending sessions they'll override OAuth |
| 509 // session restore for previous users. |
| 510 UserSessionManager::GetInstance()->RestoreAuthenticationSession(profile); |
| 511 } |
| 512 |
| 513 // Restore other user sessions if any. |
| 514 RestorePendingUserSessions(); |
| 515 } |
| 516 |
461 void UserSessionManager::CreateUserSession(const UserContext& user_context, | 517 void UserSessionManager::CreateUserSession(const UserContext& user_context, |
462 bool has_auth_cookies) { | 518 bool has_auth_cookies) { |
463 user_context_ = user_context; | 519 user_context_ = user_context; |
464 has_auth_cookies_ = has_auth_cookies; | 520 has_auth_cookies_ = has_auth_cookies; |
465 InitSessionRestoreStrategy(); | 521 InitSessionRestoreStrategy(); |
466 } | 522 } |
467 | 523 |
468 void UserSessionManager::PreStartSession() { | 524 void UserSessionManager::PreStartSession() { |
469 // Switch log file as soon as possible. | 525 // Switch log file as soon as possible. |
470 if (base::SysInfo::IsRunningOnChromeOS()) | 526 if (base::SysInfo::IsRunningOnChromeOS()) |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 if (user_manager->IsUserLoggedIn() && | 806 if (user_manager->IsUserLoggedIn() && |
751 primary_user && | 807 primary_user && |
752 profile == ProfileHelper::Get()->GetProfileByUser(primary_user) && | 808 profile == ProfileHelper::Get()->GetProfileByUser(primary_user) && |
753 CertLoader::IsInitialized() && | 809 CertLoader::IsInitialized() && |
754 base::SysInfo::IsRunningOnChromeOS()) { | 810 base::SysInfo::IsRunningOnChromeOS()) { |
755 GetNSSCertDatabaseForProfile(profile, | 811 GetNSSCertDatabaseForProfile(profile, |
756 base::Bind(&OnGetNSSCertDatabaseForUser)); | 812 base::Bind(&OnGetNSSCertDatabaseForUser)); |
757 } | 813 } |
758 } | 814 } |
759 | 815 |
| 816 void UserSessionManager::OnRestoreActiveSessions( |
| 817 const SessionManagerClient::ActiveSessionsMap& sessions, |
| 818 bool success) { |
| 819 if (!success) { |
| 820 LOG(ERROR) << "Could not get list of active user sessions after crash."; |
| 821 // If we could not get list of active user sessions it is safer to just |
| 822 // sign out so that we don't get in the inconsistent state. |
| 823 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession(); |
| 824 return; |
| 825 } |
| 826 |
| 827 // One profile has been already loaded on browser start. |
| 828 UserManager* user_manager = UserManager::Get(); |
| 829 DCHECK(user_manager->GetLoggedInUsers().size() == 1); |
| 830 DCHECK(user_manager->GetActiveUser()); |
| 831 std::string active_user_id = user_manager->GetActiveUser()->email(); |
| 832 |
| 833 SessionManagerClient::ActiveSessionsMap::const_iterator it; |
| 834 for (it = sessions.begin(); it != sessions.end(); ++it) { |
| 835 if (active_user_id == it->first) |
| 836 continue; |
| 837 pending_user_sessions_[it->first] = it->second; |
| 838 } |
| 839 RestorePendingUserSessions(); |
| 840 } |
| 841 |
| 842 void UserSessionManager::RestorePendingUserSessions() { |
| 843 if (pending_user_sessions_.empty()) { |
| 844 NotifyPendingUserSessionsRestoreFinished(); |
| 845 return; |
| 846 } |
| 847 |
| 848 // Get next user to restore sessions and delete it from list. |
| 849 SessionManagerClient::ActiveSessionsMap::const_iterator it = |
| 850 pending_user_sessions_.begin(); |
| 851 std::string user_id = it->first; |
| 852 std::string user_id_hash = it->second; |
| 853 DCHECK(!user_id.empty()); |
| 854 DCHECK(!user_id_hash.empty()); |
| 855 pending_user_sessions_.erase(user_id); |
| 856 |
| 857 // Check that this user is not logged in yet. |
| 858 UserList logged_in_users = UserManager::Get()->GetLoggedInUsers(); |
| 859 bool user_already_logged_in = false; |
| 860 for (UserList::const_iterator it = logged_in_users.begin(); |
| 861 it != logged_in_users.end(); |
| 862 ++it) { |
| 863 const User* user = (*it); |
| 864 if (user->email() == user_id) { |
| 865 user_already_logged_in = true; |
| 866 break; |
| 867 } |
| 868 } |
| 869 DCHECK(!user_already_logged_in); |
| 870 |
| 871 if (!user_already_logged_in) { |
| 872 UserContext user_context(user_id); |
| 873 user_context.SetUserIDHash(user_id_hash); |
| 874 user_context.SetIsUsingOAuth(false); |
| 875 |
| 876 // Will call OnProfilePrepared() once profile has been loaded. |
| 877 StartSession(user_context, |
| 878 NULL, // authenticator |
| 879 false, // has_auth_cookies |
| 880 true, // has_active_session |
| 881 this); |
| 882 } else { |
| 883 RestorePendingUserSessions(); |
| 884 } |
| 885 } |
| 886 |
| 887 void UserSessionManager::NotifyPendingUserSessionsRestoreFinished() { |
| 888 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 889 user_sessions_restored_ = true; |
| 890 FOR_EACH_OBSERVER(UserSessionStateObserver, |
| 891 session_state_observer_list_, |
| 892 PendingUserSessionsRestoreFinished()); |
| 893 } |
| 894 |
760 } // namespace chromeos | 895 } // namespace chromeos |
OLD | NEW |