OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/chromeos/login/session/session_manager.h" |
| 6 |
| 7 #include <string> |
| 8 |
| 9 #include "base/base_paths.h" |
| 10 #include "base/bind.h" |
| 11 #include "base/command_line.h" |
| 12 #include "base/logging.h" |
| 13 #include "base/path_service.h" |
| 14 #include "base/prefs/pref_member.h" |
| 15 #include "base/prefs/pref_registry_simple.h" |
| 16 #include "base/prefs/pref_service.h" |
| 17 #include "base/strings/string16.h" |
| 18 #include "base/sys_info.h" |
| 19 #include "base/task_runner_util.h" |
| 20 #include "base/threading/worker_pool.h" |
| 21 #include "chrome/browser/app_mode/app_mode_utils.h" |
| 22 #include "chrome/browser/browser_process.h" |
| 23 #include "chrome/browser/chrome_notification_types.h" |
| 24 #include "chrome/browser/chromeos/boot_times_loader.h" |
| 25 #include "chrome/browser/chromeos/input_method/input_method_util.h" |
| 26 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h" |
| 27 #include "chrome/browser/chromeos/login/profile_auth_data.h" |
| 28 #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.h" |
| 29 #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter_factory
.h" |
| 30 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h" |
| 31 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h" |
| 32 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h" |
| 33 #include "chrome/browser/chromeos/login/users/user.h" |
| 34 #include "chrome/browser/chromeos/login/users/user_manager.h" |
| 35 #include "chrome/browser/first_run/first_run.h" |
| 36 #include "chrome/browser/google/google_brand_chromeos.h" |
| 37 #include "chrome/browser/lifetime/application_lifetime.h" |
| 38 #include "chrome/browser/profiles/profile.h" |
| 39 #include "chrome/browser/profiles/profile_manager.h" |
| 40 #include "chrome/browser/rlz/rlz.h" |
| 41 #include "chrome/browser/signin/signin_manager_factory.h" |
| 42 #include "chrome/common/chrome_switches.h" |
| 43 #include "chrome/common/logging_chrome.h" |
| 44 #include "chrome/common/pref_names.h" |
| 45 #include "chromeos/chromeos_switches.h" |
| 46 #include "chromeos/cryptohome/cryptohome_util.h" |
| 47 #include "chromeos/dbus/cryptohome_client.h" |
| 48 #include "chromeos/dbus/dbus_thread_manager.h" |
| 49 #include "chromeos/dbus/session_manager_client.h" |
| 50 #include "chromeos/ime/input_method_manager.h" |
| 51 #include "components/signin/core/browser/signin_manager_base.h" |
| 52 #include "content/public/browser/notification_service.h" |
| 53 |
| 54 namespace chromeos { |
| 55 |
| 56 namespace { |
| 57 |
| 58 void InitLocaleAndInputMethodsForNewUser(PrefService* prefs) { |
| 59 // First, we'll set kLanguagePreloadEngines. |
| 60 std::string locale = g_browser_process->GetApplicationLocale(); |
| 61 input_method::InputMethodManager* manager = |
| 62 input_method::InputMethodManager::Get(); |
| 63 std::vector<std::string> input_method_ids; |
| 64 manager->GetInputMethodUtil()->GetFirstLoginInputMethodIds( |
| 65 locale, manager->GetCurrentInputMethod(), &input_method_ids); |
| 66 |
| 67 // Save the input methods in the user's preferences. |
| 68 StringPrefMember language_preload_engines; |
| 69 language_preload_engines.Init(prefs::kLanguagePreloadEngines, prefs); |
| 70 language_preload_engines.SetValue(JoinString(input_method_ids, ',')); |
| 71 BootTimesLoader::Get()->AddLoginTimeMarker("IMEStarted", false); |
| 72 |
| 73 // Second, we'll set kLanguagePreferredLanguages. |
| 74 std::vector<std::string> language_codes; |
| 75 |
| 76 // The current locale should be on the top. |
| 77 language_codes.push_back(locale); |
| 78 |
| 79 // Add input method IDs based on the input methods, as there may be |
| 80 // input methods that are unrelated to the current locale. Example: the |
| 81 // hardware keyboard layout xkb:us::eng is used for logging in, but the |
| 82 // UI language is set to French. In this case, we should set "fr,en" |
| 83 // to the preferred languages preference. |
| 84 std::vector<std::string> candidates; |
| 85 manager->GetInputMethodUtil()->GetLanguageCodesFromInputMethodIds( |
| 86 input_method_ids, &candidates); |
| 87 for (size_t i = 0; i < candidates.size(); ++i) { |
| 88 const std::string& candidate = candidates[i]; |
| 89 // Skip if it's already in language_codes. |
| 90 if (std::count(language_codes.begin(), language_codes.end(), |
| 91 candidate) == 0) { |
| 92 language_codes.push_back(candidate); |
| 93 } |
| 94 } |
| 95 |
| 96 // Save the preferred languages in the user's preferences. |
| 97 StringPrefMember language_preferred_languages; |
| 98 language_preferred_languages.Init(prefs::kLanguagePreferredLanguages, prefs); |
| 99 language_preferred_languages.SetValue(JoinString(language_codes, ',')); |
| 100 } |
| 101 |
| 102 #if defined(ENABLE_RLZ) |
| 103 // Flag file that disables RLZ tracking, when present. |
| 104 const base::FilePath::CharType kRLZDisabledFlagName[] = |
| 105 FILE_PATH_LITERAL(".rlz_disabled"); |
| 106 |
| 107 base::FilePath GetRlzDisabledFlagPath() { |
| 108 base::FilePath homedir; |
| 109 PathService::Get(base::DIR_HOME, &homedir); |
| 110 return homedir.Append(kRLZDisabledFlagName); |
| 111 } |
| 112 #endif |
| 113 |
| 114 } // namespace |
| 115 |
| 116 // static |
| 117 SessionManager* SessionManager::GetInstance() { |
| 118 return Singleton<SessionManager, |
| 119 DefaultSingletonTraits<SessionManager> >::get(); |
| 120 } |
| 121 |
| 122 // static |
| 123 void SessionManager::RegisterPrefs(PrefRegistrySimple* registry) { |
| 124 registry->RegisterStringPref(prefs::kRLZBrand, std::string()); |
| 125 registry->RegisterBooleanPref(prefs::kRLZDisabled, false); |
| 126 } |
| 127 |
| 128 SessionManager::SessionManager() |
| 129 : delegate_(NULL), |
| 130 has_web_auth_cookies_(false), |
| 131 exit_after_session_restore_(false), |
| 132 session_restore_strategy_( |
| 133 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN) { |
| 134 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); |
| 135 } |
| 136 |
| 137 SessionManager::~SessionManager() { |
| 138 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); |
| 139 } |
| 140 |
| 141 void SessionManager::OnSessionRestoreStateChanged( |
| 142 Profile* user_profile, |
| 143 OAuth2LoginManager::SessionRestoreState state) { |
| 144 User::OAuthTokenStatus user_status = User::OAUTH_TOKEN_STATUS_UNKNOWN; |
| 145 OAuth2LoginManager* login_manager = |
| 146 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile); |
| 147 |
| 148 bool connection_error = false; |
| 149 switch (state) { |
| 150 case OAuth2LoginManager::SESSION_RESTORE_DONE: |
| 151 user_status = User::OAUTH2_TOKEN_STATUS_VALID; |
| 152 break; |
| 153 case OAuth2LoginManager::SESSION_RESTORE_FAILED: |
| 154 user_status = User::OAUTH2_TOKEN_STATUS_INVALID; |
| 155 break; |
| 156 case OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED: |
| 157 connection_error = true; |
| 158 break; |
| 159 case OAuth2LoginManager::SESSION_RESTORE_NOT_STARTED: |
| 160 case OAuth2LoginManager::SESSION_RESTORE_PREPARING: |
| 161 case OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS: |
| 162 return; |
| 163 } |
| 164 |
| 165 // We should not be clearing existing token state if that was a connection |
| 166 // error. http://crbug.com/295245 |
| 167 if (!connection_error) { |
| 168 // We are in one of "done" states here. |
| 169 UserManager::Get()->SaveUserOAuthStatus( |
| 170 UserManager::Get()->GetLoggedInUser()->email(), |
| 171 user_status); |
| 172 } |
| 173 |
| 174 login_manager->RemoveObserver(this); |
| 175 } |
| 176 |
| 177 void SessionManager::OnNewRefreshTokenAvaiable(Profile* user_profile) { |
| 178 // Check if we were waiting to restart chrome. |
| 179 if (!exit_after_session_restore_) |
| 180 return; |
| 181 |
| 182 OAuth2LoginManager* login_manager = |
| 183 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile); |
| 184 login_manager->RemoveObserver(this); |
| 185 |
| 186 // Mark user auth token status as valid. |
| 187 UserManager::Get()->SaveUserOAuthStatus( |
| 188 UserManager::Get()->GetLoggedInUser()->email(), |
| 189 User::OAUTH2_TOKEN_STATUS_VALID); |
| 190 |
| 191 LOG(WARNING) << "Exiting after new refresh token fetched"; |
| 192 |
| 193 // We need to restart cleanly in this case to make sure OAuth2 RT is actually |
| 194 // saved. |
| 195 chrome::AttemptRestart(); |
| 196 } |
| 197 |
| 198 void SessionManager::OnConnectionTypeChanged( |
| 199 net::NetworkChangeNotifier::ConnectionType type) { |
| 200 UserManager* user_manager = UserManager::Get(); |
| 201 if (type == net::NetworkChangeNotifier::CONNECTION_NONE || |
| 202 user_manager->IsLoggedInAsGuest() || !user_manager->IsUserLoggedIn()) { |
| 203 return; |
| 204 } |
| 205 |
| 206 // Need to iterate over all users and their OAuth2 session state. |
| 207 const UserList& users = user_manager->GetLoggedInUsers(); |
| 208 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) { |
| 209 Profile* user_profile = user_manager->GetProfileByUser(*it); |
| 210 bool should_restore_session = |
| 211 pending_restore_sessions_.find((*it)->email()) != |
| 212 pending_restore_sessions_.end(); |
| 213 OAuth2LoginManager* login_manager = |
| 214 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile); |
| 215 if (login_manager->state() == |
| 216 OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) { |
| 217 // If we come online for the first time after successful offline login, |
| 218 // we need to kick off OAuth token verification process again. |
| 219 login_manager->ContinueSessionRestore(); |
| 220 } else if (should_restore_session) { |
| 221 pending_restore_sessions_.erase((*it)->email()); |
| 222 RestoreAuthSessionImpl(user_profile, has_web_auth_cookies_); |
| 223 } |
| 224 } |
| 225 } |
| 226 |
| 227 void SessionManager::StartSession(const UserContext& user_context, |
| 228 scoped_refptr<Authenticator> authenticator, |
| 229 bool has_cookies, |
| 230 bool has_active_session, |
| 231 Delegate* delegate) { |
| 232 authenticator_ = authenticator; |
| 233 delegate_ = delegate; |
| 234 |
| 235 VLOG(1) << "Starting session for " << user_context.GetUserID(); |
| 236 |
| 237 PreStartSession(); |
| 238 CreateUserSession(user_context, has_cookies); |
| 239 |
| 240 if (!has_active_session) |
| 241 StartCrosSession(); |
| 242 |
| 243 // TODO(nkostylev): Notify UserLoggedIn() after profile is actually |
| 244 // ready to be used (http://crbug.com/361528). |
| 245 NotifyUserLoggedIn(); |
| 246 PrepareProfile(); |
| 247 } |
| 248 |
| 249 void SessionManager::RestoreAuthenticationSession(Profile* user_profile) { |
| 250 UserManager* user_manager = UserManager::Get(); |
| 251 // We don't need to restore session for demo/guest/stub/public account users. |
| 252 if (!user_manager->IsUserLoggedIn() || |
| 253 user_manager->IsLoggedInAsGuest() || |
| 254 user_manager->IsLoggedInAsPublicAccount() || |
| 255 user_manager->IsLoggedInAsDemoUser() || |
| 256 user_manager->IsLoggedInAsStub()) { |
| 257 return; |
| 258 } |
| 259 |
| 260 User* user = user_manager->GetUserByProfile(user_profile); |
| 261 DCHECK(user); |
| 262 if (!net::NetworkChangeNotifier::IsOffline()) { |
| 263 pending_restore_sessions_.erase(user->email()); |
| 264 RestoreAuthSessionImpl(user_profile, false); |
| 265 } else { |
| 266 // Even if we're online we should wait till initial |
| 267 // OnConnectionTypeChanged() call. Otherwise starting fetchers too early may |
| 268 // end up canceling all request when initial network connection type is |
| 269 // processed. See http://crbug.com/121643. |
| 270 pending_restore_sessions_.insert(user->email()); |
| 271 } |
| 272 } |
| 273 |
| 274 void SessionManager::InitRlz(Profile* profile) { |
| 275 #if defined(ENABLE_RLZ) |
| 276 if (!g_browser_process->local_state()->HasPrefPath(prefs::kRLZBrand)) { |
| 277 // Read brand code asynchronously from an OEM data and repost ourselves. |
| 278 google_brand::chromeos::InitBrand( |
| 279 base::Bind(&SessionManager::InitRlz, AsWeakPtr(), profile)); |
| 280 return; |
| 281 } |
| 282 base::PostTaskAndReplyWithResult( |
| 283 base::WorkerPool::GetTaskRunner(false), |
| 284 FROM_HERE, |
| 285 base::Bind(&base::PathExists, GetRlzDisabledFlagPath()), |
| 286 base::Bind(&SessionManager::InitRlzImpl, AsWeakPtr(), profile)); |
| 287 #endif |
| 288 } |
| 289 |
| 290 OAuth2LoginManager::SessionRestoreStrategy |
| 291 SessionManager::GetSigninSessionRestoreStrategy() { |
| 292 return session_restore_strategy_; |
| 293 } |
| 294 |
| 295 // static |
| 296 void SessionManager::SetFirstLoginPrefs(PrefService* prefs) { |
| 297 VLOG(1) << "Setting first login prefs"; |
| 298 InitLocaleAndInputMethodsForNewUser(prefs); |
| 299 } |
| 300 |
| 301 void SessionManager::CreateUserSession(const UserContext& user_context, |
| 302 bool has_cookies) { |
| 303 user_context_ = user_context; |
| 304 has_web_auth_cookies_ = has_cookies; |
| 305 InitSessionRestoreStrategy(); |
| 306 } |
| 307 |
| 308 void SessionManager::PreStartSession() { |
| 309 // Switch log file as soon as possible. |
| 310 if (base::SysInfo::IsRunningOnChromeOS()) |
| 311 logging::RedirectChromeLogging(*(CommandLine::ForCurrentProcess())); |
| 312 } |
| 313 |
| 314 void SessionManager::StartCrosSession() { |
| 315 BootTimesLoader* btl = BootTimesLoader::Get(); |
| 316 btl->AddLoginTimeMarker("StartSession-Start", false); |
| 317 DBusThreadManager::Get()->GetSessionManagerClient()-> |
| 318 StartSession(user_context_.GetUserID()); |
| 319 btl->AddLoginTimeMarker("StartSession-End", false); |
| 320 } |
| 321 |
| 322 void SessionManager:: NotifyUserLoggedIn() { |
| 323 BootTimesLoader* btl = BootTimesLoader::Get(); |
| 324 btl->AddLoginTimeMarker("UserLoggedIn-Start", false); |
| 325 UserManager* user_manager = UserManager::Get(); |
| 326 user_manager->UserLoggedIn(user_context_.GetUserID(), |
| 327 user_context_.GetUserIDHash(), |
| 328 false); |
| 329 btl->AddLoginTimeMarker("UserLoggedIn-End", false); |
| 330 } |
| 331 |
| 332 void SessionManager::PrepareProfile() { |
| 333 UserManager* user_manager = UserManager::Get(); |
| 334 bool is_demo_session = |
| 335 DemoAppLauncher::IsDemoAppSession(user_context_.GetUserID()); |
| 336 |
| 337 // TODO(nkostylev): Figure out whether demo session is using the right profile |
| 338 // path or not. See https://codereview.chromium.org/171423009 |
| 339 g_browser_process->profile_manager()->CreateProfileAsync( |
| 340 user_manager->GetUserProfileDir(user_context_.GetUserID()), |
| 341 base::Bind(&SessionManager::OnProfileCreated, AsWeakPtr(), |
| 342 user_context_.GetUserID(), is_demo_session), |
| 343 base::string16(), base::string16(), std::string()); |
| 344 } |
| 345 |
| 346 void SessionManager::OnProfileCreated(const std::string& user_id, |
| 347 bool is_incognito_profile, |
| 348 Profile* profile, |
| 349 Profile::CreateStatus status) { |
| 350 CHECK(profile); |
| 351 |
| 352 switch (status) { |
| 353 case Profile::CREATE_STATUS_CREATED: |
| 354 // Profile created but before initializing extensions and promo resources. |
| 355 InitProfilePreferences(profile, user_id); |
| 356 break; |
| 357 case Profile::CREATE_STATUS_INITIALIZED: |
| 358 // Profile is created, extensions and promo resources are initialized. |
| 359 // At this point all other Chrome OS services will be notified that it is |
| 360 // safe to use this profile. |
| 361 UserProfileInitialized(profile, is_incognito_profile); |
| 362 break; |
| 363 case Profile::CREATE_STATUS_LOCAL_FAIL: |
| 364 case Profile::CREATE_STATUS_REMOTE_FAIL: |
| 365 case Profile::CREATE_STATUS_CANCELED: |
| 366 case Profile::MAX_CREATE_STATUS: |
| 367 NOTREACHED(); |
| 368 break; |
| 369 } |
| 370 } |
| 371 |
| 372 void SessionManager::InitProfilePreferences(Profile* profile, |
| 373 const std::string& user_id) { |
| 374 if (UserManager::Get()->IsCurrentUserNew()) |
| 375 SetFirstLoginPrefs(profile->GetPrefs()); |
| 376 |
| 377 if (UserManager::Get()->IsLoggedInAsLocallyManagedUser()) { |
| 378 User* active_user = UserManager::Get()->GetActiveUser(); |
| 379 std::string managed_user_sync_id = |
| 380 UserManager::Get()->GetSupervisedUserManager()-> |
| 381 GetUserSyncId(active_user->email()); |
| 382 profile->GetPrefs()->SetString(prefs::kSupervisedUserId, |
| 383 managed_user_sync_id); |
| 384 } else if (UserManager::Get()->IsLoggedInAsRegularUser()) { |
| 385 // Make sure that the google service username is properly set (we do this |
| 386 // on every sign in, not just the first login, to deal with existing |
| 387 // profiles that might not have it set yet). |
| 388 SigninManagerBase* signin_manager = |
| 389 SigninManagerFactory::GetForProfile(profile); |
| 390 signin_manager->SetAuthenticatedUsername(user_id); |
| 391 } |
| 392 } |
| 393 |
| 394 void SessionManager::UserProfileInitialized(Profile* profile, |
| 395 bool is_incognito_profile) { |
| 396 if (is_incognito_profile) { |
| 397 profile->OnLogin(); |
| 398 // Send the notification before creating the browser so additional objects |
| 399 // that need the profile (e.g. the launcher) can be created first. |
| 400 content::NotificationService::current()->Notify( |
| 401 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, |
| 402 content::NotificationService::AllSources(), |
| 403 content::Details<Profile>(profile)); |
| 404 |
| 405 if (delegate_) |
| 406 delegate_->OnProfilePrepared(profile); |
| 407 |
| 408 return; |
| 409 } |
| 410 |
| 411 BootTimesLoader* btl = BootTimesLoader::Get(); |
| 412 btl->AddLoginTimeMarker("UserProfileGotten", false); |
| 413 |
| 414 if (user_context_.IsUsingOAuth()) { |
| 415 // Transfer proxy authentication cache, cookies (optionally) and server |
| 416 // bound certs from the profile that was used for authentication. This |
| 417 // profile contains cookies that auth extension should have already put in |
| 418 // place that will ensure that the newly created session is authenticated |
| 419 // for the websites that work with the used authentication schema. |
| 420 ProfileAuthData::Transfer( |
| 421 authenticator_->authentication_profile(), |
| 422 profile, |
| 423 has_web_auth_cookies_, // transfer_cookies |
| 424 base::Bind(&SessionManager::CompleteProfileCreateAfterAuthTransfer, |
| 425 AsWeakPtr(), |
| 426 profile)); |
| 427 return; |
| 428 } |
| 429 |
| 430 FinalizePrepareProfile(profile); |
| 431 } |
| 432 |
| 433 void SessionManager::CompleteProfileCreateAfterAuthTransfer(Profile* profile) { |
| 434 RestoreAuthSessionImpl(profile, has_web_auth_cookies_); |
| 435 FinalizePrepareProfile(profile); |
| 436 } |
| 437 |
| 438 void SessionManager::FinalizePrepareProfile(Profile* profile) { |
| 439 BootTimesLoader* btl = BootTimesLoader::Get(); |
| 440 |
| 441 // Own TPM device if, for any reason, it has not been done in EULA screen. |
| 442 CryptohomeClient* client = DBusThreadManager::Get()->GetCryptohomeClient(); |
| 443 btl->AddLoginTimeMarker("TPMOwn-Start", false); |
| 444 if (cryptohome_util::TpmIsEnabled() && !cryptohome_util::TpmIsBeingOwned()) { |
| 445 if (cryptohome_util::TpmIsOwned()) { |
| 446 client->CallTpmClearStoredPasswordAndBlock(); |
| 447 } else { |
| 448 client->TpmCanAttemptOwnership(EmptyVoidDBusMethodCallback()); |
| 449 } |
| 450 } |
| 451 btl->AddLoginTimeMarker("TPMOwn-End", false); |
| 452 |
| 453 UserManager* user_manager = UserManager::Get(); |
| 454 if (user_manager->IsLoggedInAsRegularUser()) { |
| 455 SAMLOfflineSigninLimiter* saml_offline_signin_limiter = |
| 456 SAMLOfflineSigninLimiterFactory::GetForProfile(profile); |
| 457 if (saml_offline_signin_limiter) |
| 458 saml_offline_signin_limiter->SignedIn(user_context_.GetAuthFlow()); |
| 459 } |
| 460 |
| 461 profile->OnLogin(); |
| 462 |
| 463 // Send the notification before creating the browser so additional objects |
| 464 // that need the profile (e.g. the launcher) can be created first. |
| 465 content::NotificationService::current()->Notify( |
| 466 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, |
| 467 content::NotificationService::AllSources(), |
| 468 content::Details<Profile>(profile)); |
| 469 |
| 470 // Initialize RLZ only for primary user. |
| 471 if (user_manager->GetPrimaryUser() == |
| 472 user_manager->GetUserByProfile(profile)) { |
| 473 InitRlz(profile); |
| 474 } |
| 475 |
| 476 // TODO(altimofeev): This pointer should probably never be NULL, but it looks |
| 477 // like LoginUtilsImpl::OnProfileCreated() may be getting called before |
| 478 // SessionManager::PrepareProfile() has set |delegate_| when Chrome is killed |
| 479 // during shutdown in tests -- see http://crosbug.com/18269. Replace this |
| 480 // 'if' statement with a CHECK(delegate_) once the underlying issue is |
| 481 // resolved. |
| 482 if (delegate_) |
| 483 delegate_->OnProfilePrepared(profile); |
| 484 } |
| 485 |
| 486 void SessionManager::InitSessionRestoreStrategy() { |
| 487 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 488 bool in_app_mode = chrome::IsRunningInForcedAppMode(); |
| 489 |
| 490 // Are we in kiosk app mode? |
| 491 if (in_app_mode) { |
| 492 if (command_line->HasSwitch(::switches::kAppModeOAuth2Token)) { |
| 493 oauth2_refresh_token_ = command_line->GetSwitchValueASCII( |
| 494 ::switches::kAppModeOAuth2Token); |
| 495 } |
| 496 |
| 497 if (command_line->HasSwitch(::switches::kAppModeAuthCode)) { |
| 498 user_context_.SetAuthCode(command_line->GetSwitchValueASCII( |
| 499 ::switches::kAppModeAuthCode)); |
| 500 } |
| 501 |
| 502 DCHECK(!has_web_auth_cookies_); |
| 503 if (!user_context_.GetAuthCode().empty()) { |
| 504 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE; |
| 505 } else if (!oauth2_refresh_token_.empty()) { |
| 506 session_restore_strategy_ = |
| 507 OAuth2LoginManager::RESTORE_FROM_PASSED_OAUTH2_REFRESH_TOKEN; |
| 508 } else { |
| 509 session_restore_strategy_ = |
| 510 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN; |
| 511 } |
| 512 return; |
| 513 } |
| 514 |
| 515 if (has_web_auth_cookies_) { |
| 516 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR; |
| 517 } else if (!user_context_.GetAuthCode().empty()) { |
| 518 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE; |
| 519 } else { |
| 520 session_restore_strategy_ = |
| 521 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN; |
| 522 } |
| 523 } |
| 524 |
| 525 void SessionManager::RestoreAuthSessionImpl(Profile* profile, |
| 526 bool restore_from_auth_cookies) { |
| 527 CHECK((authenticator_.get() && authenticator_->authentication_profile()) || |
| 528 !restore_from_auth_cookies); |
| 529 |
| 530 if (chrome::IsRunningInForcedAppMode() || |
| 531 CommandLine::ForCurrentProcess()->HasSwitch( |
| 532 chromeos::switches::kOobeSkipPostLogin)) { |
| 533 return; |
| 534 } |
| 535 |
| 536 exit_after_session_restore_ = false; |
| 537 |
| 538 // Remove legacy OAuth1 token if we have one. If it's valid, we should already |
| 539 // have OAuth2 refresh token in OAuth2TokenService that could be used to |
| 540 // retrieve all other tokens and user_context. |
| 541 OAuth2LoginManager* login_manager = |
| 542 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile); |
| 543 login_manager->AddObserver(this); |
| 544 login_manager->RestoreSession( |
| 545 authenticator_.get() && authenticator_->authentication_profile() |
| 546 ? authenticator_->authentication_profile()->GetRequestContext() |
| 547 : NULL, |
| 548 session_restore_strategy_, |
| 549 oauth2_refresh_token_, |
| 550 user_context_.GetAuthCode()); |
| 551 } |
| 552 |
| 553 void SessionManager::InitRlzImpl(Profile* profile, bool disabled) { |
| 554 #if defined(ENABLE_RLZ) |
| 555 PrefService* local_state = g_browser_process->local_state(); |
| 556 if (disabled) { |
| 557 // Empty brand code means an organic install (no RLZ pings are sent). |
| 558 google_brand::chromeos::ClearBrandForCurrentSession(); |
| 559 } |
| 560 if (disabled != local_state->GetBoolean(prefs::kRLZDisabled)) { |
| 561 // When switching to RLZ enabled/disabled state, clear all recorded events. |
| 562 RLZTracker::ClearRlzState(); |
| 563 local_state->SetBoolean(prefs::kRLZDisabled, disabled); |
| 564 } |
| 565 // Init the RLZ library. |
| 566 int ping_delay = profile->GetPrefs()->GetInteger( |
| 567 first_run::GetPingDelayPrefName().c_str()); |
| 568 // Negative ping delay means to send ping immediately after a first search is |
| 569 // recorded. |
| 570 RLZTracker::InitRlzFromProfileDelayed( |
| 571 profile, UserManager::Get()->IsCurrentUserNew(), |
| 572 ping_delay < 0, base::TimeDelta::FromMilliseconds(abs(ping_delay))); |
| 573 if (delegate_) |
| 574 delegate_->OnRlzInitialized(); |
| 575 #endif |
| 576 } |
| 577 |
| 578 } // namespace chromeos |
OLD | NEW |