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"
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"
93 #if defined(USE_ATHENA)
94 #include "athena/main/public/athena_launcher.h"
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
,
109 const std::string
& public_session_locale
,
110 const std::string
& public_session_input_method
) {
111 PrefService
* prefs
= profile
->GetPrefs();
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
);
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
135 input_method_ids
.push_back(public_session_input_method
);
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(
141 session_manager
->GetDefaultIMEState(profile
)->GetCurrentInputMethod(),
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(),
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
);
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())
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
);
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)
218 // Only restart if needed and if not going into managed mode.
219 if (user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser())
222 if (about_flags::AreSwitchesIdenticalToCurrentCommandLine(
223 user_flags
, *CommandLine::ForCurrentProcess(),
224 out_command_line_difference
)) {
231 bool CanPerformEarlyRestart() {
232 // Desktop build is used for development only. Early restart is not supported.
233 if (!base::SysInfo::IsRunningOnChromeOS())
236 if (!ChromeUserManager::Get()
237 ->GetCurrentUserFlow()
238 ->SupportsEarlyRestartToApplyFlags()) {
242 const ExistingUserController
* controller
=
243 ExistingUserController::current_controller();
247 // Early restart is possible only if OAuth token is up to date.
249 if (controller
->password_changed())
252 if (controller
->auth_mode() != LoginPerformer::AUTH_MODE_INTERNAL
)
255 // No early restart if Easy unlock key needs to be updated.
256 if (UserSessionManager::GetInstance()->NeedsToUpdateEasyUnlockKeys())
262 void LogCustomSwitches(const std::set
<std::string
>& switches
) {
265 for (std::set
<std::string
>::const_iterator it
= switches
.begin();
266 it
!= switches
.end(); ++it
) {
267 VLOG(1) << "Switch leading to restart: '" << *it
<< "'";
273 UserSessionManagerDelegate::~UserSessionManagerDelegate() {
276 void UserSessionStateObserver::PendingUserSessionsRestoreFinished() {
279 UserSessionStateObserver::~UserSessionStateObserver() {
283 UserSessionManager
* UserSessionManager::GetInstance() {
284 return Singleton
<UserSessionManager
,
285 DefaultSingletonTraits
<UserSessionManager
> >::get();
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
,
301 true /* path is absolute */,
302 false /* don't create */);
308 void UserSessionManager::RegisterPrefs(PrefRegistrySimple
* registry
) {
309 registry
->RegisterStringPref(prefs::kRLZBrand
, std::string());
310 registry
->RegisterBooleanPref(prefs::kRLZDisabled
, false);
313 UserSessionManager::UserSessionManager()
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
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
,
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
355 const CommandLine
user_flags(CommandLine::NO_PROGRAM
);
356 if (!about_flags::AreSwitchesIdenticalToCurrentCommandLine(
358 *CommandLine::ForCurrentProcess(),
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();
382 CreateUserSession(user_context
, has_auth_cookies
);
384 if (!has_active_session
)
387 // TODO(nkostylev): Notify UserLoggedIn() after profile is actually
388 // ready to be used (http://crbug.com/361528).
389 NotifyUserLoggedIn();
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()) {
417 user_manager::User
* user
=
418 ProfileHelper::Get()->GetUserByProfile(user_profile
);
420 if (!net::NetworkChangeNotifier::IsOffline()) {
421 pending_signin_restore_sessions_
.erase(user
->email());
422 RestoreAuthSessionImpl(user_profile
, false /* has_auth_cookies */);
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
));
456 base::PostTaskAndReplyWithResult(
457 base::WorkerPool::GetTaskRunner(false).get(),
459 base::Bind(&base::PathExists
, GetRlzDisabledFlagPath()),
460 base::Bind(&UserSessionManager::InitRlzImpl
, AsWeakPtr(), profile
));
464 void UserSessionManager::SetFirstLoginPrefs(
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()) {
481 *chrome_client_id
= chrome_client_id_
;
482 *chrome_client_secret
= chrome_client_secret_
;
486 void UserSessionManager::SetAppModeChromeClientOAuthInfo(
487 const std::string
& chrome_client_id
,
488 const std::string
& chrome_client_secret
) {
489 if (!chrome::IsRunningInForcedAppMode())
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(
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
)
510 user_manager::UserManager
* user_manager
= user_manager::UserManager::Get();
511 if (!user
|| (user_manager
->IsUserLoggedIn() &&
512 user
!= user_manager
->GetPrimaryUser())) {
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)
521 const PrefService
* prefs
= profile
->GetPrefs();
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
) +
553 : (std::string("account_locale - unused. ")))
554 << " Selected '" << pref_locale
<< "'";
555 profile
->ChangeAppLocale(
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
);
578 bool UserSessionManager::RestartToApplyPerSessionFlagsIfNeed(
580 bool early_restart
) {
581 if (ProfileHelper::IsSigninProfile(profile
))
584 if (early_restart
&& !CanPerformEarlyRestart())
587 const CommandLine
user_flags(CreatePerSessionCommandLine(profile
));
588 std::set
<CommandLine::StringType
> command_line_difference
;
589 if (!NeedRestartToApplyPerSessionFlags(user_flags
, &command_line_difference
))
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
);
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_
)
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
;
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;
646 case OAuth2LoginManager::SESSION_RESTORE_DONE
:
647 user_status
= user_manager::User::OAUTH2_TOKEN_STATUS_VALID
;
649 case OAuth2LoginManager::SESSION_RESTORE_FAILED
:
650 user_status
= user_manager::User::OAUTH2_TOKEN_STATUS_INVALID
;
652 case OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED
:
653 connection_error
= true;
655 case OAuth2LoginManager::SESSION_RESTORE_NOT_STARTED
:
656 case OAuth2LoginManager::SESSION_RESTORE_PREPARING
:
657 case OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS
:
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(),
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
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
) {
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();
704 if (!(*it
)->is_profile_created())
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(),
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
,
788 void UserSessionManager::OnProfileCreated(const UserContext
& user_context
,
789 bool is_incognito_profile
,
791 Profile::CreateStatus status
) {
795 case Profile::CREATE_STATUS_CREATED
:
796 // Profile created but before initializing extensions and promo resources.
797 InitProfilePreferences(profile
, user_context
);
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());
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
:
816 void UserSessionManager::InitProfilePreferences(
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
) {
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
));
876 delegate_
->OnProfilePrepared(profile
, false);
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
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
=
909 ProfileAuthData::Transfer(
910 authenticator_
->authentication_context(),
912 transfer_auth_cookies_and_channel_ids_on_first_login
,
913 transfer_saml_auth_cookies_on_subsequent_login
,
914 base::Bind(&UserSessionManager::CompleteProfileCreateAfterAuthTransfer
,
920 FinalizePrepareProfile(profile
);
923 void UserSessionManager::CompleteProfileCreateAfterAuthTransfer(
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();
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());
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
) {
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
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
986 delegate_
->OnProfilePrepared(profile
, browser_launched
);
989 void UserSessionManager::ActivateWizard(const std::string
& screen_name
) {
990 LoginDisplayHost
* host
= LoginDisplayHostImpl::default_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
1009 for (base::ListValue::const_iterator it
= urls
->begin();
1010 it
!= urls
->end(); ++it
) {
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
1037 CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kSilentLaunch
);
1038 first_run::MaybeLaunchDialogAfterSessionStart();
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())
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
1065 if (!SessionStartupPref::TypeIsManaged(profile
->GetPrefs()))
1066 InitializeStartUrls();
1068 // Mark the device as registered., i.e. the second part of OOBE as
1070 if (!StartupUtils::IsDeviceRegistered())
1071 StartupUtils::MarkDeviceRegistered(base::Closure());
1073 ActivateWizard(WizardController::kTermsOfServiceScreenName
);
1078 LoginUtils::Get()->DoBrowserLaunch(profile
,
1079 LoginDisplayHostImpl::default_host());
1083 void UserSessionManager::InitSessionRestoreStrategy() {
1084 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
1085 bool in_app_mode
= chrome::IsRunningInForcedAppMode();
1087 // Are we in kiosk 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
;
1106 session_restore_strategy_
=
1107 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN
;
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
;
1117 session_restore_strategy_
=
1118 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN
;
1122 void UserSessionManager::RestoreAuthSessionImpl(
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
)) {
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()
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();
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
1168 RLZTracker::InitRlzFromProfileDelayed(
1170 user_manager::UserManager::Get()->IsCurrentUserNew(),
1172 base::TimeDelta::FromMilliseconds(abs(ping_delay
)));
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();
1195 crl_set
->StartInitialLoad(cus
, path
);
1199 void UserSessionManager::OnRestoreActiveSessions(
1200 const SessionManagerClient::ActiveSessionsMap
& sessions
,
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();
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
)
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();
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();
1248 const user_manager::User
* user
= (*it
);
1249 if (user
->email() == user_id
) {
1250 user_already_logged_in
= true;
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
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
1288 // TODO(xiyuan): Revisit this when adding tests.
1289 if (!base::SysInfo::IsRunningOnChromeOS())
1292 // Only update Easy unlock keys for regular user.
1293 // TODO(xiyuan): Fix inconsistency user type of |user_context| introduced in
1295 const user_manager::User
* user
=
1296 user_manager::UserManager::Get()->FindUser(user_context
.GetUserID());
1297 if (!user
|| !user
->HasGaiaAccount())
1300 // Bail if |user_context| does not have secret.
1301 if (user_context
.GetKey()->GetSecret().empty())
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;
1315 key_manager
->RefreshKeys(
1318 base::Bind(&UserSessionManager::OnEasyUnlockKeyOpsFinished
,
1320 user_context
.GetUserID()));
1322 key_manager
->RemoveKeys(
1325 base::Bind(&UserSessionManager::OnEasyUnlockKeyOpsFinished
,
1327 user_context
.GetUserID()));
1331 void UserSessionManager::AttemptRestart(Profile
* profile
) {
1332 if (CheckEasyUnlockKeyOps(base::Bind(&UserSessionManager::AttemptRestart
,
1333 AsWeakPtr(), profile
))) {
1337 if (session_restore_strategy_
!=
1338 OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR
) {
1339 chrome::AttemptRestart();
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();
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
,
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.
1379 input_method::InputMethodManager
* manager
=
1380 input_method::InputMethodManager::Get();
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
];
1390 // Profile can be NULL in tests.
1391 state
= input_method::InputMethodManager::Get()->CreateNewState(profile
);
1392 default_ime_states_
[profile
] = 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())
1410 if (!locale_pref_checked
) {
1411 RespectLocalePreferenceWrapper(
1413 base::Bind(&UserSessionManager::DoBrowserLaunchInternal
, AsWeakPtr(),
1414 profile
, login_host
, true /* locale_pref_checked */));
1418 if (!ChromeUserManager::Get()->GetCurrentUserFlow()->ShouldLaunchBrowser()) {
1419 ChromeUserManager::Get()->GetCurrentUserFlow()->LaunchExtraSteps(profile
);
1423 if (RestartToApplyPerSessionFlagsIfNeed(profile
, false))
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
);
1439 StartupBrowserCreator browser_creator
;
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
);
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.
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(
1465 const base::Closure
& callback
) {
1466 if (browser_shutdown::IsTryingToQuit())
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
1476 if (!RespectLocalePreference(profile
, user
, locale_switched_callback
))
1481 void UserSessionManager::RunCallbackOnLocaleLoaded(
1482 const base::Closure
& callback
,
1483 InputEventsBlocker
* /* input_events_blocker */,
1484 const locale_util::LanguageSwitchResult
& /* result */) {
1488 } // namespace chromeos