Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: chrome/browser/chromeos/login/user_manager_impl.cc

Issue 15929005: [CrOS multi-profiles] Restore user sessions after crash (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nit Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/user_manager_impl.h" 5 #include "chrome/browser/chromeos/login/user_manager_impl.h"
6 6
7 #include <cstddef> 7 #include <cstddef>
8 #include <set> 8 #include <set>
9 9
10 #include "ash/shell.h" 10 #include "ash/shell.h"
(...skipping 10 matching lines...) Expand all
21 #include "base/string_util.h" 21 #include "base/string_util.h"
22 #include "base/stringprintf.h" 22 #include "base/stringprintf.h"
23 #include "base/utf_string_conversions.h" 23 #include "base/utf_string_conversions.h"
24 #include "base/values.h" 24 #include "base/values.h"
25 #include "chrome/browser/app_mode/app_mode_utils.h" 25 #include "chrome/browser/app_mode/app_mode_utils.h"
26 #include "chrome/browser/browser_process.h" 26 #include "chrome/browser/browser_process.h"
27 #include "chrome/browser/chromeos/cros/cert_library.h" 27 #include "chrome/browser/chromeos/cros/cert_library.h"
28 #include "chrome/browser/chromeos/cros/cros_library.h" 28 #include "chrome/browser/chromeos/cros/cros_library.h"
29 #include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" 29 #include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h"
30 #include "chrome/browser/chromeos/login/login_display.h" 30 #include "chrome/browser/chromeos/login/login_display.h"
31 #include "chrome/browser/chromeos/login/login_utils.h"
31 #include "chrome/browser/chromeos/login/remove_user_delegate.h" 32 #include "chrome/browser/chromeos/login/remove_user_delegate.h"
32 #include "chrome/browser/chromeos/login/user_image_manager_impl.h" 33 #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
33 #include "chrome/browser/chromeos/login/wizard_controller.h" 34 #include "chrome/browser/chromeos/login/wizard_controller.h"
34 #include "chrome/browser/chromeos/policy/device_local_account.h" 35 #include "chrome/browser/chromeos/policy/device_local_account.h"
35 #include "chrome/browser/chromeos/session_length_limiter.h" 36 #include "chrome/browser/chromeos/session_length_limiter.h"
36 #include "chrome/browser/chromeos/settings/cros_settings_names.h" 37 #include "chrome/browser/chromeos/settings/cros_settings_names.h"
37 #include "chrome/browser/policy/browser_policy_connector.h" 38 #include "chrome/browser/policy/browser_policy_connector.h"
38 #include "chrome/browser/prefs/scoped_user_pref_update.h" 39 #include "chrome/browser/prefs/scoped_user_pref_update.h"
39 #include "chrome/browser/profiles/profile_manager.h" 40 #include "chrome/browser/profiles/profile_manager.h"
40 #include "chrome/browser/sync/profile_sync_service.h" 41 #include "chrome/browser/sync/profile_sync_service.h"
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 registry->RegisterDictionaryPref(kUserDisplayEmail); 182 registry->RegisterDictionaryPref(kUserDisplayEmail);
182 SessionLengthLimiter::RegisterPrefs(registry); 183 SessionLengthLimiter::RegisterPrefs(registry);
183 } 184 }
184 185
185 UserManagerImpl::UserManagerImpl() 186 UserManagerImpl::UserManagerImpl()
186 : cros_settings_(CrosSettings::Get()), 187 : cros_settings_(CrosSettings::Get()),
187 device_local_account_policy_service_(NULL), 188 device_local_account_policy_service_(NULL),
188 users_loaded_(false), 189 users_loaded_(false),
189 active_user_(NULL), 190 active_user_(NULL),
190 session_started_(false), 191 session_started_(false),
192 user_sessions_restored_(false),
191 is_current_user_owner_(false), 193 is_current_user_owner_(false),
192 is_current_user_new_(false), 194 is_current_user_new_(false),
193 is_current_user_ephemeral_regular_user_(false), 195 is_current_user_ephemeral_regular_user_(false),
194 ephemeral_users_enabled_(false), 196 ephemeral_users_enabled_(false),
195 merge_session_state_(MERGE_STATUS_NOT_STARTED), 197 merge_session_state_(MERGE_STATUS_NOT_STARTED),
196 observed_sync_service_(NULL), 198 observed_sync_service_(NULL),
197 user_image_manager_(new UserImageManagerImpl) { 199 user_image_manager_(new UserImageManagerImpl) {
198 // UserManager instance should be used only on UI thread. 200 // UserManager instance should be used only on UI thread.
199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 201 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
200 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, 202 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 CheckOwnership(); 624 CheckOwnership();
623 RetrieveTrustedDevicePolicies(); 625 RetrieveTrustedDevicePolicies();
624 break; 626 break;
625 case chrome::NOTIFICATION_PROFILE_ADDED: 627 case chrome::NOTIFICATION_PROFILE_ADDED:
626 if (IsUserLoggedIn() && 628 if (IsUserLoggedIn() &&
627 !IsLoggedInAsGuest() && 629 !IsLoggedInAsGuest() &&
628 !IsLoggedInAsLocallyManagedUser() && 630 !IsLoggedInAsLocallyManagedUser() &&
629 !IsLoggedInAsKioskApp()) { 631 !IsLoggedInAsKioskApp()) {
630 Profile* profile = content::Source<Profile>(source).ptr(); 632 Profile* profile = content::Source<Profile>(source).ptr();
631 if (!profile->IsOffTheRecord() && 633 if (!profile->IsOffTheRecord() &&
632 // TODO(nkostylev): We should observe all logged in user's profiles.
633 profile == ProfileManager::GetDefaultProfile()) { 634 profile == ProfileManager::GetDefaultProfile()) {
634 DCHECK(NULL == observed_sync_service_); 635 // TODO(nkostylev): We should observe all logged in user's profiles.
636 // http://crbug.com/230860
637 if (!CommandLine::ForCurrentProcess()->
638 HasSwitch(::switches::kMultiProfiles)) {
639 DCHECK(NULL == observed_sync_service_);
640 }
635 observed_sync_service_ = 641 observed_sync_service_ =
636 ProfileSyncServiceFactory::GetForProfile(profile); 642 ProfileSyncServiceFactory::GetForProfile(profile);
637 if (observed_sync_service_) 643 if (observed_sync_service_)
638 observed_sync_service_->AddObserver(this); 644 observed_sync_service_->AddObserver(this);
639 } 645 }
640 } 646 }
641 break; 647 break;
642 case chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED: 648 case chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED:
643 DCHECK_EQ(*content::Details<const std::string>(details).ptr(), 649 DCHECK_EQ(*content::Details<const std::string>(details).ptr(),
644 kAccountsPrefDeviceLocalAccounts); 650 kAccountsPrefDeviceLocalAccounts);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 bool UserManagerImpl::IsLoggedInAsStub() const { 761 bool UserManagerImpl::IsLoggedInAsStub() const {
756 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 762 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
757 return IsUserLoggedIn() && active_user_->email() == kStubUser; 763 return IsUserLoggedIn() && active_user_->email() == kStubUser;
758 } 764 }
759 765
760 bool UserManagerImpl::IsSessionStarted() const { 766 bool UserManagerImpl::IsSessionStarted() const {
761 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 767 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
762 return session_started_; 768 return session_started_;
763 } 769 }
764 770
771 bool UserManagerImpl::UserSessionsRestored() const {
772 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
773 return user_sessions_restored_;
774 }
775
765 UserManager::MergeSessionState UserManagerImpl::GetMergeSessionState() const { 776 UserManager::MergeSessionState UserManagerImpl::GetMergeSessionState() const {
766 return merge_session_state_; 777 return merge_session_state_;
767 } 778 }
768 779
769 void UserManagerImpl::SetMergeSessionState( 780 void UserManagerImpl::SetMergeSessionState(
770 UserManager::MergeSessionState state) { 781 UserManager::MergeSessionState state) {
771 if (merge_session_state_ == state) 782 if (merge_session_state_ == state)
772 return; 783 return;
773 784
774 merge_session_state_ = state; 785 merge_session_state_ = state;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 850 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
840 session_state_observer_list_.RemoveObserver(obs); 851 session_state_observer_list_.RemoveObserver(obs);
841 } 852 }
842 853
843 void UserManagerImpl::NotifyLocalStateChanged() { 854 void UserManagerImpl::NotifyLocalStateChanged() {
844 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 855 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
845 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_, 856 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_,
846 LocalStateChanged(this)); 857 LocalStateChanged(this));
847 } 858 }
848 859
860 void UserManagerImpl::OnProfilePrepared(Profile* profile) {
861 LoginUtils::Get()->DoBrowserLaunch(profile,
862 NULL); // host_, not needed here
863
864 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) {
865 // Did not log in (we crashed or are debugging), need to restore Sync.
866 // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
867 // users once it is fully multi-profile aware. http://crbug.com/238987
868 // For now if we have other user pending sessions they'll override OAuth
869 // session restore for previous users.
870 LoginUtils::Get()->RestoreAuthenticationSession(profile);
871 }
872
873 // Restore other user sessions if any.
874 RestorePendingUserSessions();
875 }
876
849 void UserManagerImpl::EnsureUsersLoaded() { 877 void UserManagerImpl::EnsureUsersLoaded() {
850 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 878 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
851 if (!g_browser_process || !g_browser_process->local_state()) 879 if (!g_browser_process || !g_browser_process->local_state())
852 return; 880 return;
853 881
854 if (users_loaded_) 882 if (users_loaded_)
855 return; 883 return;
856 users_loaded_ = true; 884 users_loaded_ = true;
857 885
858 // Clean up user list first. 886 // Clean up user list first.
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after
1498 MergeSessionStateChanged(merge_session_state_)); 1526 MergeSessionStateChanged(merge_session_state_));
1499 } 1527 }
1500 1528
1501 void UserManagerImpl::NotifyActiveUserHashChanged(const std::string& hash) { 1529 void UserManagerImpl::NotifyActiveUserHashChanged(const std::string& hash) {
1502 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1530 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1503 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver, 1531 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1504 session_state_observer_list_, 1532 session_state_observer_list_,
1505 ActiveUserHashChanged(hash)); 1533 ActiveUserHashChanged(hash));
1506 } 1534 }
1507 1535
1536 void UserManagerImpl::NotifyPendingUserSessionsRestoreFinished() {
1537 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1538 user_sessions_restored_ = true;
1539 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1540 session_state_observer_list_,
1541 PendingUserSessionsRestoreFinished());
1542 }
1543
1508 void UserManagerImpl::UpdateLoginState() { 1544 void UserManagerImpl::UpdateLoginState() {
1509 if (!LoginState::IsInitialized()) 1545 if (!LoginState::IsInitialized())
1510 return; // LoginState may not be intialized in tests. 1546 return; // LoginState may not be intialized in tests.
1511 LoginState::LoggedInState logged_in_state; 1547 LoginState::LoggedInState logged_in_state;
1512 logged_in_state = active_user_ ? LoginState::LOGGED_IN_ACTIVE 1548 logged_in_state = active_user_ ? LoginState::LOGGED_IN_ACTIVE
1513 : LoginState::LOGGED_IN_NONE; 1549 : LoginState::LOGGED_IN_NONE;
1514 1550
1515 LoginState::LoggedInUserType login_user_type; 1551 LoginState::LoggedInUserType login_user_type;
1516 if (logged_in_state == LoginState::LOGGED_IN_NONE) 1552 if (logged_in_state == LoginState::LOGGED_IN_NONE)
1517 login_user_type = LoginState::LOGGED_IN_USER_NONE; 1553 login_user_type = LoginState::LOGGED_IN_USER_NONE;
(...skipping 20 matching lines...) Expand all
1538 lru_logged_in_users_.end(), 1574 lru_logged_in_users_.end(),
1539 user); 1575 user);
1540 if (it != lru_logged_in_users_.end()) 1576 if (it != lru_logged_in_users_.end())
1541 lru_logged_in_users_.erase(it); 1577 lru_logged_in_users_.erase(it);
1542 lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user); 1578 lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user);
1543 } 1579 }
1544 1580
1545 void UserManagerImpl::OnRestoreActiveSessions( 1581 void UserManagerImpl::OnRestoreActiveSessions(
1546 const SessionManagerClient::ActiveSessionsMap& sessions, 1582 const SessionManagerClient::ActiveSessionsMap& sessions,
1547 bool success) { 1583 bool success) {
1548 // TODO(nkostylev): Restore all user sessions (in the background). 1584 if (!success) {
1549 // This requires first refactoring this flow out of LoginUtils. 1585 LOG(ERROR) << "Could not get list of active user sessions after crash.";
1550 // 1. UserManager::UserLoggedIn() 1586 // If we could not get list of active user sessions it is safer to just
1551 // 2. InitSessionRestoreStrategy() (OAuth) 1587 // sign out so that we don't get in the inconsistent state.
1552 // 2. ProfileManager::CreateDefaultProfileAsync() 1588 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
1553 // 3. InitProfilePreferences 1589 return;
1554 // 4. chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED 1590 }
1591
1592 // One profile has been already loaded on browser start.
1593 DCHECK(GetLoggedInUsers().size() == 1);
1594 DCHECK(GetActiveUser());
1595 std::string active_user_id = GetActiveUser()->email();
1596
1597 SessionManagerClient::ActiveSessionsMap::const_iterator it;
1598 for (it = sessions.begin(); it != sessions.end(); ++it) {
1599 if (active_user_id == it->first)
1600 continue;
1601 pending_user_sessions_[it->first] = it->second;
1602 }
1603 RestorePendingUserSessions();
1604 }
1605
1606 void UserManagerImpl::RestorePendingUserSessions() {
1607 if (pending_user_sessions_.empty()) {
1608 NotifyPendingUserSessionsRestoreFinished();
1609 return;
1610 }
1611
1612 // Get next user to restore sessions and delete it from list.
1613 SessionManagerClient::ActiveSessionsMap::const_iterator it =
1614 pending_user_sessions_.begin();
1615 std::string user_id = it->first;
1616 std::string user_id_hash = it->second;
1617 DCHECK(!user_id.empty());
1618 DCHECK(!user_id_hash.empty());
1619 pending_user_sessions_.erase(user_id);
1620
1621 // Check that this user is not logged in yet.
1622 UserList logged_in_users = GetLoggedInUsers();
1623 bool user_already_logged_in = false;
1624 for (UserList::const_iterator it = logged_in_users.begin();
1625 it != logged_in_users.end(); ++it) {
1626 const User* user = (*it);
1627 if (user->email() == user_id) {
1628 user_already_logged_in = true;
1629 break;
1630 }
1631 }
1632 DCHECK(!user_already_logged_in);
1633
1634 if (!user_already_logged_in) {
1635 // Will call OnProfilePrepared() once profile has been loaded.
1636 LoginUtils::Get()->PrepareProfile(UserContext(user_id,
1637 std::string(), // password
1638 std::string(), // auth_code
1639 user_id_hash),
1640 std::string(), // display_email
1641 false, // using_oauth
1642 false, // has_cookies
1643 true, // has_active_session
1644 this);
1645 } else {
1646 RestorePendingUserSessions();
1647 }
1555 } 1648 }
1556 1649
1557 } // namespace chromeos 1650 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/user_manager_impl.h ('k') | chrome/browser/chromeos/profiles/profile_helper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698