| Index: chrome/browser/chromeos/login/user_manager_impl.cc
|
| diff --git a/chrome/browser/chromeos/login/user_manager_impl.cc b/chrome/browser/chromeos/login/user_manager_impl.cc
|
| index 7f1d22a6bde2e44e27ec7ca19ac57053ff5dbb6b..32ff174cf8ff3c2bc54c91c04c9d1bec41e4511a 100644
|
| --- a/chrome/browser/chromeos/login/user_manager_impl.cc
|
| +++ b/chrome/browser/chromeos/login/user_manager_impl.cc
|
| @@ -28,6 +28,7 @@
|
| #include "chrome/browser/chromeos/cros/cros_library.h"
|
| #include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h"
|
| #include "chrome/browser/chromeos/login/login_display.h"
|
| +#include "chrome/browser/chromeos/login/login_utils.h"
|
| #include "chrome/browser/chromeos/login/remove_user_delegate.h"
|
| #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
|
| #include "chrome/browser/chromeos/login/wizard_controller.h"
|
| @@ -188,6 +189,7 @@ UserManagerImpl::UserManagerImpl()
|
| users_loaded_(false),
|
| active_user_(NULL),
|
| session_started_(false),
|
| + user_sessions_restored_(false),
|
| is_current_user_owner_(false),
|
| is_current_user_new_(false),
|
| is_current_user_ephemeral_regular_user_(false),
|
| @@ -629,9 +631,13 @@ void UserManagerImpl::Observe(int type,
|
| !IsLoggedInAsKioskApp()) {
|
| Profile* profile = content::Source<Profile>(source).ptr();
|
| if (!profile->IsOffTheRecord() &&
|
| - // TODO(nkostylev): We should observe all logged in user's profiles.
|
| profile == ProfileManager::GetDefaultProfile()) {
|
| - DCHECK(NULL == observed_sync_service_);
|
| + // TODO(nkostylev): We should observe all logged in user's profiles.
|
| + // http://crbug.com/230860
|
| + if (!CommandLine::ForCurrentProcess()->
|
| + HasSwitch(::switches::kMultiProfiles)) {
|
| + DCHECK(NULL == observed_sync_service_);
|
| + }
|
| observed_sync_service_ =
|
| ProfileSyncServiceFactory::GetForProfile(profile);
|
| if (observed_sync_service_)
|
| @@ -762,6 +768,11 @@ bool UserManagerImpl::IsSessionStarted() const {
|
| return session_started_;
|
| }
|
|
|
| +bool UserManagerImpl::UserSessionsRestored() const {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + return user_sessions_restored_;
|
| +}
|
| +
|
| UserManager::MergeSessionState UserManagerImpl::GetMergeSessionState() const {
|
| return merge_session_state_;
|
| }
|
| @@ -846,6 +857,23 @@ void UserManagerImpl::NotifyLocalStateChanged() {
|
| LocalStateChanged(this));
|
| }
|
|
|
| +void UserManagerImpl::OnProfilePrepared(Profile* profile) {
|
| + LoginUtils::Get()->DoBrowserLaunch(profile,
|
| + NULL); // host_, not needed here
|
| +
|
| + if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) {
|
| + // Did not log in (we crashed or are debugging), need to restore Sync.
|
| + // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
|
| + // users once it is fully multi-profile aware. http://crbug.com/238987
|
| + // For now if we have other user pending sessions they'll override OAuth
|
| + // session restore for previous users.
|
| + LoginUtils::Get()->RestoreAuthenticationSession(profile);
|
| + }
|
| +
|
| + // Restore other user sessions if any.
|
| + RestorePendingUserSessions();
|
| +}
|
| +
|
| void UserManagerImpl::EnsureUsersLoaded() {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| if (!g_browser_process || !g_browser_process->local_state())
|
| @@ -1505,6 +1533,14 @@ void UserManagerImpl::NotifyActiveUserHashChanged(const std::string& hash) {
|
| ActiveUserHashChanged(hash));
|
| }
|
|
|
| +void UserManagerImpl::NotifyPendingUserSessionsRestoreFinished() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + user_sessions_restored_ = true;
|
| + FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
|
| + session_state_observer_list_,
|
| + PendingUserSessionsRestoreFinished());
|
| +}
|
| +
|
| void UserManagerImpl::UpdateLoginState() {
|
| if (!LoginState::IsInitialized())
|
| return; // LoginState may not be intialized in tests.
|
| @@ -1545,13 +1581,70 @@ void UserManagerImpl::SetLRUUser(User* user) {
|
| void UserManagerImpl::OnRestoreActiveSessions(
|
| const SessionManagerClient::ActiveSessionsMap& sessions,
|
| bool success) {
|
| - // TODO(nkostylev): Restore all user sessions (in the background).
|
| - // This requires first refactoring this flow out of LoginUtils.
|
| - // 1. UserManager::UserLoggedIn()
|
| - // 2. InitSessionRestoreStrategy() (OAuth)
|
| - // 2. ProfileManager::CreateDefaultProfileAsync()
|
| - // 3. InitProfilePreferences
|
| - // 4. chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED
|
| + if (!success) {
|
| + LOG(ERROR) << "Could not get list of active user sessions after crash.";
|
| + // If we could not get list of active user sessions it is safer to just
|
| + // sign out so that we don't get in the inconsistent state.
|
| + DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
|
| + return;
|
| + }
|
| +
|
| + // One profile has been already loaded on browser start.
|
| + DCHECK(GetLoggedInUsers().size() == 1);
|
| + DCHECK(GetActiveUser());
|
| + std::string active_user_id = GetActiveUser()->email();
|
| +
|
| + SessionManagerClient::ActiveSessionsMap::const_iterator it;
|
| + for (it = sessions.begin(); it != sessions.end(); ++it) {
|
| + if (active_user_id == it->first)
|
| + continue;
|
| + pending_user_sessions_[it->first] = it->second;
|
| + }
|
| + RestorePendingUserSessions();
|
| +}
|
| +
|
| +void UserManagerImpl::RestorePendingUserSessions() {
|
| + if (pending_user_sessions_.empty()) {
|
| + NotifyPendingUserSessionsRestoreFinished();
|
| + return;
|
| + }
|
| +
|
| + // Get next user to restore sessions and delete it from list.
|
| + SessionManagerClient::ActiveSessionsMap::const_iterator it =
|
| + pending_user_sessions_.begin();
|
| + std::string user_id = it->first;
|
| + std::string user_id_hash = it->second;
|
| + DCHECK(!user_id.empty());
|
| + DCHECK(!user_id_hash.empty());
|
| + pending_user_sessions_.erase(user_id);
|
| +
|
| + // Check that this user is not logged in yet.
|
| + UserList logged_in_users = GetLoggedInUsers();
|
| + bool user_already_logged_in = false;
|
| + for (UserList::const_iterator it = logged_in_users.begin();
|
| + it != logged_in_users.end(); ++it) {
|
| + const User* user = (*it);
|
| + if (user->email() == user_id) {
|
| + user_already_logged_in = true;
|
| + break;
|
| + }
|
| + }
|
| + DCHECK(!user_already_logged_in);
|
| +
|
| + if (!user_already_logged_in) {
|
| + // Will call OnProfilePrepared() once profile has been loaded.
|
| + LoginUtils::Get()->PrepareProfile(UserContext(user_id,
|
| + std::string(), // password
|
| + std::string(), // auth_code
|
| + user_id_hash),
|
| + std::string(), // display_email
|
| + false, // using_oauth
|
| + false, // has_cookies
|
| + true, // has_active_session
|
| + this);
|
| + } else {
|
| + RestorePendingUserSessions();
|
| + }
|
| }
|
|
|
| } // namespace chromeos
|
|
|