| 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::kManagedUserId, managed_user_sync_id); | |
| 383 } else if (UserManager::Get()->IsLoggedInAsRegularUser()) { | |
| 384 // Make sure that the google service username is properly set (we do this | |
| 385 // on every sign in, not just the first login, to deal with existing | |
| 386 // profiles that might not have it set yet). | |
| 387 SigninManagerBase* signin_manager = | |
| 388 SigninManagerFactory::GetForProfile(profile); | |
| 389 signin_manager->SetAuthenticatedUsername(user_id); | |
| 390 } | |
| 391 } | |
| 392 | |
| 393 void SessionManager::UserProfileInitialized(Profile* profile, | |
| 394 bool is_incognito_profile) { | |
| 395 if (is_incognito_profile) { | |
| 396 profile->OnLogin(); | |
| 397 // Send the notification before creating the browser so additional objects | |
| 398 // that need the profile (e.g. the launcher) can be created first. | |
| 399 content::NotificationService::current()->Notify( | |
| 400 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, | |
| 401 content::NotificationService::AllSources(), | |
| 402 content::Details<Profile>(profile)); | |
| 403 | |
| 404 if (delegate_) | |
| 405 delegate_->OnProfilePrepared(profile); | |
| 406 | |
| 407 return; | |
| 408 } | |
| 409 | |
| 410 BootTimesLoader* btl = BootTimesLoader::Get(); | |
| 411 btl->AddLoginTimeMarker("UserProfileGotten", false); | |
| 412 | |
| 413 if (user_context_.IsUsingOAuth()) { | |
| 414 // Transfer proxy authentication cache, cookies (optionally) and server | |
| 415 // bound certs from the profile that was used for authentication. This | |
| 416 // profile contains cookies that auth extension should have already put in | |
| 417 // place that will ensure that the newly created session is authenticated | |
| 418 // for the websites that work with the used authentication schema. | |
| 419 ProfileAuthData::Transfer( | |
| 420 authenticator_->authentication_profile(), | |
| 421 profile, | |
| 422 has_web_auth_cookies_, // transfer_cookies | |
| 423 base::Bind(&SessionManager::CompleteProfileCreateAfterAuthTransfer, | |
| 424 AsWeakPtr(), | |
| 425 profile)); | |
| 426 return; | |
| 427 } | |
| 428 | |
| 429 FinalizePrepareProfile(profile); | |
| 430 } | |
| 431 | |
| 432 void SessionManager::CompleteProfileCreateAfterAuthTransfer(Profile* profile) { | |
| 433 RestoreAuthSessionImpl(profile, has_web_auth_cookies_); | |
| 434 FinalizePrepareProfile(profile); | |
| 435 } | |
| 436 | |
| 437 void SessionManager::FinalizePrepareProfile(Profile* profile) { | |
| 438 BootTimesLoader* btl = BootTimesLoader::Get(); | |
| 439 | |
| 440 // Own TPM device if, for any reason, it has not been done in EULA screen. | |
| 441 CryptohomeClient* client = DBusThreadManager::Get()->GetCryptohomeClient(); | |
| 442 btl->AddLoginTimeMarker("TPMOwn-Start", false); | |
| 443 if (cryptohome_util::TpmIsEnabled() && !cryptohome_util::TpmIsBeingOwned()) { | |
| 444 if (cryptohome_util::TpmIsOwned()) { | |
| 445 client->CallTpmClearStoredPasswordAndBlock(); | |
| 446 } else { | |
| 447 client->TpmCanAttemptOwnership(EmptyVoidDBusMethodCallback()); | |
| 448 } | |
| 449 } | |
| 450 btl->AddLoginTimeMarker("TPMOwn-End", false); | |
| 451 | |
| 452 UserManager* user_manager = UserManager::Get(); | |
| 453 if (user_manager->IsLoggedInAsRegularUser()) { | |
| 454 SAMLOfflineSigninLimiter* saml_offline_signin_limiter = | |
| 455 SAMLOfflineSigninLimiterFactory::GetForProfile(profile); | |
| 456 if (saml_offline_signin_limiter) | |
| 457 saml_offline_signin_limiter->SignedIn(user_context_.GetAuthFlow()); | |
| 458 } | |
| 459 | |
| 460 profile->OnLogin(); | |
| 461 | |
| 462 // Send the notification before creating the browser so additional objects | |
| 463 // that need the profile (e.g. the launcher) can be created first. | |
| 464 content::NotificationService::current()->Notify( | |
| 465 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, | |
| 466 content::NotificationService::AllSources(), | |
| 467 content::Details<Profile>(profile)); | |
| 468 | |
| 469 // Initialize RLZ only for primary user. | |
| 470 if (user_manager->GetPrimaryUser() == | |
| 471 user_manager->GetUserByProfile(profile)) { | |
| 472 InitRlz(profile); | |
| 473 } | |
| 474 | |
| 475 // TODO(altimofeev): This pointer should probably never be NULL, but it looks | |
| 476 // like LoginUtilsImpl::OnProfileCreated() may be getting called before | |
| 477 // SessionManager::PrepareProfile() has set |delegate_| when Chrome is killed | |
| 478 // during shutdown in tests -- see http://crosbug.com/18269. Replace this | |
| 479 // 'if' statement with a CHECK(delegate_) once the underlying issue is | |
| 480 // resolved. | |
| 481 if (delegate_) | |
| 482 delegate_->OnProfilePrepared(profile); | |
| 483 } | |
| 484 | |
| 485 void SessionManager::InitSessionRestoreStrategy() { | |
| 486 CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
| 487 bool in_app_mode = chrome::IsRunningInForcedAppMode(); | |
| 488 | |
| 489 // Are we in kiosk app mode? | |
| 490 if (in_app_mode) { | |
| 491 if (command_line->HasSwitch(::switches::kAppModeOAuth2Token)) { | |
| 492 oauth2_refresh_token_ = command_line->GetSwitchValueASCII( | |
| 493 ::switches::kAppModeOAuth2Token); | |
| 494 } | |
| 495 | |
| 496 if (command_line->HasSwitch(::switches::kAppModeAuthCode)) { | |
| 497 user_context_.SetAuthCode(command_line->GetSwitchValueASCII( | |
| 498 ::switches::kAppModeAuthCode)); | |
| 499 } | |
| 500 | |
| 501 DCHECK(!has_web_auth_cookies_); | |
| 502 if (!user_context_.GetAuthCode().empty()) { | |
| 503 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE; | |
| 504 } else if (!oauth2_refresh_token_.empty()) { | |
| 505 session_restore_strategy_ = | |
| 506 OAuth2LoginManager::RESTORE_FROM_PASSED_OAUTH2_REFRESH_TOKEN; | |
| 507 } else { | |
| 508 session_restore_strategy_ = | |
| 509 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN; | |
| 510 } | |
| 511 return; | |
| 512 } | |
| 513 | |
| 514 if (has_web_auth_cookies_) { | |
| 515 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR; | |
| 516 } else if (!user_context_.GetAuthCode().empty()) { | |
| 517 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE; | |
| 518 } else { | |
| 519 session_restore_strategy_ = | |
| 520 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN; | |
| 521 } | |
| 522 } | |
| 523 | |
| 524 void SessionManager::RestoreAuthSessionImpl(Profile* profile, | |
| 525 bool restore_from_auth_cookies) { | |
| 526 CHECK((authenticator_.get() && authenticator_->authentication_profile()) || | |
| 527 !restore_from_auth_cookies); | |
| 528 | |
| 529 if (chrome::IsRunningInForcedAppMode() || | |
| 530 CommandLine::ForCurrentProcess()->HasSwitch( | |
| 531 chromeos::switches::kOobeSkipPostLogin)) { | |
| 532 return; | |
| 533 } | |
| 534 | |
| 535 exit_after_session_restore_ = false; | |
| 536 | |
| 537 // Remove legacy OAuth1 token if we have one. If it's valid, we should already | |
| 538 // have OAuth2 refresh token in OAuth2TokenService that could be used to | |
| 539 // retrieve all other tokens and user_context. | |
| 540 OAuth2LoginManager* login_manager = | |
| 541 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile); | |
| 542 login_manager->AddObserver(this); | |
| 543 login_manager->RestoreSession( | |
| 544 authenticator_.get() && authenticator_->authentication_profile() | |
| 545 ? authenticator_->authentication_profile()->GetRequestContext() | |
| 546 : NULL, | |
| 547 session_restore_strategy_, | |
| 548 oauth2_refresh_token_, | |
| 549 user_context_.GetAuthCode()); | |
| 550 } | |
| 551 | |
| 552 void SessionManager::InitRlzImpl(Profile* profile, bool disabled) { | |
| 553 #if defined(ENABLE_RLZ) | |
| 554 PrefService* local_state = g_browser_process->local_state(); | |
| 555 if (disabled) { | |
| 556 // Empty brand code means an organic install (no RLZ pings are sent). | |
| 557 google_brand::chromeos::ClearBrandForCurrentSession(); | |
| 558 } | |
| 559 if (disabled != local_state->GetBoolean(prefs::kRLZDisabled)) { | |
| 560 // When switching to RLZ enabled/disabled state, clear all recorded events. | |
| 561 RLZTracker::ClearRlzState(); | |
| 562 local_state->SetBoolean(prefs::kRLZDisabled, disabled); | |
| 563 } | |
| 564 // Init the RLZ library. | |
| 565 int ping_delay = profile->GetPrefs()->GetInteger( | |
| 566 first_run::GetPingDelayPrefName().c_str()); | |
| 567 // Negative ping delay means to send ping immediately after a first search is | |
| 568 // recorded. | |
| 569 RLZTracker::InitRlzFromProfileDelayed( | |
| 570 profile, UserManager::Get()->IsCurrentUserNew(), | |
| 571 ping_delay < 0, base::TimeDelta::FromMilliseconds(abs(ping_delay))); | |
| 572 if (delegate_) | |
| 573 delegate_->OnRlzInitialized(); | |
| 574 #endif | |
| 575 } | |
| 576 | |
| 577 } // namespace chromeos | |
| OLD | NEW |