Chromium Code Reviews| 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/chrome_session_manager.h" | 5 #include "chrome/browser/chromeos/login/session/chrome_session_manager.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/sys_info.h" | 11 #include "base/sys_info.h" |
| 12 #include "chrome/browser/browser_process.h" | |
| 13 #include "chrome/browser/browser_process_platform_part_chromeos.h" | |
| 12 #include "chrome/browser/chrome_notification_types.h" | 14 #include "chrome/browser/chrome_notification_types.h" |
| 13 #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h" | 15 #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h" |
| 14 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" | 16 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" |
| 15 #include "chrome/browser/chromeos/login/session/kiosk_auto_launcher_session_mana ger_delegate.h" | 17 #include "chrome/browser/chromeos/arc/arc_auth_service.h" |
| 16 #include "chrome/browser/chromeos/login/session/login_oobe_session_manager_deleg ate.h" | 18 #include "chrome/browser/chromeos/login/login_wizard.h" |
| 17 #include "chrome/browser/chromeos/login/session/restore_after_crash_session_mana ger_delegate.h" | 19 #include "chrome/browser/chromeos/login/session/user_session_manager.h" |
| 18 #include "chrome/browser/chromeos/login/session/stub_login_session_manager_deleg ate.h" | 20 #include "chrome/browser/chromeos/login/wizard_controller.h" |
| 21 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" | |
| 19 #include "chrome/browser/profiles/profile.h" | 22 #include "chrome/browser/profiles/profile.h" |
| 23 #include "chrome/browser/signin/signin_manager_factory.h" | |
| 24 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" | |
| 25 #include "chrome/common/chrome_switches.h" | |
| 26 #include "chrome/common/pref_names.h" | |
| 27 #include "chromeos/audio/cras_audio_handler.h" | |
| 20 #include "chromeos/chromeos_switches.h" | 28 #include "chromeos/chromeos_switches.h" |
| 21 #include "chromeos/cryptohome/cryptohome_parameters.h" | 29 #include "chromeos/cryptohome/cryptohome_parameters.h" |
| 30 #include "chromeos/dbus/dbus_thread_manager.h" | |
| 31 #include "chromeos/dbus/session_manager_client.h" | |
| 22 #include "chromeos/login/user_names.h" | 32 #include "chromeos/login/user_names.h" |
| 33 #include "components/arc/arc_bridge_service.h" | |
| 34 #include "components/arc/arc_service_manager.h" | |
| 35 #include "components/prefs/pref_service.h" | |
| 23 #include "components/signin/core/account_id/account_id.h" | 36 #include "components/signin/core/account_id/account_id.h" |
| 37 #include "components/signin/core/browser/signin_manager.h" | |
| 24 #include "components/user_manager/user_manager.h" | 38 #include "components/user_manager/user_manager.h" |
| 25 #include "content/public/browser/notification_service.h" | 39 #include "content/public/browser/notification_service.h" |
| 40 #include "content/public/common/content_switches.h" | |
| 26 | 41 |
| 27 namespace chromeos { | 42 namespace chromeos { |
| 28 | 43 |
| 29 namespace { | 44 namespace { |
| 30 | 45 |
| 31 bool ShouldAutoLaunchKioskApp(const base::CommandLine& command_line) { | 46 bool ShouldAutoLaunchKioskApp(const base::CommandLine& command_line) { |
| 32 KioskAppManager* app_manager = KioskAppManager::Get(); | 47 KioskAppManager* app_manager = KioskAppManager::Get(); |
| 33 return command_line.HasSwitch(switches::kLoginManager) && | 48 return command_line.HasSwitch(switches::kLoginManager) && |
| 34 !command_line.HasSwitch(switches::kForceLoginManagerInTests) && | 49 !command_line.HasSwitch(switches::kForceLoginManagerInTests) && |
| 35 app_manager->IsAutoLaunchEnabled() && | 50 app_manager->IsAutoLaunchEnabled() && |
| 36 KioskAppLaunchError::Get() == KioskAppLaunchError::NONE; | 51 KioskAppLaunchError::Get() == KioskAppLaunchError::NONE; |
| 37 } | 52 } |
| 38 | 53 |
| 54 void StartKioskSession() { | |
|
achuithb
2016/10/27 21:18:52
Let's add a short function comment for each of the
xiyuan
2016/10/27 21:31:13
Done.
| |
| 55 // Kiosk app launcher starts with login state. | |
| 56 session_manager::SessionManager::Get()->SetSessionState( | |
| 57 session_manager::SessionState::LOGIN_PRIMARY); | |
| 58 | |
| 59 ShowLoginWizard(chromeos::WizardController::kAppLaunchSplashScreenName); | |
| 60 | |
| 61 // Login screen is skipped but 'login-prompt-visible' signal is still needed. | |
| 62 VLOG(1) << "Kiosk app auto launch >> login-prompt-visible"; | |
| 63 DBusThreadManager::Get()->GetSessionManagerClient()->EmitLoginPromptVisible(); | |
| 64 } | |
| 65 | |
| 66 void StartLoginOobeSession() { | |
| 67 // State will be defined once out-of-box/login branching is complete. | |
| 68 ShowLoginWizard(std::string()); | |
| 69 | |
| 70 // Reset reboot after update flag when login screen is shown. | |
| 71 policy::BrowserPolicyConnectorChromeOS* connector = | |
| 72 g_browser_process->platform_part()->browser_policy_connector_chromeos(); | |
| 73 if (!connector->IsEnterpriseManaged()) { | |
| 74 PrefService* local_state = g_browser_process->local_state(); | |
| 75 local_state->ClearPref(prefs::kRebootAfterUpdate); | |
| 76 } | |
| 77 } | |
| 78 | |
| 79 void StartRestoreAfterCrashSession(Profile* user_profile, | |
| 80 const std::string& login_user_id) { | |
| 81 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | |
| 82 | |
| 83 session_manager::SessionManager::Get()->SetSessionState( | |
| 84 session_manager::SessionState::ACTIVE); | |
| 85 | |
| 86 // TODO(nkostylev): Identify tests that do not set this kLoginUser flag but | |
|
achuithb
2016/10/27 21:18:52
Let's remove nkostylev here.
xiyuan
2016/10/27 21:31:13
Done.
| |
| 87 // still rely on "stub user" session. Keeping existing behavior to avoid | |
| 88 // breaking tests. | |
| 89 if (command_line->HasSwitch(chromeos::switches::kLoginUser)) { | |
| 90 // This is done in SessionManager::OnProfileCreated during normal login. | |
| 91 UserSessionManager* user_session_mgr = UserSessionManager::GetInstance(); | |
| 92 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); | |
| 93 const user_manager::User* user = user_manager->GetActiveUser(); | |
| 94 if (!user) { | |
| 95 // This is possible if crash occured after profile removal | |
| 96 // (see crbug.com/178290 for some more info). | |
| 97 LOG(ERROR) << "Could not get active user after crash."; | |
| 98 return; | |
| 99 } | |
| 100 user_session_mgr->InitRlz(user_profile); | |
| 101 user_session_mgr->InitializeCerts(user_profile); | |
| 102 user_session_mgr->InitializeCRLSetFetcher(user); | |
| 103 user_session_mgr->InitializeCertificateTransparencyComponents(user); | |
| 104 | |
| 105 if (arc::ArcBridgeService::GetEnabled( | |
| 106 base::CommandLine::ForCurrentProcess())) { | |
| 107 DCHECK(arc::ArcServiceManager::Get()); | |
| 108 std::unique_ptr<BooleanPrefMember> arc_enabled_pref = | |
| 109 base::MakeUnique<BooleanPrefMember>(); | |
| 110 arc_enabled_pref->Init(prefs::kArcEnabled, user_profile->GetPrefs()); | |
| 111 arc::ArcServiceManager::Get()->OnPrimaryUserProfilePrepared( | |
| 112 multi_user_util::GetAccountIdFromProfile(user_profile), | |
| 113 std::move(arc_enabled_pref)); | |
| 114 DCHECK(arc::ArcAuthService::Get()); | |
| 115 arc::ArcAuthService::Get()->OnPrimaryUserProfilePrepared(user_profile); | |
| 116 } | |
| 117 | |
| 118 // Send the PROFILE_PREPARED notification and call SessionStarted() | |
| 119 // so that the Launcher and other Profile dependent classes are created. | |
| 120 content::NotificationService::current()->Notify( | |
| 121 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, | |
| 122 content::NotificationService::AllSources(), | |
| 123 content::Details<Profile>(user_profile)); | |
| 124 | |
| 125 // This call will set session state to SESSION_STATE_ACTIVE (same one). | |
| 126 session_manager::SessionManager::Get()->SessionStarted(); | |
| 127 | |
| 128 // Now is the good time to retrieve other logged in users for this session. | |
| 129 // First user has been already marked as logged in and active in | |
| 130 // PreProfileInit(). Restore sessions for other users in the background. | |
| 131 user_session_mgr->RestoreActiveSessions(); | |
| 132 } | |
| 133 | |
| 134 bool is_running_test = command_line->HasSwitch(::switches::kTestName) || | |
| 135 command_line->HasSwitch(::switches::kTestType); | |
| 136 | |
| 137 if (!is_running_test) { | |
| 138 // Enable CrasAudioHandler logging when chrome restarts after crashing. | |
| 139 if (chromeos::CrasAudioHandler::IsInitialized()) | |
| 140 chromeos::CrasAudioHandler::Get()->LogErrors(); | |
| 141 | |
| 142 // We did not log in (we crashed or are debugging), so we need to | |
| 143 // restore Sync. | |
| 144 UserSessionManager::GetInstance()->RestoreAuthenticationSession( | |
| 145 user_profile); | |
| 146 } | |
| 147 } | |
| 148 | |
| 149 void StartStubLoginSession(Profile* user_profile, | |
| 150 const std::string& login_user_id) { | |
| 151 session_manager::SessionManager::Get()->SetSessionState( | |
| 152 session_manager::SessionState::ACTIVE); | |
| 153 | |
| 154 // For dev machines and stub user emulate as if sync has been initialized. | |
| 155 SigninManagerFactory::GetForProfile(user_profile) | |
| 156 ->SetAuthenticatedAccountInfo(login_user_id, login_user_id); | |
| 157 StartRestoreAfterCrashSession(user_profile, login_user_id); | |
| 158 } | |
| 159 | |
| 39 } // namespace | 160 } // namespace |
| 40 | 161 |
| 41 // static | 162 ChromeSessionManager::ChromeSessionManager() {} |
| 42 std::unique_ptr<session_manager::SessionManager> | 163 ChromeSessionManager::~ChromeSessionManager() {} |
| 43 ChromeSessionManager::CreateSessionManager( | 164 |
| 165 void ChromeSessionManager::Initialize( | |
| 44 const base::CommandLine& parsed_command_line, | 166 const base::CommandLine& parsed_command_line, |
| 45 Profile* profile, | 167 Profile* profile, |
| 46 bool is_running_test) { | 168 bool is_running_test) { |
| 47 // Tests should be able to tune login manager before showing it. Thus only | 169 // Tests should be able to tune login manager before showing it. Thus only |
| 48 // show login UI (login and out-of-box) in normal (non-testing) mode with | 170 // show login UI (login and out-of-box) in normal (non-testing) mode with |
| 49 // --login-manager switch and if test passed --force-login-manager-in-tests. | 171 // --login-manager switch and if test passed --force-login-manager-in-tests. |
| 50 bool force_login_screen_in_test = | 172 bool force_login_screen_in_test = |
| 51 parsed_command_line.HasSwitch(switches::kForceLoginManagerInTests); | 173 parsed_command_line.HasSwitch(switches::kForceLoginManagerInTests); |
| 52 | 174 |
| 53 const std::string cryptohome_id = | 175 const std::string cryptohome_id = |
| 54 parsed_command_line.GetSwitchValueASCII(switches::kLoginUser); | 176 parsed_command_line.GetSwitchValueASCII(switches::kLoginUser); |
| 55 const AccountId login_account_id( | 177 const AccountId login_account_id( |
| 56 cryptohome::Identification::FromString(cryptohome_id).GetAccountId()); | 178 cryptohome::Identification::FromString(cryptohome_id).GetAccountId()); |
| 57 | 179 |
| 58 KioskAppManager::RemoveObsoleteCryptohomes(); | 180 KioskAppManager::RemoveObsoleteCryptohomes(); |
| 59 | 181 |
| 60 if (ShouldAutoLaunchKioskApp(parsed_command_line)) { | 182 if (ShouldAutoLaunchKioskApp(parsed_command_line)) { |
| 61 VLOG(1) << "Starting Chrome with KioskAutoLauncherSessionManagerDelegate"; | 183 VLOG(1) << "Starting Chrome with kiosk auto launch."; |
| 62 return std::unique_ptr<session_manager::SessionManager>( | 184 StartKioskSession(); |
| 63 new ChromeSessionManager( | 185 return; |
| 64 new KioskAutoLauncherSessionManagerDelegate())); | |
| 65 } else if (parsed_command_line.HasSwitch(switches::kLoginManager) && | |
| 66 (!is_running_test || force_login_screen_in_test)) { | |
| 67 VLOG(1) << "Starting Chrome with LoginOobeSessionManagerDelegate"; | |
| 68 return std::unique_ptr<session_manager::SessionManager>( | |
| 69 new ChromeSessionManager(new LoginOobeSessionManagerDelegate())); | |
| 70 } else if (!base::SysInfo::IsRunningOnChromeOS() && | |
| 71 login_account_id == login::StubAccountId()) { | |
| 72 VLOG(1) << "Starting Chrome with StubLoginSessionManagerDelegate"; | |
| 73 return std::unique_ptr<session_manager::SessionManager>( | |
| 74 new ChromeSessionManager(new StubLoginSessionManagerDelegate( | |
| 75 profile, login_account_id.GetUserEmail()))); | |
| 76 } else { | |
| 77 VLOG(1) << "Starting Chrome with RestoreAfterCrashSessionManagerDelegate"; | |
| 78 // Restarting Chrome inside existing user session. Possible cases: | |
| 79 // 1. Chrome is restarted after crash. | |
| 80 // 2. Chrome is restarted for Guest session. | |
| 81 // 3. Chrome is started in browser_tests skipping the login flow. | |
| 82 // 4. Chrome is started on dev machine i.e. not on Chrome OS device w/o | |
| 83 // login flow. In that case --login-user=[chromeos::login::kStubUser] is | |
| 84 // added. See PreEarlyInitialization(). | |
| 85 return std::unique_ptr<session_manager::SessionManager>( | |
| 86 new ChromeSessionManager(new RestoreAfterCrashSessionManagerDelegate( | |
| 87 profile, login_account_id.GetUserEmail()))); | |
| 88 } | 186 } |
| 89 } | |
| 90 | 187 |
| 91 ChromeSessionManager::ChromeSessionManager( | 188 if (parsed_command_line.HasSwitch(switches::kLoginManager) && |
| 92 session_manager::SessionManagerDelegate* delegate) { | 189 (!is_running_test || force_login_screen_in_test)) { |
| 93 Initialize(delegate); | 190 VLOG(1) << "Starting Chrome with login/oobe screen."; |
| 94 } | 191 StartLoginOobeSession(); |
| 192 return; | |
| 193 } | |
| 95 | 194 |
| 96 ChromeSessionManager::~ChromeSessionManager() { | 195 if (!base::SysInfo::IsRunningOnChromeOS() && |
| 196 login_account_id == login::StubAccountId()) { | |
| 197 VLOG(1) << "Starting Chrome with stub login."; | |
| 198 StartStubLoginSession(profile, login_account_id.GetUserEmail()); | |
| 199 return; | |
| 200 } | |
| 201 | |
| 202 VLOG(1) << "Starting Chrome with restart after crash session."; | |
| 203 // Restarting Chrome inside existing user session. Possible cases: | |
| 204 // 1. Chrome is restarted after crash. | |
| 205 // 2. Chrome is restarted for Guest session. | |
| 206 // 3. Chrome is started in browser_tests skipping the login flow. | |
| 207 // 4. Chrome is started on dev machine i.e. not on Chrome OS device w/o | |
| 208 // login flow. In that case --login-user=[chromeos::login::kStubUser] is | |
| 209 // added. See PreEarlyInitialization(). | |
| 210 StartRestoreAfterCrashSession(profile, login_account_id.GetUserEmail()); | |
| 97 } | 211 } |
| 98 | 212 |
| 99 void ChromeSessionManager::SessionStarted() { | 213 void ChromeSessionManager::SessionStarted() { |
| 100 session_manager::SessionManager::SessionStarted(); | 214 session_manager::SessionManager::SessionStarted(); |
| 101 SetSessionState(session_manager::SessionState::ACTIVE); | 215 SetSessionState(session_manager::SessionState::ACTIVE); |
| 102 | 216 |
| 103 // Notifies UserManager so that it can update login state. | 217 // Notifies UserManager so that it can update login state. |
| 104 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); | 218 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); |
| 105 if (user_manager) | 219 if (user_manager) |
| 106 user_manager->OnSessionStarted(); | 220 user_manager->OnSessionStarted(); |
| 107 | 221 |
| 108 content::NotificationService::current()->Notify( | 222 content::NotificationService::current()->Notify( |
| 109 chrome::NOTIFICATION_SESSION_STARTED, | 223 chrome::NOTIFICATION_SESSION_STARTED, |
| 110 content::Source<session_manager::SessionManager>(this), | 224 content::Source<session_manager::SessionManager>(this), |
| 111 content::Details<const user_manager::User>( | 225 content::Details<const user_manager::User>( |
| 112 user_manager->GetActiveUser())); | 226 user_manager->GetActiveUser())); |
| 113 } | 227 } |
| 114 | 228 |
| 115 } // namespace chromeos | 229 } // namespace chromeos |
| OLD | NEW |