CHECK for LoginDisplayHost instance in ActivateWizard
[chromium-blink-merge.git] / chrome / browser / chromeos / login / session / user_session_manager.cc
blobee137a63f671d94410b5744d6278306e13b7ed4f
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.
5 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
7 #include <string>
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/strings/stringprintf.h"
19 #include "base/sys_info.h"
20 #include "base/task_runner_util.h"
21 #include "base/threading/worker_pool.h"
22 #include "chrome/browser/about_flags.h"
23 #include "chrome/browser/app_mode/app_mode_utils.h"
24 #include "chrome/browser/browser_process.h"
25 #include "chrome/browser/browser_process_platform_part_chromeos.h"
26 #include "chrome/browser/browser_shutdown.h"
27 #include "chrome/browser/chrome_notification_types.h"
28 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
29 #include "chrome/browser/chromeos/base/locale_util.h"
30 #include "chrome/browser/chromeos/boot_times_loader.h"
31 #include "chrome/browser/chromeos/first_run/first_run.h"
32 #include "chrome/browser/chromeos/input_method/input_method_util.h"
33 #include "chrome/browser/chromeos/login/chrome_restart_request.h"
34 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
35 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
36 #include "chrome/browser/chromeos/login/profile_auth_data.h"
37 #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.h"
38 #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter_factory.h"
39 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h"
40 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h"
41 #include "chrome/browser/chromeos/login/startup_utils.h"
42 #include "chrome/browser/chromeos/login/ui/input_events_blocker.h"
43 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
44 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
45 #include "chrome/browser/chromeos/login/user_flow.h"
46 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
47 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
48 #include "chrome/browser/chromeos/login/wizard_controller.h"
49 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
50 #include "chrome/browser/chromeos/profiles/profile_helper.h"
51 #include "chrome/browser/chromeos/settings/cros_settings.h"
52 #include "chrome/browser/first_run/first_run.h"
53 #include "chrome/browser/google/google_brand_chromeos.h"
54 #include "chrome/browser/lifetime/application_lifetime.h"
55 #include "chrome/browser/net/crl_set_fetcher.h"
56 #include "chrome/browser/net/nss_context.h"
57 #include "chrome/browser/pref_service_flags_storage.h"
58 #include "chrome/browser/prefs/session_startup_pref.h"
59 #include "chrome/browser/profiles/profile.h"
60 #include "chrome/browser/profiles/profile_manager.h"
61 #include "chrome/browser/rlz/rlz.h"
62 #include "chrome/browser/signin/account_tracker_service_factory.h"
63 #include "chrome/browser/signin/easy_unlock_service.h"
64 #include "chrome/browser/signin/signin_manager_factory.h"
65 #include "chrome/browser/ui/app_list/start_page_service.h"
66 #include "chrome/browser/ui/startup/startup_browser_creator.h"
67 #include "chrome/common/chrome_switches.h"
68 #include "chrome/common/logging_chrome.h"
69 #include "chrome/common/pref_names.h"
70 #include "chromeos/cert_loader.h"
71 #include "chromeos/chromeos_switches.h"
72 #include "chromeos/cryptohome/cryptohome_util.h"
73 #include "chromeos/dbus/cryptohome_client.h"
74 #include "chromeos/dbus/dbus_thread_manager.h"
75 #include "chromeos/dbus/session_manager_client.h"
76 #include "chromeos/ime/input_method_manager.h"
77 #include "chromeos/login/user_names.h"
78 #include "chromeos/network/portal_detector/network_portal_detector.h"
79 #include "chromeos/network/portal_detector/network_portal_detector_strategy.h"
80 #include "chromeos/settings/cros_settings_names.h"
81 #include "components/component_updater/component_updater_service.h"
82 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
83 #include "components/session_manager/core/session_manager.h"
84 #include "components/signin/core/browser/account_tracker_service.h"
85 #include "components/signin/core/browser/signin_manager_base.h"
86 #include "components/user_manager/user.h"
87 #include "components/user_manager/user_manager.h"
88 #include "components/user_manager/user_type.h"
89 #include "content/public/browser/browser_thread.h"
90 #include "content/public/browser/notification_service.h"
91 #include "url/gurl.h"
93 #if defined(USE_ATHENA)
94 #include "athena/main/public/athena_launcher.h"
95 #endif
97 namespace chromeos {
99 namespace {
101 // ChromeVox tutorial URL (used in place of "getting started" url when
102 // accessibility is enabled).
103 const char kChromeVoxTutorialURLPattern[] =
104 "http://www.chromevox.com/tutorial/index.html?lang=%s";
106 void InitLocaleAndInputMethodsForNewUser(
107 UserSessionManager* session_manager,
108 Profile* profile,
109 const std::string& public_session_locale,
110 const std::string& public_session_input_method) {
111 PrefService* prefs = profile->GetPrefs();
112 std::string locale;
113 if (!public_session_locale.empty()) {
114 // If this is a public session and the user chose a |public_session_locale|,
115 // write it to |prefs| so that the UI switches to it.
116 locale = public_session_locale;
117 prefs->SetString(prefs::kApplicationLocale, locale);
119 // Suppress the locale change dialog.
120 prefs->SetString(prefs::kApplicationLocaleAccepted, locale);
121 } else {
122 // Otherwise, assume that the session will use the current UI locale.
123 locale = g_browser_process->GetApplicationLocale();
126 // First, we'll set kLanguagePreloadEngines.
127 input_method::InputMethodManager* manager =
128 input_method::InputMethodManager::Get();
129 std::vector<std::string> input_method_ids;
131 if (!public_session_input_method.empty()) {
132 // If this is a public session and the user chose a
133 // |public_session_input_method|, set kLanguagePreloadEngines to this input
134 // method only.
135 input_method_ids.push_back(public_session_input_method);
136 } else {
137 // Otherwise, set kLanguagePreloadEngines to a list of input methods derived
138 // from the |locale| and the currently active input method.
139 manager->GetInputMethodUtil()->GetFirstLoginInputMethodIds(
140 locale,
141 session_manager->GetDefaultIMEState(profile)->GetCurrentInputMethod(),
142 &input_method_ids);
145 // Save the input methods in the user's preferences.
146 StringPrefMember language_preload_engines;
147 language_preload_engines.Init(prefs::kLanguagePreloadEngines, prefs);
148 language_preload_engines.SetValue(JoinString(input_method_ids, ','));
149 BootTimesLoader::Get()->AddLoginTimeMarker("IMEStarted", false);
151 // Second, we'll set kLanguagePreferredLanguages.
152 std::vector<std::string> language_codes;
154 // The current locale should be on the top.
155 language_codes.push_back(locale);
157 // Add input method IDs based on the input methods, as there may be
158 // input methods that are unrelated to the current locale. Example: the
159 // hardware keyboard layout xkb:us::eng is used for logging in, but the
160 // UI language is set to French. In this case, we should set "fr,en"
161 // to the preferred languages preference.
162 std::vector<std::string> candidates;
163 manager->GetInputMethodUtil()->GetLanguageCodesFromInputMethodIds(
164 input_method_ids, &candidates);
165 for (size_t i = 0; i < candidates.size(); ++i) {
166 const std::string& candidate = candidates[i];
167 // Skip if it's already in language_codes.
168 if (std::count(language_codes.begin(), language_codes.end(),
169 candidate) == 0) {
170 language_codes.push_back(candidate);
174 // Save the preferred languages in the user's preferences.
175 StringPrefMember language_preferred_languages;
176 language_preferred_languages.Init(prefs::kLanguagePreferredLanguages, prefs);
177 language_preferred_languages.SetValue(JoinString(language_codes, ','));
180 #if defined(ENABLE_RLZ)
181 // Flag file that disables RLZ tracking, when present.
182 const base::FilePath::CharType kRLZDisabledFlagName[] =
183 FILE_PATH_LITERAL(".rlz_disabled");
185 base::FilePath GetRlzDisabledFlagPath() {
186 base::FilePath homedir;
187 PathService::Get(base::DIR_HOME, &homedir);
188 return homedir.Append(kRLZDisabledFlagName);
190 #endif
192 // Callback to GetNSSCertDatabaseForProfile. It starts CertLoader using the
193 // provided NSS database. It must be called for primary user only.
194 void OnGetNSSCertDatabaseForUser(net::NSSCertDatabase* database) {
195 if (!CertLoader::IsInitialized())
196 return;
198 CertLoader::Get()->StartWithNSSDB(database);
201 // Returns new CommandLine with per-user flags.
202 CommandLine CreatePerSessionCommandLine(Profile* profile) {
203 CommandLine user_flags(CommandLine::NO_PROGRAM);
204 about_flags::PrefServiceFlagsStorage flags_storage_(profile->GetPrefs());
205 about_flags::ConvertFlagsToSwitches(&flags_storage_, &user_flags,
206 about_flags::kAddSentinels);
207 return user_flags;
210 // Returns true if restart is needed to apply per-session flags.
211 bool NeedRestartToApplyPerSessionFlags(
212 const CommandLine& user_flags,
213 std::set<CommandLine::StringType>* out_command_line_difference) {
214 // Don't restart browser if it is not first profile in session.
215 if (user_manager::UserManager::Get()->GetLoggedInUsers().size() != 1)
216 return false;
218 // Only restart if needed and if not going into managed mode.
219 if (user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser())
220 return false;
222 if (about_flags::AreSwitchesIdenticalToCurrentCommandLine(
223 user_flags, *CommandLine::ForCurrentProcess(),
224 out_command_line_difference)) {
225 return false;
228 return true;
231 bool CanPerformEarlyRestart() {
232 // Desktop build is used for development only. Early restart is not supported.
233 if (!base::SysInfo::IsRunningOnChromeOS())
234 return false;
236 if (!ChromeUserManager::Get()
237 ->GetCurrentUserFlow()
238 ->SupportsEarlyRestartToApplyFlags()) {
239 return false;
242 const ExistingUserController* controller =
243 ExistingUserController::current_controller();
244 if (!controller)
245 return true;
247 // Early restart is possible only if OAuth token is up to date.
249 if (controller->password_changed())
250 return false;
252 if (controller->auth_mode() != LoginPerformer::AUTH_MODE_INTERNAL)
253 return false;
255 // No early restart if Easy unlock key needs to be updated.
256 if (UserSessionManager::GetInstance()->NeedsToUpdateEasyUnlockKeys())
257 return false;
259 return true;
262 void LogCustomSwitches(const std::set<std::string>& switches) {
263 if (!VLOG_IS_ON(1))
264 return;
265 for (std::set<std::string>::const_iterator it = switches.begin();
266 it != switches.end(); ++it) {
267 VLOG(1) << "Switch leading to restart: '" << *it << "'";
271 } // namespace
273 UserSessionManagerDelegate::~UserSessionManagerDelegate() {
276 void UserSessionStateObserver::PendingUserSessionsRestoreFinished() {
279 UserSessionStateObserver::~UserSessionStateObserver() {
282 // static
283 UserSessionManager* UserSessionManager::GetInstance() {
284 return Singleton<UserSessionManager,
285 DefaultSingletonTraits<UserSessionManager> >::get();
288 // static
289 void UserSessionManager::OverrideHomedir() {
290 // Override user homedir, check for ProfileManager being initialized as
291 // it may not exist in unit tests.
292 if (g_browser_process->profile_manager()) {
293 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
294 if (user_manager->GetLoggedInUsers().size() == 1) {
295 base::FilePath homedir = ProfileHelper::GetProfilePathByUserIdHash(
296 user_manager->GetPrimaryUser()->username_hash());
297 // This path has been either created by cryptohome (on real Chrome OS
298 // device) or by ProfileManager (on chromeos=1 desktop builds).
299 PathService::OverrideAndCreateIfNeeded(base::DIR_HOME,
300 homedir,
301 true /* path is absolute */,
302 false /* don't create */);
307 // static
308 void UserSessionManager::RegisterPrefs(PrefRegistrySimple* registry) {
309 registry->RegisterStringPref(prefs::kRLZBrand, std::string());
310 registry->RegisterBooleanPref(prefs::kRLZDisabled, false);
313 UserSessionManager::UserSessionManager()
314 : delegate_(NULL),
315 has_auth_cookies_(false),
316 user_sessions_restored_(false),
317 user_sessions_restore_in_progress_(false),
318 exit_after_session_restore_(false),
319 session_restore_strategy_(
320 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN),
321 running_easy_unlock_key_ops_(false) {
322 net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
323 user_manager::UserManager::Get()->AddSessionStateObserver(this);
326 UserSessionManager::~UserSessionManager() {
327 // UserManager is destroyed before singletons, so we need to check if it
328 // still exists.
329 // TODO(nkostylev): fix order of destruction of UserManager
330 // / UserSessionManager objects.
331 if (user_manager::UserManager::IsInitialized())
332 user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
333 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
336 void UserSessionManager::CompleteGuestSessionLogin(const GURL& start_url) {
337 VLOG(1) << "Completing guest session login";
339 // For guest session we ask session_manager to restart Chrome with --bwsi
340 // flag. We keep only some of the arguments of this process.
341 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
342 CommandLine command_line(browser_command_line.GetProgram());
343 std::string cmd_line_str =
344 GetOffTheRecordCommandLine(start_url,
345 StartupUtils::IsOobeCompleted(),
346 browser_command_line,
347 &command_line);
349 // This makes sure that Chrome restarts with no per-session flags. The guest
350 // profile will always have empty set of per-session flags. If this is not
351 // done and device owner has some per-session flags, when Chrome is relaunched
352 // the guest profile session flags will not match the current command line and
353 // another restart will be attempted in order to reset the user flags for the
354 // guest user.
355 const CommandLine user_flags(CommandLine::NO_PROGRAM);
356 if (!about_flags::AreSwitchesIdenticalToCurrentCommandLine(
357 user_flags,
358 *CommandLine::ForCurrentProcess(),
359 NULL)) {
360 DBusThreadManager::Get()->GetSessionManagerClient()->SetFlagsForUser(
361 chromeos::login::kGuestUserName,
362 CommandLine::StringVector());
365 RestartChrome(cmd_line_str);
368 void UserSessionManager::StartSession(
369 const UserContext& user_context,
370 StartSessionType start_session_type,
371 scoped_refptr<Authenticator> authenticator,
372 bool has_auth_cookies,
373 bool has_active_session,
374 UserSessionManagerDelegate* delegate) {
375 authenticator_ = authenticator;
376 delegate_ = delegate;
377 start_session_type_ = start_session_type;
379 VLOG(1) << "Starting session for " << user_context.GetUserID();
381 PreStartSession();
382 CreateUserSession(user_context, has_auth_cookies);
384 if (!has_active_session)
385 StartCrosSession();
387 // TODO(nkostylev): Notify UserLoggedIn() after profile is actually
388 // ready to be used (http://crbug.com/361528).
389 NotifyUserLoggedIn();
390 PrepareProfile();
393 void UserSessionManager::PerformPostUserLoggedInActions() {
394 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
395 if (user_manager->GetLoggedInUsers().size() == 1) {
396 if (NetworkPortalDetector::IsInitialized()) {
397 NetworkPortalDetector::Get()->SetStrategy(
398 PortalDetectorStrategy::STRATEGY_ID_SESSION);
403 void UserSessionManager::RestoreAuthenticationSession(Profile* user_profile) {
404 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
405 // We need to restore session only for logged in GAIA (regular) users.
406 // Note: stub user is a special case that is used for tests, running
407 // linux_chromeos build on dev workstations w/o user_id parameters.
408 // Stub user is considered to be a regular GAIA user but it has special
409 // user_id (kStubUser) and certain services like restoring OAuth session are
410 // explicitly disabled for it.
411 if (!user_manager->IsUserLoggedIn() ||
412 !user_manager->IsLoggedInAsUserWithGaiaAccount() ||
413 user_manager->IsLoggedInAsStub()) {
414 return;
417 user_manager::User* user =
418 ProfileHelper::Get()->GetUserByProfile(user_profile);
419 DCHECK(user);
420 if (!net::NetworkChangeNotifier::IsOffline()) {
421 pending_signin_restore_sessions_.erase(user->email());
422 RestoreAuthSessionImpl(user_profile, false /* has_auth_cookies */);
423 } else {
424 // Even if we're online we should wait till initial
425 // OnConnectionTypeChanged() call. Otherwise starting fetchers too early may
426 // end up canceling all request when initial network connection type is
427 // processed. See http://crbug.com/121643.
428 pending_signin_restore_sessions_.insert(user->email());
432 void UserSessionManager::RestoreActiveSessions() {
433 user_sessions_restore_in_progress_ = true;
434 DBusThreadManager::Get()->GetSessionManagerClient()->RetrieveActiveSessions(
435 base::Bind(&UserSessionManager::OnRestoreActiveSessions, AsWeakPtr()));
438 bool UserSessionManager::UserSessionsRestored() const {
439 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
440 return user_sessions_restored_;
443 bool UserSessionManager::UserSessionsRestoreInProgress() const {
444 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
445 return user_sessions_restore_in_progress_;
448 void UserSessionManager::InitRlz(Profile* profile) {
449 #if defined(ENABLE_RLZ)
450 if (!g_browser_process->local_state()->HasPrefPath(prefs::kRLZBrand)) {
451 // Read brand code asynchronously from an OEM data and repost ourselves.
452 google_brand::chromeos::InitBrand(
453 base::Bind(&UserSessionManager::InitRlz, AsWeakPtr(), profile));
454 return;
456 base::PostTaskAndReplyWithResult(
457 base::WorkerPool::GetTaskRunner(false).get(),
458 FROM_HERE,
459 base::Bind(&base::PathExists, GetRlzDisabledFlagPath()),
460 base::Bind(&UserSessionManager::InitRlzImpl, AsWeakPtr(), profile));
461 #endif
464 void UserSessionManager::SetFirstLoginPrefs(
465 Profile* profile,
466 const std::string& public_session_locale,
467 const std::string& public_session_input_method) {
468 VLOG(1) << "Setting first login prefs";
469 InitLocaleAndInputMethodsForNewUser(
470 this, profile, public_session_locale, public_session_input_method);
473 bool UserSessionManager::GetAppModeChromeClientOAuthInfo(
474 std::string* chrome_client_id, std::string* chrome_client_secret) {
475 if (!chrome::IsRunningInForcedAppMode() ||
476 chrome_client_id_.empty() ||
477 chrome_client_secret_.empty()) {
478 return false;
481 *chrome_client_id = chrome_client_id_;
482 *chrome_client_secret = chrome_client_secret_;
483 return true;
486 void UserSessionManager::SetAppModeChromeClientOAuthInfo(
487 const std::string& chrome_client_id,
488 const std::string& chrome_client_secret) {
489 if (!chrome::IsRunningInForcedAppMode())
490 return;
492 chrome_client_id_ = chrome_client_id;
493 chrome_client_secret_ = chrome_client_secret;
496 void UserSessionManager::DoBrowserLaunch(Profile* profile,
497 LoginDisplayHost* login_host) {
498 DoBrowserLaunchInternal(profile, login_host, false /* locale_pref_checked */);
501 bool UserSessionManager::RespectLocalePreference(
502 Profile* profile,
503 const user_manager::User* user,
504 const locale_util::SwitchLanguageCallback& callback) const {
505 // TODO(alemate): http://crbug.com/288941 : Respect preferred language list in
506 // the Google user profile.
507 if (g_browser_process == NULL)
508 return false;
510 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
511 if (!user || (user_manager->IsUserLoggedIn() &&
512 user != user_manager->GetPrimaryUser())) {
513 return false;
516 // In case of multi-profiles session we don't apply profile locale
517 // because it is unsafe.
518 if (user_manager->GetLoggedInUsers().size() != 1)
519 return false;
521 const PrefService* prefs = profile->GetPrefs();
522 if (prefs == NULL)
523 return false;
525 std::string pref_locale;
526 const std::string pref_app_locale =
527 prefs->GetString(prefs::kApplicationLocale);
528 const std::string pref_bkup_locale =
529 prefs->GetString(prefs::kApplicationLocaleBackup);
531 pref_locale = pref_app_locale;
532 if (pref_locale.empty())
533 pref_locale = pref_bkup_locale;
535 const std::string* account_locale = NULL;
536 if (pref_locale.empty() && user->has_gaia_account()) {
537 if (user->GetAccountLocale() == NULL)
538 return false; // wait until Account profile is loaded.
539 account_locale = user->GetAccountLocale();
540 pref_locale = *account_locale;
542 const std::string global_app_locale =
543 g_browser_process->GetApplicationLocale();
544 if (pref_locale.empty())
545 pref_locale = global_app_locale;
546 DCHECK(!pref_locale.empty());
547 VLOG(1) << "RespectLocalePreference: "
548 << "app_locale='" << pref_app_locale << "', "
549 << "bkup_locale='" << pref_bkup_locale << "', "
550 << (account_locale != NULL
551 ? (std::string("account_locale='") + (*account_locale) +
552 "'. ")
553 : (std::string("account_locale - unused. ")))
554 << " Selected '" << pref_locale << "'";
555 profile->ChangeAppLocale(
556 pref_locale,
557 user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT ?
558 Profile::APP_LOCALE_CHANGED_VIA_PUBLIC_SESSION_LOGIN :
559 Profile::APP_LOCALE_CHANGED_VIA_LOGIN);
561 // Here we don't enable keyboard layouts for normal users. Input methods
562 // are set up when the user first logs in. Then the user may customize the
563 // input methods. Hence changing input methods here, just because the user's
564 // UI language is different from the login screen UI language, is not
565 // desirable. Note that input method preferences are synced, so users can use
566 // their farovite input methods as soon as the preferences are synced.
568 // For Guest mode, user locale preferences will never get initialized.
569 // So input methods should be enabled somewhere.
570 const bool enable_layouts =
571 user_manager::UserManager::Get()->IsLoggedInAsGuest();
572 locale_util::SwitchLanguage(
573 pref_locale, enable_layouts, false /* login_layouts_only */, callback);
575 return true;
578 bool UserSessionManager::RestartToApplyPerSessionFlagsIfNeed(
579 Profile* profile,
580 bool early_restart) {
581 if (ProfileHelper::IsSigninProfile(profile))
582 return false;
584 if (early_restart && !CanPerformEarlyRestart())
585 return false;
587 const CommandLine user_flags(CreatePerSessionCommandLine(profile));
588 std::set<CommandLine::StringType> command_line_difference;
589 if (!NeedRestartToApplyPerSessionFlags(user_flags, &command_line_difference))
590 return false;
592 LogCustomSwitches(command_line_difference);
594 about_flags::ReportCustomFlags("Login.CustomFlags", command_line_difference);
596 CommandLine::StringVector flags;
597 // argv[0] is the program name |CommandLine::NO_PROGRAM|.
598 flags.assign(user_flags.argv().begin() + 1, user_flags.argv().end());
599 LOG(WARNING) << "Restarting to apply per-session flags...";
600 DBusThreadManager::Get()->GetSessionManagerClient()->SetFlagsForUser(
601 user_manager::UserManager::Get()->GetActiveUser()->email(), flags);
602 AttemptRestart(profile);
603 return true;
606 bool UserSessionManager::NeedsToUpdateEasyUnlockKeys() const {
607 return EasyUnlockService::IsSignInEnabled() &&
608 !user_context_.GetUserID().empty() &&
609 user_manager::User::TypeHasGaiaAccount(user_context_.GetUserType()) &&
610 user_context_.GetKey() && !user_context_.GetKey()->GetSecret().empty();
613 bool UserSessionManager::CheckEasyUnlockKeyOps(const base::Closure& callback) {
614 if (!running_easy_unlock_key_ops_)
615 return false;
617 // Assumes only one deferred callback is needed.
618 DCHECK(easy_unlock_key_ops_finished_callback_.is_null());
620 easy_unlock_key_ops_finished_callback_ = callback;
621 return true;
624 void UserSessionManager::AddSessionStateObserver(
625 chromeos::UserSessionStateObserver* observer) {
626 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
627 session_state_observer_list_.AddObserver(observer);
630 void UserSessionManager::RemoveSessionStateObserver(
631 chromeos::UserSessionStateObserver* observer) {
632 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
633 session_state_observer_list_.RemoveObserver(observer);
636 void UserSessionManager::OnSessionRestoreStateChanged(
637 Profile* user_profile,
638 OAuth2LoginManager::SessionRestoreState state) {
639 user_manager::User::OAuthTokenStatus user_status =
640 user_manager::User::OAUTH_TOKEN_STATUS_UNKNOWN;
641 OAuth2LoginManager* login_manager =
642 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile);
644 bool connection_error = false;
645 switch (state) {
646 case OAuth2LoginManager::SESSION_RESTORE_DONE:
647 user_status = user_manager::User::OAUTH2_TOKEN_STATUS_VALID;
648 break;
649 case OAuth2LoginManager::SESSION_RESTORE_FAILED:
650 user_status = user_manager::User::OAUTH2_TOKEN_STATUS_INVALID;
651 break;
652 case OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED:
653 connection_error = true;
654 break;
655 case OAuth2LoginManager::SESSION_RESTORE_NOT_STARTED:
656 case OAuth2LoginManager::SESSION_RESTORE_PREPARING:
657 case OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS:
658 return;
661 // We should not be clearing existing token state if that was a connection
662 // error. http://crbug.com/295245
663 if (!connection_error) {
664 // We are in one of "done" states here.
665 user_manager::UserManager::Get()->SaveUserOAuthStatus(
666 user_manager::UserManager::Get()->GetLoggedInUser()->email(),
667 user_status);
670 login_manager->RemoveObserver(this);
672 if (exit_after_session_restore_ &&
673 (state == OAuth2LoginManager::SESSION_RESTORE_DONE ||
674 state == OAuth2LoginManager::SESSION_RESTORE_FAILED ||
675 state == OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED)) {
676 LOG(WARNING) << "Restarting Chrome after session restore finishes, "
677 << "most likely due to custom flags.";
679 // We need to restart cleanly in this case to make sure OAuth2 RT is
680 // actually saved.
681 chrome::AttemptRestart();
685 void UserSessionManager::OnConnectionTypeChanged(
686 net::NetworkChangeNotifier::ConnectionType type) {
687 bool is_running_test =
688 base::CommandLine::ForCurrentProcess()->HasSwitch(
689 ::switches::kTestName) ||
690 base::CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestType);
691 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
692 if (type == net::NetworkChangeNotifier::CONNECTION_NONE ||
693 !user_manager->IsUserLoggedIn() ||
694 !user_manager->IsLoggedInAsUserWithGaiaAccount() ||
695 user_manager->IsLoggedInAsStub() || is_running_test) {
696 return;
699 // Need to iterate over all users and their OAuth2 session state.
700 const user_manager::UserList& users = user_manager->GetLoggedInUsers();
701 for (user_manager::UserList::const_iterator it = users.begin();
702 it != users.end();
703 ++it) {
704 if (!(*it)->is_profile_created())
705 continue;
707 Profile* user_profile = ProfileHelper::Get()->GetProfileByUserUnsafe(*it);
708 bool should_restore_session =
709 pending_signin_restore_sessions_.find((*it)->email()) !=
710 pending_signin_restore_sessions_.end();
711 OAuth2LoginManager* login_manager =
712 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile);
713 if (login_manager->state() ==
714 OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) {
715 // If we come online for the first time after successful offline login,
716 // we need to kick off OAuth token verification process again.
717 login_manager->ContinueSessionRestore();
718 } else if (should_restore_session) {
719 pending_signin_restore_sessions_.erase((*it)->email());
720 RestoreAuthSessionImpl(user_profile, false /* has_auth_cookies */);
725 void UserSessionManager::OnProfilePrepared(Profile* profile,
726 bool browser_launched) {
727 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) {
728 // Did not log in (we crashed or are debugging), need to restore Sync.
729 // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
730 // users once it is fully multi-profile aware. http://crbug.com/238987
731 // For now if we have other user pending sessions they'll override OAuth
732 // session restore for previous users.
733 RestoreAuthenticationSession(profile);
736 // Restore other user sessions if any.
737 RestorePendingUserSessions();
740 void UserSessionManager::CreateUserSession(const UserContext& user_context,
741 bool has_auth_cookies) {
742 user_context_ = user_context;
743 has_auth_cookies_ = has_auth_cookies;
744 InitSessionRestoreStrategy();
747 void UserSessionManager::PreStartSession() {
748 // Switch log file as soon as possible.
749 if (base::SysInfo::IsRunningOnChromeOS())
750 logging::RedirectChromeLogging(*(CommandLine::ForCurrentProcess()));
753 void UserSessionManager::StartCrosSession() {
754 BootTimesLoader* btl = BootTimesLoader::Get();
755 btl->AddLoginTimeMarker("StartSession-Start", false);
756 DBusThreadManager::Get()->GetSessionManagerClient()->
757 StartSession(user_context_.GetUserID());
758 btl->AddLoginTimeMarker("StartSession-End", false);
761 void UserSessionManager::NotifyUserLoggedIn() {
762 BootTimesLoader* btl = BootTimesLoader::Get();
763 btl->AddLoginTimeMarker("UserLoggedIn-Start", false);
764 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
765 user_manager->UserLoggedIn(user_context_.GetUserID(),
766 user_context_.GetUserIDHash(),
767 false);
768 btl->AddLoginTimeMarker("UserLoggedIn-End", false);
771 void UserSessionManager::PrepareProfile() {
772 bool is_demo_session =
773 DemoAppLauncher::IsDemoAppSession(user_context_.GetUserID());
775 // TODO(nkostylev): Figure out whether demo session is using the right profile
776 // path or not. See https://codereview.chromium.org/171423009
777 g_browser_process->profile_manager()->CreateProfileAsync(
778 ProfileHelper::GetProfilePathByUserIdHash(user_context_.GetUserIDHash()),
779 base::Bind(&UserSessionManager::OnProfileCreated,
780 AsWeakPtr(),
781 user_context_,
782 is_demo_session),
783 base::string16(),
784 base::string16(),
785 std::string());
788 void UserSessionManager::OnProfileCreated(const UserContext& user_context,
789 bool is_incognito_profile,
790 Profile* profile,
791 Profile::CreateStatus status) {
792 CHECK(profile);
794 switch (status) {
795 case Profile::CREATE_STATUS_CREATED:
796 // Profile created but before initializing extensions and promo resources.
797 InitProfilePreferences(profile, user_context);
798 break;
799 case Profile::CREATE_STATUS_INITIALIZED:
800 // Profile is created, extensions and promo resources are initialized.
801 // At this point all other Chrome OS services will be notified that it is
802 // safe to use this profile.
803 UserProfileInitialized(profile,
804 is_incognito_profile,
805 user_context.GetUserID());
806 break;
807 case Profile::CREATE_STATUS_LOCAL_FAIL:
808 case Profile::CREATE_STATUS_REMOTE_FAIL:
809 case Profile::CREATE_STATUS_CANCELED:
810 case Profile::MAX_CREATE_STATUS:
811 NOTREACHED();
812 break;
816 void UserSessionManager::InitProfilePreferences(
817 Profile* profile,
818 const UserContext& user_context) {
819 user_manager::User* user = ProfileHelper::Get()->GetUserByProfile(profile);
820 if (user->is_active()) {
821 input_method::InputMethodManager* manager =
822 input_method::InputMethodManager::Get();
823 manager->SetState(GetDefaultIMEState(profile));
825 if (user_manager::UserManager::Get()->IsCurrentUserNew()) {
826 SetFirstLoginPrefs(profile,
827 user_context.GetPublicSessionLocale(),
828 user_context.GetPublicSessionInputMethod());
831 if (user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser()) {
832 user_manager::User* active_user =
833 user_manager::UserManager::Get()->GetActiveUser();
834 std::string supervised_user_sync_id =
835 ChromeUserManager::Get()->GetSupervisedUserManager()->GetUserSyncId(
836 active_user->email());
837 profile->GetPrefs()->SetString(prefs::kSupervisedUserId,
838 supervised_user_sync_id);
839 } else if (user_manager::UserManager::Get()->
840 IsLoggedInAsUserWithGaiaAccount()) {
841 // Prime the account tracker with this combination of gaia id/display email.
842 // Don't do this unless both email and gaia_id are valid. They may not
843 // be when simply unlocking the profile.
844 if (!user_context.GetGaiaID().empty() &&
845 !user_context.GetUserID().empty()) {
846 AccountTrackerService* account_tracker =
847 AccountTrackerServiceFactory::GetForProfile(profile);
848 account_tracker->SeedAccountInfo(user_context.GetGaiaID(),
849 user_context.GetUserID());
852 // Make sure that the google service username is properly set (we do this
853 // on every sign in, not just the first login, to deal with existing
854 // profiles that might not have it set yet).
855 SigninManagerBase* signin_manager =
856 SigninManagerFactory::GetForProfile(profile);
857 signin_manager->SetAuthenticatedUsername(user_context.GetUserID());
861 void UserSessionManager::UserProfileInitialized(Profile* profile,
862 bool is_incognito_profile,
863 const std::string& user_id) {
864 // Demo user signed in.
865 if (is_incognito_profile) {
866 profile->OnLogin();
868 // Send the notification before creating the browser so additional objects
869 // that need the profile (e.g. the launcher) can be created first.
870 content::NotificationService::current()->Notify(
871 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
872 content::NotificationService::AllSources(),
873 content::Details<Profile>(profile));
875 if (delegate_)
876 delegate_->OnProfilePrepared(profile, false);
878 return;
881 BootTimesLoader* btl = BootTimesLoader::Get();
882 btl->AddLoginTimeMarker("UserProfileGotten", false);
884 if (user_context_.IsUsingOAuth()) {
885 // Retrieve the policy that indicates whether to continue copying
886 // authentication cookies set by a SAML IdP on subsequent logins after the
887 // first.
888 bool transfer_saml_auth_cookies_on_subsequent_login = false;
889 if (has_auth_cookies_ &&
890 g_browser_process->platform_part()->
891 browser_policy_connector_chromeos()->GetUserAffiliation(user_id) ==
892 policy::USER_AFFILIATION_MANAGED) {
893 CrosSettings::Get()->GetBoolean(
894 kAccountsPrefTransferSAMLCookies,
895 &transfer_saml_auth_cookies_on_subsequent_login);
898 // Transfers authentication-related data from the profile that was used for
899 // authentication to the user's profile. The proxy authentication state is
900 // transferred unconditionally. If the user authenticated via an auth
901 // extension, authentication cookies and channel IDs will be transferred as
902 // well when the user's cookie jar is empty. If the cookie jar is not empty,
903 // the authentication states in the browser context and the user's profile
904 // must be merged using /MergeSession instead. Authentication cookies set by
905 // a SAML IdP will also be transferred when the user's cookie jar is not
906 // empty if |transfer_saml_auth_cookies_on_subsequent_login| is true.
907 const bool transfer_auth_cookies_and_channel_ids_on_first_login =
908 has_auth_cookies_;
909 ProfileAuthData::Transfer(
910 authenticator_->authentication_context(),
911 profile,
912 transfer_auth_cookies_and_channel_ids_on_first_login,
913 transfer_saml_auth_cookies_on_subsequent_login,
914 base::Bind(&UserSessionManager::CompleteProfileCreateAfterAuthTransfer,
915 AsWeakPtr(),
916 profile));
917 return;
920 FinalizePrepareProfile(profile);
923 void UserSessionManager::CompleteProfileCreateAfterAuthTransfer(
924 Profile* profile) {
925 RestoreAuthSessionImpl(profile, has_auth_cookies_);
926 FinalizePrepareProfile(profile);
929 void UserSessionManager::FinalizePrepareProfile(Profile* profile) {
930 BootTimesLoader* btl = BootTimesLoader::Get();
932 // Own TPM device if, for any reason, it has not been done in EULA screen.
933 CryptohomeClient* client = DBusThreadManager::Get()->GetCryptohomeClient();
934 btl->AddLoginTimeMarker("TPMOwn-Start", false);
935 if (cryptohome_util::TpmIsEnabled() && !cryptohome_util::TpmIsBeingOwned()) {
936 if (cryptohome_util::TpmIsOwned())
937 client->CallTpmClearStoredPasswordAndBlock();
938 else
939 client->TpmCanAttemptOwnership(EmptyVoidDBusMethodCallback());
941 btl->AddLoginTimeMarker("TPMOwn-End", false);
943 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
944 if (user_manager->IsLoggedInAsUserWithGaiaAccount()) {
945 SAMLOfflineSigninLimiter* saml_offline_signin_limiter =
946 SAMLOfflineSigninLimiterFactory::GetForProfile(profile);
947 if (saml_offline_signin_limiter)
948 saml_offline_signin_limiter->SignedIn(user_context_.GetAuthFlow());
951 profile->OnLogin();
953 g_browser_process->platform_part()->SessionManager()->SetSessionState(
954 session_manager::SESSION_STATE_LOGGED_IN_NOT_ACTIVE);
956 // Send the notification before creating the browser so additional objects
957 // that need the profile (e.g. the launcher) can be created first.
958 content::NotificationService::current()->Notify(
959 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
960 content::NotificationService::AllSources(),
961 content::Details<Profile>(profile));
963 // Initialize various services only for primary user.
964 const user_manager::User* user =
965 ProfileHelper::Get()->GetUserByProfile(profile);
966 if (user_manager->GetPrimaryUser() == user) {
967 InitRlz(profile);
968 InitializeCerts(profile);
969 InitializeCRLSetFetcher(user);
972 UpdateEasyUnlockKeys(user_context_);
973 user_context_.ClearSecrets();
975 // Now that profile is ready, proceed to either alternative login flows or
976 // launch browser.
977 bool browser_launched = InitializeUserSession(profile);
979 // TODO(nkostylev): This pointer should probably never be NULL, but it looks
980 // like LoginUtilsImpl::OnProfileCreated() may be getting called before
981 // UserSessionManager::PrepareProfile() has set |delegate_| when Chrome is
982 // killed during shutdown in tests -- see http://crosbug.com/18269. Replace
983 // this 'if' statement with a CHECK(delegate_) once the underlying issue is
984 // resolved.
985 if (delegate_)
986 delegate_->OnProfilePrepared(profile, browser_launched);
989 void UserSessionManager::ActivateWizard(const std::string& screen_name) {
990 LoginDisplayHost* host = LoginDisplayHostImpl::default_host();
991 CHECK(host);
992 scoped_ptr<base::DictionaryValue> params;
993 host->StartWizard(screen_name, params.Pass());
996 void UserSessionManager::InitializeStartUrls() const {
997 std::vector<std::string> start_urls;
999 const base::ListValue *urls;
1000 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
1001 bool can_show_getstarted_guide =
1002 user_manager->GetActiveUser()->GetType() ==
1003 user_manager::USER_TYPE_REGULAR &&
1004 !user_manager->IsCurrentUserNonCryptohomeDataEphemeral();
1005 if (user_manager->IsLoggedInAsDemoUser()) {
1006 if (CrosSettings::Get()->GetList(kStartUpUrls, &urls)) {
1007 // The retail mode user will get start URLs from a special policy if it is
1008 // set.
1009 for (base::ListValue::const_iterator it = urls->begin();
1010 it != urls->end(); ++it) {
1011 std::string url;
1012 if ((*it)->GetAsString(&url))
1013 start_urls.push_back(url);
1016 can_show_getstarted_guide = false;
1017 // Skip the default first-run behavior for public accounts.
1018 } else if (!user_manager->IsLoggedInAsPublicAccount()) {
1019 if (AccessibilityManager::Get()->IsSpokenFeedbackEnabled()) {
1020 const char* url = kChromeVoxTutorialURLPattern;
1021 PrefService* prefs = g_browser_process->local_state();
1022 const std::string current_locale =
1023 base::StringToLowerASCII(prefs->GetString(prefs::kApplicationLocale));
1024 std::string vox_url = base::StringPrintf(url, current_locale.c_str());
1025 start_urls.push_back(vox_url);
1026 can_show_getstarted_guide = false;
1030 // Only show getting started guide for a new user.
1031 const bool should_show_getstarted_guide = user_manager->IsCurrentUserNew();
1033 if (can_show_getstarted_guide && should_show_getstarted_guide) {
1034 // Don't open default Chrome window if we're going to launch the first-run
1035 // app. Because we dont' want the first-run app to be hidden in the
1036 // background.
1037 CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kSilentLaunch);
1038 first_run::MaybeLaunchDialogAfterSessionStart();
1039 } else {
1040 for (size_t i = 0; i < start_urls.size(); ++i) {
1041 CommandLine::ForCurrentProcess()->AppendArg(start_urls[i]);
1046 bool UserSessionManager::InitializeUserSession(Profile* profile) {
1047 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
1049 // Kiosk apps has their own session initialization pipeline.
1050 if (user_manager->IsLoggedInAsKioskApp())
1051 return false;
1053 if (start_session_type_ == PRIMARY_USER_SESSION) {
1054 UserFlow* user_flow = ChromeUserManager::Get()->GetCurrentUserFlow();
1055 WizardController* oobe_controller = WizardController::default_controller();
1056 base::CommandLine* cmdline = CommandLine::ForCurrentProcess();
1057 bool skip_post_login_screens =
1058 user_flow->ShouldSkipPostLoginScreens() ||
1059 (oobe_controller && oobe_controller->skip_post_login_screens()) ||
1060 cmdline->HasSwitch(chromeos::switches::kOobeSkipPostLogin);
1062 if (user_manager->IsCurrentUserNew() && !skip_post_login_screens) {
1063 // Don't specify start URLs if the administrator has configured the start
1064 // URLs via policy.
1065 if (!SessionStartupPref::TypeIsManaged(profile->GetPrefs()))
1066 InitializeStartUrls();
1068 // Mark the device as registered., i.e. the second part of OOBE as
1069 // completed.
1070 if (!StartupUtils::IsDeviceRegistered())
1071 StartupUtils::MarkDeviceRegistered(base::Closure());
1073 ActivateWizard(WizardController::kTermsOfServiceScreenName);
1074 return false;
1078 LoginUtils::Get()->DoBrowserLaunch(profile,
1079 LoginDisplayHostImpl::default_host());
1080 return true;
1083 void UserSessionManager::InitSessionRestoreStrategy() {
1084 CommandLine* command_line = CommandLine::ForCurrentProcess();
1085 bool in_app_mode = chrome::IsRunningInForcedAppMode();
1087 // Are we in kiosk app mode?
1088 if (in_app_mode) {
1089 if (command_line->HasSwitch(::switches::kAppModeOAuth2Token)) {
1090 oauth2_refresh_token_ = command_line->GetSwitchValueASCII(
1091 ::switches::kAppModeOAuth2Token);
1094 if (command_line->HasSwitch(::switches::kAppModeAuthCode)) {
1095 user_context_.SetAuthCode(command_line->GetSwitchValueASCII(
1096 ::switches::kAppModeAuthCode));
1099 DCHECK(!has_auth_cookies_);
1100 if (!user_context_.GetAuthCode().empty()) {
1101 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE;
1102 } else if (!oauth2_refresh_token_.empty()) {
1103 session_restore_strategy_ =
1104 OAuth2LoginManager::RESTORE_FROM_PASSED_OAUTH2_REFRESH_TOKEN;
1105 } else {
1106 session_restore_strategy_ =
1107 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN;
1109 return;
1112 if (has_auth_cookies_) {
1113 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR;
1114 } else if (!user_context_.GetAuthCode().empty()) {
1115 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE;
1116 } else {
1117 session_restore_strategy_ =
1118 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN;
1122 void UserSessionManager::RestoreAuthSessionImpl(
1123 Profile* profile,
1124 bool restore_from_auth_cookies) {
1125 CHECK((authenticator_.get() && authenticator_->authentication_context()) ||
1126 !restore_from_auth_cookies);
1128 if (chrome::IsRunningInForcedAppMode() ||
1129 CommandLine::ForCurrentProcess()->HasSwitch(
1130 chromeos::switches::kDisableGaiaServices)) {
1131 return;
1134 exit_after_session_restore_ = false;
1136 // Remove legacy OAuth1 token if we have one. If it's valid, we should already
1137 // have OAuth2 refresh token in OAuth2TokenService that could be used to
1138 // retrieve all other tokens and user_context.
1139 OAuth2LoginManager* login_manager =
1140 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile);
1141 login_manager->AddObserver(this);
1142 login_manager->RestoreSession(
1143 authenticator_.get() && authenticator_->authentication_context()
1144 ? authenticator_->authentication_context()->GetRequestContext()
1145 : NULL,
1146 session_restore_strategy_,
1147 oauth2_refresh_token_,
1148 user_context_.GetAuthCode());
1151 void UserSessionManager::InitRlzImpl(Profile* profile, bool disabled) {
1152 #if defined(ENABLE_RLZ)
1153 PrefService* local_state = g_browser_process->local_state();
1154 if (disabled) {
1155 // Empty brand code means an organic install (no RLZ pings are sent).
1156 google_brand::chromeos::ClearBrandForCurrentSession();
1158 if (disabled != local_state->GetBoolean(prefs::kRLZDisabled)) {
1159 // When switching to RLZ enabled/disabled state, clear all recorded events.
1160 RLZTracker::ClearRlzState();
1161 local_state->SetBoolean(prefs::kRLZDisabled, disabled);
1163 // Init the RLZ library.
1164 int ping_delay = profile->GetPrefs()->GetInteger(
1165 ::first_run::GetPingDelayPrefName().c_str());
1166 // Negative ping delay means to send ping immediately after a first search is
1167 // recorded.
1168 RLZTracker::InitRlzFromProfileDelayed(
1169 profile,
1170 user_manager::UserManager::Get()->IsCurrentUserNew(),
1171 ping_delay < 0,
1172 base::TimeDelta::FromMilliseconds(abs(ping_delay)));
1173 #endif
1176 void UserSessionManager::InitializeCerts(Profile* profile) {
1177 // Now that the user profile has been initialized
1178 // |GetNSSCertDatabaseForProfile| is safe to be used.
1179 if (CertLoader::IsInitialized() && base::SysInfo::IsRunningOnChromeOS()) {
1180 GetNSSCertDatabaseForProfile(profile,
1181 base::Bind(&OnGetNSSCertDatabaseForUser));
1185 void UserSessionManager::InitializeCRLSetFetcher(
1186 const user_manager::User* user) {
1187 const std::string username_hash = user->username_hash();
1188 if (!username_hash.empty()) {
1189 base::FilePath path;
1190 path = ProfileHelper::GetProfilePathByUserIdHash(username_hash);
1191 component_updater::ComponentUpdateService* cus =
1192 g_browser_process->component_updater();
1193 CRLSetFetcher* crl_set = g_browser_process->crl_set_fetcher();
1194 if (crl_set && cus)
1195 crl_set->StartInitialLoad(cus, path);
1199 void UserSessionManager::OnRestoreActiveSessions(
1200 const SessionManagerClient::ActiveSessionsMap& sessions,
1201 bool success) {
1202 if (!success) {
1203 LOG(ERROR) << "Could not get list of active user sessions after crash.";
1204 // If we could not get list of active user sessions it is safer to just
1205 // sign out so that we don't get in the inconsistent state.
1206 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
1207 return;
1210 // One profile has been already loaded on browser start.
1211 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
1212 DCHECK(user_manager->GetLoggedInUsers().size() == 1);
1213 DCHECK(user_manager->GetActiveUser());
1214 std::string active_user_id = user_manager->GetActiveUser()->email();
1216 SessionManagerClient::ActiveSessionsMap::const_iterator it;
1217 for (it = sessions.begin(); it != sessions.end(); ++it) {
1218 if (active_user_id == it->first)
1219 continue;
1220 pending_user_sessions_[it->first] = it->second;
1222 RestorePendingUserSessions();
1225 void UserSessionManager::RestorePendingUserSessions() {
1226 if (pending_user_sessions_.empty()) {
1227 user_manager::UserManager::Get()->SwitchToLastActiveUser();
1228 NotifyPendingUserSessionsRestoreFinished();
1229 return;
1232 // Get next user to restore sessions and delete it from list.
1233 SessionManagerClient::ActiveSessionsMap::const_iterator it =
1234 pending_user_sessions_.begin();
1235 std::string user_id = it->first;
1236 std::string user_id_hash = it->second;
1237 DCHECK(!user_id.empty());
1238 DCHECK(!user_id_hash.empty());
1239 pending_user_sessions_.erase(user_id);
1241 // Check that this user is not logged in yet.
1242 user_manager::UserList logged_in_users =
1243 user_manager::UserManager::Get()->GetLoggedInUsers();
1244 bool user_already_logged_in = false;
1245 for (user_manager::UserList::const_iterator it = logged_in_users.begin();
1246 it != logged_in_users.end();
1247 ++it) {
1248 const user_manager::User* user = (*it);
1249 if (user->email() == user_id) {
1250 user_already_logged_in = true;
1251 break;
1254 DCHECK(!user_already_logged_in);
1256 if (!user_already_logged_in) {
1257 UserContext user_context(user_id);
1258 user_context.SetUserIDHash(user_id_hash);
1259 user_context.SetIsUsingOAuth(false);
1261 // Will call OnProfilePrepared() once profile has been loaded.
1262 // Only handling secondary users here since primary user profile
1263 // (and session) has been loaded on Chrome startup.
1264 StartSession(user_context,
1265 SECONDARY_USER_SESSION_AFTER_CRASH,
1266 NULL, // authenticator
1267 false, // has_auth_cookies
1268 true, // has_active_session, this is restart after crash
1269 this);
1270 } else {
1271 RestorePendingUserSessions();
1275 void UserSessionManager::NotifyPendingUserSessionsRestoreFinished() {
1276 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
1277 user_sessions_restored_ = true;
1278 user_sessions_restore_in_progress_ = false;
1279 FOR_EACH_OBSERVER(chromeos::UserSessionStateObserver,
1280 session_state_observer_list_,
1281 PendingUserSessionsRestoreFinished());
1284 void UserSessionManager::UpdateEasyUnlockKeys(const UserContext& user_context) {
1285 // Skip key update because FakeCryptohomeClient always return success
1286 // and RemoveKey op expects a failure to stop. As a result, some tests would
1287 // timeout.
1288 // TODO(xiyuan): Revisit this when adding tests.
1289 if (!base::SysInfo::IsRunningOnChromeOS())
1290 return;
1292 // Only update Easy unlock keys for regular user.
1293 // TODO(xiyuan): Fix inconsistency user type of |user_context| introduced in
1294 // authenticator.
1295 const user_manager::User* user =
1296 user_manager::UserManager::Get()->FindUser(user_context.GetUserID());
1297 if (!user || !user->HasGaiaAccount())
1298 return;
1300 // Bail if |user_context| does not have secret.
1301 if (user_context.GetKey()->GetSecret().empty())
1302 return;
1304 const base::ListValue* device_list = NULL;
1305 EasyUnlockService* easy_unlock_service = EasyUnlockService::GetForUser(*user);
1306 if (easy_unlock_service) {
1307 device_list = easy_unlock_service->GetRemoteDevices();
1308 easy_unlock_service->SetHardlockState(
1309 EasyUnlockScreenlockStateHandler::NO_HARDLOCK);
1312 EasyUnlockKeyManager* key_manager = GetEasyUnlockKeyManager();
1313 running_easy_unlock_key_ops_ = true;
1314 if (device_list) {
1315 key_manager->RefreshKeys(
1316 user_context,
1317 *device_list,
1318 base::Bind(&UserSessionManager::OnEasyUnlockKeyOpsFinished,
1319 AsWeakPtr(),
1320 user_context.GetUserID()));
1321 } else {
1322 key_manager->RemoveKeys(
1323 user_context,
1325 base::Bind(&UserSessionManager::OnEasyUnlockKeyOpsFinished,
1326 AsWeakPtr(),
1327 user_context.GetUserID()));
1331 void UserSessionManager::AttemptRestart(Profile* profile) {
1332 if (CheckEasyUnlockKeyOps(base::Bind(&UserSessionManager::AttemptRestart,
1333 AsWeakPtr(), profile))) {
1334 return;
1337 if (session_restore_strategy_ !=
1338 OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR) {
1339 chrome::AttemptRestart();
1340 return;
1343 // We can't really quit if the session restore process that mints new
1344 // refresh token is still in progress.
1345 OAuth2LoginManager* login_manager =
1346 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile);
1347 if (login_manager->state() != OAuth2LoginManager::SESSION_RESTORE_PREPARING &&
1348 login_manager->state() !=
1349 OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) {
1350 chrome::AttemptRestart();
1351 return;
1354 LOG(WARNING) << "Attempting browser restart during session restore.";
1355 exit_after_session_restore_ = true;
1358 void UserSessionManager::OnEasyUnlockKeyOpsFinished(
1359 const std::string& user_id,
1360 bool success) {
1361 running_easy_unlock_key_ops_ = false;
1362 if (!easy_unlock_key_ops_finished_callback_.is_null())
1363 easy_unlock_key_ops_finished_callback_.Run();
1365 const user_manager::User* user =
1366 user_manager::UserManager::Get()->FindUser(user_id);
1367 EasyUnlockService* easy_unlock_service =
1368 EasyUnlockService::GetForUser(*user);
1369 easy_unlock_service->CheckCryptohomeKeysAndMaybeHardlock();
1372 void UserSessionManager::ActiveUserChanged(
1373 const user_manager::User* active_user) {
1374 Profile* profile = ProfileHelper::Get()->GetProfileByUser(active_user);
1375 // If profile has not yet been initialized, delay initialization of IME.
1376 if (!profile)
1377 return;
1379 input_method::InputMethodManager* manager =
1380 input_method::InputMethodManager::Get();
1381 manager->SetState(
1382 GetDefaultIMEState(ProfileHelper::Get()->GetProfileByUser(active_user)));
1385 scoped_refptr<input_method::InputMethodManager::State>
1386 UserSessionManager::GetDefaultIMEState(Profile* profile) {
1387 scoped_refptr<input_method::InputMethodManager::State> state =
1388 default_ime_states_[profile];
1389 if (!state.get()) {
1390 // Profile can be NULL in tests.
1391 state = input_method::InputMethodManager::Get()->CreateNewState(profile);
1392 default_ime_states_[profile] = state;
1394 return state;
1397 EasyUnlockKeyManager* UserSessionManager::GetEasyUnlockKeyManager() {
1398 if (!easy_unlock_key_manager_)
1399 easy_unlock_key_manager_.reset(new EasyUnlockKeyManager);
1401 return easy_unlock_key_manager_.get();
1404 void UserSessionManager::DoBrowserLaunchInternal(Profile* profile,
1405 LoginDisplayHost* login_host,
1406 bool locale_pref_checked) {
1407 if (browser_shutdown::IsTryingToQuit())
1408 return;
1410 if (!locale_pref_checked) {
1411 RespectLocalePreferenceWrapper(
1412 profile,
1413 base::Bind(&UserSessionManager::DoBrowserLaunchInternal, AsWeakPtr(),
1414 profile, login_host, true /* locale_pref_checked */));
1415 return;
1418 if (!ChromeUserManager::Get()->GetCurrentUserFlow()->ShouldLaunchBrowser()) {
1419 ChromeUserManager::Get()->GetCurrentUserFlow()->LaunchExtraSteps(profile);
1420 return;
1423 if (RestartToApplyPerSessionFlagsIfNeed(profile, false))
1424 return;
1426 if (login_host) {
1427 login_host->SetStatusAreaVisible(true);
1428 login_host->BeforeSessionStart();
1431 BootTimesLoader::Get()->AddLoginTimeMarker("BrowserLaunched", false);
1433 VLOG(1) << "Launching browser...";
1434 TRACE_EVENT0("login", "LaunchBrowser");
1436 #if defined(USE_ATHENA)
1437 athena::StartAthenaSessionWithContext(profile);
1438 #else
1439 StartupBrowserCreator browser_creator;
1440 int return_code;
1441 chrome::startup::IsFirstRun first_run =
1442 ::first_run::IsChromeFirstRun() ? chrome::startup::IS_FIRST_RUN
1443 : chrome::startup::IS_NOT_FIRST_RUN;
1445 browser_creator.LaunchBrowser(
1446 *CommandLine::ForCurrentProcess(), profile, base::FilePath(),
1447 chrome::startup::IS_PROCESS_STARTUP, first_run, &return_code);
1449 // Triggers app launcher start page service to load start page web contents.
1450 app_list::StartPageService::Get(profile);
1451 #endif
1453 // Mark login host for deletion after browser starts. This
1454 // guarantees that the message loop will be referenced by the
1455 // browser before it is dereferenced by the login host.
1456 if (login_host)
1457 login_host->Finalize();
1458 user_manager::UserManager::Get()->SessionStarted();
1459 chromeos::BootTimesLoader::Get()->LoginDone(
1460 user_manager::UserManager::Get()->IsCurrentUserNew());
1463 void UserSessionManager::RespectLocalePreferenceWrapper(
1464 Profile* profile,
1465 const base::Closure& callback) {
1466 if (browser_shutdown::IsTryingToQuit())
1467 return;
1469 user_manager::User* const user =
1470 ProfileHelper::Get()->GetUserByProfile(profile);
1471 locale_util::SwitchLanguageCallback locale_switched_callback(base::Bind(
1472 &UserSessionManager::RunCallbackOnLocaleLoaded, callback,
1473 base::Owned(new InputEventsBlocker))); // Block UI events until
1474 // the ResourceBundle is
1475 // reloaded.
1476 if (!RespectLocalePreference(profile, user, locale_switched_callback))
1477 callback.Run();
1480 // static
1481 void UserSessionManager::RunCallbackOnLocaleLoaded(
1482 const base::Closure& callback,
1483 InputEventsBlocker* /* input_events_blocker */,
1484 const locale_util::LanguageSwitchResult& /* result */) {
1485 callback.Run();
1488 } // namespace chromeos