Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / session / user_session_manager.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
6
7 #include <string>
8
9 #include "base/base_paths.h"
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/logging.h"
13 #include "base/path_service.h"
14 #include "base/prefs/pref_member.h"
15 #include "base/prefs/pref_registry_simple.h"
16 #include "base/prefs/pref_service.h"
17 #include "base/strings/string16.h"
18 #include "base/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/chrome_notification_types.h"
27 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
28 #include "chrome/browser/chromeos/base/locale_util.h"
29 #include "chrome/browser/chromeos/boot_times_loader.h"
30 #include "chrome/browser/chromeos/first_run/first_run.h"
31 #include "chrome/browser/chromeos/input_method/input_method_util.h"
32 #include "chrome/browser/chromeos/login/chrome_restart_request.h"
33 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
34 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
35 #include "chrome/browser/chromeos/login/profile_auth_data.h"
36 #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.h"
37 #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter_factory.h"
38 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h"
39 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h"
40 #include "chrome/browser/chromeos/login/startup_utils.h"
41 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
42 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
43 #include "chrome/browser/chromeos/login/user_flow.h"
44 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
45 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
46 #include "chrome/browser/chromeos/login/wizard_controller.h"
47 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
48 #include "chrome/browser/chromeos/profiles/profile_helper.h"
49 #include "chrome/browser/chromeos/settings/cros_settings.h"
50 #include "chrome/browser/first_run/first_run.h"
51 #include "chrome/browser/google/google_brand_chromeos.h"
52 #include "chrome/browser/lifetime/application_lifetime.h"
53 #include "chrome/browser/net/crl_set_fetcher.h"
54 #include "chrome/browser/net/nss_context.h"
55 #include "chrome/browser/prefs/session_startup_pref.h"
56 #include "chrome/browser/profiles/profile.h"
57 #include "chrome/browser/profiles/profile_manager.h"
58 #include "chrome/browser/rlz/rlz.h"
59 #include "chrome/browser/signin/account_tracker_service_factory.h"
60 #include "chrome/browser/signin/easy_unlock_service.h"
61 #include "chrome/browser/signin/signin_manager_factory.h"
62 #include "chrome/common/chrome_switches.h"
63 #include "chrome/common/logging_chrome.h"
64 #include "chrome/common/pref_names.h"
65 #include "chromeos/cert_loader.h"
66 #include "chromeos/chromeos_switches.h"
67 #include "chromeos/cryptohome/cryptohome_util.h"
68 #include "chromeos/dbus/cryptohome_client.h"
69 #include "chromeos/dbus/dbus_thread_manager.h"
70 #include "chromeos/dbus/session_manager_client.h"
71 #include "chromeos/ime/input_method_manager.h"
72 #include "chromeos/login/user_names.h"
73 #include "chromeos/network/portal_detector/network_portal_detector.h"
74 #include "chromeos/network/portal_detector/network_portal_detector_strategy.h"
75 #include "chromeos/settings/cros_settings_names.h"
76 #include "components/component_updater/component_updater_service.h"
77 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
78 #include "components/session_manager/core/session_manager.h"
79 #include "components/signin/core/browser/account_tracker_service.h"
80 #include "components/signin/core/browser/signin_manager_base.h"
81 #include "components/user_manager/user.h"
82 #include "components/user_manager/user_manager.h"
83 #include "components/user_manager/user_type.h"
84 #include "content/public/browser/browser_thread.h"
85 #include "content/public/browser/notification_service.h"
86 #include "url/gurl.h"
87
88 namespace chromeos {
89
90 namespace {
91
92 // ChromeVox tutorial URL (used in place of "getting started" url when
93 // accessibility is enabled).
94 const char kChromeVoxTutorialURLPattern[] =
95     "http://www.chromevox.com/tutorial/index.html?lang=%s";
96
97 void InitLocaleAndInputMethodsForNewUser(
98     UserSessionManager* session_manager,
99     Profile* profile,
100     const std::string& public_session_locale,
101     const std::string& public_session_input_method) {
102   PrefService* prefs = profile->GetPrefs();
103   std::string locale;
104   if (!public_session_locale.empty()) {
105     // If this is a public session and the user chose a |public_session_locale|,
106     // write it to |prefs| so that the UI switches to it.
107     locale = public_session_locale;
108     prefs->SetString(prefs::kApplicationLocale, locale);
109
110     // Suppress the locale change dialog.
111     prefs->SetString(prefs::kApplicationLocaleAccepted, locale);
112   } else {
113     // Otherwise, assume that the session will use the current UI locale.
114     locale = g_browser_process->GetApplicationLocale();
115   }
116
117   // First, we'll set kLanguagePreloadEngines.
118   input_method::InputMethodManager* manager =
119       input_method::InputMethodManager::Get();
120   std::vector<std::string> input_method_ids;
121
122   if (!public_session_input_method.empty()) {
123     // If this is a public session and the user chose a
124     // |public_session_input_method|, set kLanguagePreloadEngines to this input
125     // method only.
126     input_method_ids.push_back(public_session_input_method);
127   } else {
128     // Otherwise, set kLanguagePreloadEngines to a list of input methods derived
129     // from the |locale| and the currently active input method.
130     manager->GetInputMethodUtil()->GetFirstLoginInputMethodIds(
131         locale,
132         session_manager->GetDefaultIMEState(profile)->GetCurrentInputMethod(),
133         &input_method_ids);
134   }
135
136   // Save the input methods in the user's preferences.
137   StringPrefMember language_preload_engines;
138   language_preload_engines.Init(prefs::kLanguagePreloadEngines, prefs);
139   language_preload_engines.SetValue(JoinString(input_method_ids, ','));
140   BootTimesLoader::Get()->AddLoginTimeMarker("IMEStarted", false);
141
142   // Second, we'll set kLanguagePreferredLanguages.
143   std::vector<std::string> language_codes;
144
145   // The current locale should be on the top.
146   language_codes.push_back(locale);
147
148   // Add input method IDs based on the input methods, as there may be
149   // input methods that are unrelated to the current locale. Example: the
150   // hardware keyboard layout xkb:us::eng is used for logging in, but the
151   // UI language is set to French. In this case, we should set "fr,en"
152   // to the preferred languages preference.
153   std::vector<std::string> candidates;
154   manager->GetInputMethodUtil()->GetLanguageCodesFromInputMethodIds(
155       input_method_ids, &candidates);
156   for (size_t i = 0; i < candidates.size(); ++i) {
157     const std::string& candidate = candidates[i];
158     // Skip if it's already in language_codes.
159     if (std::count(language_codes.begin(), language_codes.end(),
160                    candidate) == 0) {
161       language_codes.push_back(candidate);
162     }
163   }
164
165   // Save the preferred languages in the user's preferences.
166   StringPrefMember language_preferred_languages;
167   language_preferred_languages.Init(prefs::kLanguagePreferredLanguages, prefs);
168   language_preferred_languages.SetValue(JoinString(language_codes, ','));
169 }
170
171 #if defined(ENABLE_RLZ)
172 // Flag file that disables RLZ tracking, when present.
173 const base::FilePath::CharType kRLZDisabledFlagName[] =
174     FILE_PATH_LITERAL(".rlz_disabled");
175
176 base::FilePath GetRlzDisabledFlagPath() {
177   base::FilePath homedir;
178   PathService::Get(base::DIR_HOME, &homedir);
179   return homedir.Append(kRLZDisabledFlagName);
180 }
181 #endif
182
183 // Callback to GetNSSCertDatabaseForProfile. It starts CertLoader using the
184 // provided NSS database. It must be called for primary user only.
185 void OnGetNSSCertDatabaseForUser(net::NSSCertDatabase* database) {
186   if (!CertLoader::IsInitialized())
187     return;
188
189   CertLoader::Get()->StartWithNSSDB(database);
190 }
191
192 }  // namespace
193
194 #if defined(ENABLE_RLZ)
195 void UserSessionManagerDelegate::OnRlzInitialized() {
196 }
197 #endif
198
199 UserSessionManagerDelegate::~UserSessionManagerDelegate() {
200 }
201
202 void UserSessionStateObserver::PendingUserSessionsRestoreFinished() {
203 }
204
205 UserSessionStateObserver::~UserSessionStateObserver() {
206 }
207
208 // static
209 UserSessionManager* UserSessionManager::GetInstance() {
210   return Singleton<UserSessionManager,
211       DefaultSingletonTraits<UserSessionManager> >::get();
212 }
213
214 // static
215 void UserSessionManager::OverrideHomedir() {
216   // Override user homedir, check for ProfileManager being initialized as
217   // it may not exist in unit tests.
218   if (g_browser_process->profile_manager()) {
219     user_manager::UserManager* user_manager = user_manager::UserManager::Get();
220     if (user_manager->GetLoggedInUsers().size() == 1) {
221       base::FilePath homedir = ProfileHelper::GetProfilePathByUserIdHash(
222           user_manager->GetPrimaryUser()->username_hash());
223       // This path has been either created by cryptohome (on real Chrome OS
224       // device) or by ProfileManager (on chromeos=1 desktop builds).
225       PathService::OverrideAndCreateIfNeeded(base::DIR_HOME,
226                                              homedir,
227                                              true /* path is absolute */,
228                                              false /* don't create */);
229     }
230   }
231 }
232
233 // static
234 void UserSessionManager::RegisterPrefs(PrefRegistrySimple* registry) {
235   registry->RegisterStringPref(prefs::kRLZBrand, std::string());
236   registry->RegisterBooleanPref(prefs::kRLZDisabled, false);
237 }
238
239 UserSessionManager::UserSessionManager()
240     : delegate_(NULL),
241       has_auth_cookies_(false),
242       user_sessions_restored_(false),
243       user_sessions_restore_in_progress_(false),
244       exit_after_session_restore_(false),
245       session_restore_strategy_(
246           OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN),
247       running_easy_unlock_key_ops_(false) {
248   net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
249   user_manager::UserManager::Get()->AddSessionStateObserver(this);
250 }
251
252 UserSessionManager::~UserSessionManager() {
253   // UserManager is destroyed before singletons, so we need to check if it
254   // still exists.
255   // TODO(nkostylev): fix order of destruction of UserManager
256   // / UserSessionManager objects.
257   if (user_manager::UserManager::IsInitialized())
258     user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
259   net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
260 }
261
262 void UserSessionManager::CompleteGuestSessionLogin(const GURL& start_url) {
263   VLOG(1) << "Completing guest session login";
264
265   // For guest session we ask session_manager to restart Chrome with --bwsi
266   // flag. We keep only some of the arguments of this process.
267   const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
268   CommandLine command_line(browser_command_line.GetProgram());
269   std::string cmd_line_str =
270       GetOffTheRecordCommandLine(start_url,
271                                  StartupUtils::IsOobeCompleted(),
272                                  browser_command_line,
273                                  &command_line);
274
275   // This makes sure that Chrome restarts with no per-session flags. The guest
276   // profile will always have empty set of per-session flags. If this is not
277   // done and device owner has some per-session flags, when Chrome is relaunched
278   // the guest profile session flags will not match the current command line and
279   // another restart will be attempted in order to reset the user flags for the
280   // guest user.
281   const CommandLine user_flags(CommandLine::NO_PROGRAM);
282   if (!about_flags::AreSwitchesIdenticalToCurrentCommandLine(
283            user_flags,
284            *CommandLine::ForCurrentProcess(),
285            NULL)) {
286     DBusThreadManager::Get()->GetSessionManagerClient()->SetFlagsForUser(
287         chromeos::login::kGuestUserName,
288         CommandLine::StringVector());
289   }
290
291   RestartChrome(cmd_line_str);
292 }
293
294 void UserSessionManager::StartSession(
295     const UserContext& user_context,
296     StartSessionType start_session_type,
297     scoped_refptr<Authenticator> authenticator,
298     bool has_auth_cookies,
299     bool has_active_session,
300     UserSessionManagerDelegate* delegate) {
301   authenticator_ = authenticator;
302   delegate_ = delegate;
303   start_session_type_ = start_session_type;
304
305   VLOG(1) << "Starting session for " << user_context.GetUserID();
306
307   PreStartSession();
308   CreateUserSession(user_context, has_auth_cookies);
309
310   if (!has_active_session)
311     StartCrosSession();
312
313   // TODO(nkostylev): Notify UserLoggedIn() after profile is actually
314   // ready to be used (http://crbug.com/361528).
315   NotifyUserLoggedIn();
316   PrepareProfile();
317 }
318
319 void UserSessionManager::PerformPostUserLoggedInActions() {
320   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
321   if (user_manager->GetLoggedInUsers().size() == 1) {
322     if (NetworkPortalDetector::IsInitialized()) {
323       NetworkPortalDetector::Get()->SetStrategy(
324           PortalDetectorStrategy::STRATEGY_ID_SESSION);
325     }
326   }
327 }
328
329 void UserSessionManager::RestoreAuthenticationSession(Profile* user_profile) {
330   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
331   // We need to restore session only for logged in regular (GAIA) users.
332   // Note: stub user is a special case that is used for tests, running
333   // linux_chromeos build on dev workstations w/o user_id parameters.
334   // Stub user is considered to be a regular GAIA user but it has special
335   // user_id (kStubUser) and certain services like restoring OAuth session are
336   // explicitly disabled for it.
337   if (!user_manager->IsUserLoggedIn() ||
338       !user_manager->IsLoggedInAsRegularUser() ||
339       user_manager->IsLoggedInAsStub()) {
340     return;
341   }
342
343   user_manager::User* user =
344       ProfileHelper::Get()->GetUserByProfile(user_profile);
345   DCHECK(user);
346   if (!net::NetworkChangeNotifier::IsOffline()) {
347     pending_signin_restore_sessions_.erase(user->email());
348     RestoreAuthSessionImpl(user_profile, false /* has_auth_cookies */);
349   } else {
350     // Even if we're online we should wait till initial
351     // OnConnectionTypeChanged() call. Otherwise starting fetchers too early may
352     // end up canceling all request when initial network connection type is
353     // processed. See http://crbug.com/121643.
354     pending_signin_restore_sessions_.insert(user->email());
355   }
356 }
357
358 void UserSessionManager::RestoreActiveSessions() {
359   user_sessions_restore_in_progress_ = true;
360   DBusThreadManager::Get()->GetSessionManagerClient()->RetrieveActiveSessions(
361       base::Bind(&UserSessionManager::OnRestoreActiveSessions,
362                  base::Unretained(this)));
363 }
364
365 bool UserSessionManager::UserSessionsRestored() const {
366   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
367   return user_sessions_restored_;
368 }
369
370 bool UserSessionManager::UserSessionsRestoreInProgress() const {
371   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
372   return user_sessions_restore_in_progress_;
373 }
374
375 void UserSessionManager::InitRlz(Profile* profile) {
376 #if defined(ENABLE_RLZ)
377   if (!g_browser_process->local_state()->HasPrefPath(prefs::kRLZBrand)) {
378     // Read brand code asynchronously from an OEM data and repost ourselves.
379     google_brand::chromeos::InitBrand(
380         base::Bind(&UserSessionManager::InitRlz, AsWeakPtr(), profile));
381     return;
382   }
383   base::PostTaskAndReplyWithResult(
384       base::WorkerPool::GetTaskRunner(false).get(),
385       FROM_HERE,
386       base::Bind(&base::PathExists, GetRlzDisabledFlagPath()),
387       base::Bind(&UserSessionManager::InitRlzImpl, AsWeakPtr(), profile));
388 #endif
389 }
390
391 OAuth2LoginManager::SessionRestoreStrategy
392 UserSessionManager::GetSigninSessionRestoreStrategy() {
393   return session_restore_strategy_;
394 }
395
396 void UserSessionManager::SetFirstLoginPrefs(
397     Profile* profile,
398     const std::string& public_session_locale,
399     const std::string& public_session_input_method) {
400   VLOG(1) << "Setting first login prefs";
401   InitLocaleAndInputMethodsForNewUser(
402       this, profile, public_session_locale, public_session_input_method);
403 }
404
405 bool UserSessionManager::GetAppModeChromeClientOAuthInfo(
406     std::string* chrome_client_id, std::string* chrome_client_secret) {
407   if (!chrome::IsRunningInForcedAppMode() ||
408       chrome_client_id_.empty() ||
409       chrome_client_secret_.empty()) {
410     return false;
411   }
412
413   *chrome_client_id = chrome_client_id_;
414   *chrome_client_secret = chrome_client_secret_;
415   return true;
416 }
417
418 void UserSessionManager::SetAppModeChromeClientOAuthInfo(
419     const std::string& chrome_client_id,
420     const std::string& chrome_client_secret) {
421   if (!chrome::IsRunningInForcedAppMode())
422     return;
423
424   chrome_client_id_ = chrome_client_id;
425   chrome_client_secret_ = chrome_client_secret;
426 }
427
428 bool UserSessionManager::RespectLocalePreference(
429     Profile* profile,
430     const user_manager::User* user,
431     scoped_ptr<locale_util::SwitchLanguageCallback> callback) const {
432   // TODO(alemate): http://crbug.com/288941 : Respect preferred language list in
433   // the Google user profile.
434   if (g_browser_process == NULL)
435     return false;
436
437   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
438   if (!user || (user_manager->IsUserLoggedIn() &&
439                 user != user_manager->GetPrimaryUser())) {
440     return false;
441   }
442
443   // In case of multi-profiles session we don't apply profile locale
444   // because it is unsafe.
445   if (user_manager->GetLoggedInUsers().size() != 1)
446     return false;
447
448   const PrefService* prefs = profile->GetPrefs();
449   if (prefs == NULL)
450     return false;
451
452   std::string pref_locale;
453   const std::string pref_app_locale =
454       prefs->GetString(prefs::kApplicationLocale);
455   const std::string pref_bkup_locale =
456       prefs->GetString(prefs::kApplicationLocaleBackup);
457
458   pref_locale = pref_app_locale;
459   if (pref_locale.empty())
460     pref_locale = pref_bkup_locale;
461
462   const std::string* account_locale = NULL;
463   if (pref_locale.empty() && user->has_gaia_account()) {
464     if (user->GetAccountLocale() == NULL)
465       return false;  // wait until Account profile is loaded.
466     account_locale = user->GetAccountLocale();
467     pref_locale = *account_locale;
468   }
469   const std::string global_app_locale =
470       g_browser_process->GetApplicationLocale();
471   if (pref_locale.empty())
472     pref_locale = global_app_locale;
473   DCHECK(!pref_locale.empty());
474   VLOG(1) << "RespectLocalePreference: "
475           << "app_locale='" << pref_app_locale << "', "
476           << "bkup_locale='" << pref_bkup_locale << "', "
477           << (account_locale != NULL
478               ? (std::string("account_locale='") + (*account_locale) +
479                  "'. ")
480               : (std::string("account_locale - unused. ")))
481           << " Selected '" << pref_locale << "'";
482   profile->ChangeAppLocale(
483       pref_locale,
484       user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT ?
485           Profile::APP_LOCALE_CHANGED_VIA_PUBLIC_SESSION_LOGIN :
486           Profile::APP_LOCALE_CHANGED_VIA_LOGIN);
487
488   // Here we don't enable keyboard layouts for normal users. Input methods
489   // are set up when the user first logs in. Then the user may customize the
490   // input methods.  Hence changing input methods here, just because the user's
491   // UI language is different from the login screen UI language, is not
492   // desirable. Note that input method preferences are synced, so users can use
493   // their farovite input methods as soon as the preferences are synced.
494   //
495   // For Guest mode, user locale preferences will never get initialized.
496   // So input methods should be enabled somewhere.
497   const bool enable_layouts =
498       user_manager::UserManager::Get()->IsLoggedInAsGuest();
499   locale_util::SwitchLanguage(pref_locale,
500                               enable_layouts,
501                               false /* login_layouts_only */,
502                               callback.Pass());
503
504   return true;
505 }
506
507 bool UserSessionManager::NeedsToUpdateEasyUnlockKeys() const {
508   return EasyUnlockService::IsSignInEnabled() &&
509          !user_context_.GetUserID().empty() &&
510          user_context_.GetUserType() == user_manager::USER_TYPE_REGULAR &&
511          user_context_.GetKey() && !user_context_.GetKey()->GetSecret().empty();
512 }
513
514 bool UserSessionManager::CheckEasyUnlockKeyOps(const base::Closure& callback) {
515   if (!running_easy_unlock_key_ops_)
516     return false;
517
518   // Assumes only one deferred callback is needed.
519   DCHECK(easy_unlock_key_ops_finished_callback_.is_null());
520
521   easy_unlock_key_ops_finished_callback_ = callback;
522   return true;
523 }
524
525 void UserSessionManager::AddSessionStateObserver(
526     chromeos::UserSessionStateObserver* observer) {
527   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
528   session_state_observer_list_.AddObserver(observer);
529 }
530
531 void UserSessionManager::RemoveSessionStateObserver(
532     chromeos::UserSessionStateObserver* observer) {
533   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
534   session_state_observer_list_.RemoveObserver(observer);
535 }
536
537 void UserSessionManager::OnSessionRestoreStateChanged(
538     Profile* user_profile,
539     OAuth2LoginManager::SessionRestoreState state) {
540   user_manager::User::OAuthTokenStatus user_status =
541       user_manager::User::OAUTH_TOKEN_STATUS_UNKNOWN;
542   OAuth2LoginManager* login_manager =
543       OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile);
544
545   bool connection_error = false;
546   switch (state) {
547     case OAuth2LoginManager::SESSION_RESTORE_DONE:
548       user_status = user_manager::User::OAUTH2_TOKEN_STATUS_VALID;
549       break;
550     case OAuth2LoginManager::SESSION_RESTORE_FAILED:
551       user_status = user_manager::User::OAUTH2_TOKEN_STATUS_INVALID;
552       break;
553     case OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED:
554       connection_error = true;
555       break;
556     case OAuth2LoginManager::SESSION_RESTORE_NOT_STARTED:
557     case OAuth2LoginManager::SESSION_RESTORE_PREPARING:
558     case OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS:
559       return;
560   }
561
562   // We should not be clearing existing token state if that was a connection
563   // error. http://crbug.com/295245
564   if (!connection_error) {
565     // We are in one of "done" states here.
566     user_manager::UserManager::Get()->SaveUserOAuthStatus(
567         user_manager::UserManager::Get()->GetLoggedInUser()->email(),
568         user_status);
569   }
570
571   login_manager->RemoveObserver(this);
572 }
573
574 void UserSessionManager::OnNewRefreshTokenAvaiable(Profile* user_profile) {
575   // Check if we were waiting to restart chrome.
576   if (!exit_after_session_restore_)
577     return;
578
579   OAuth2LoginManager* login_manager =
580       OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile);
581   login_manager->RemoveObserver(this);
582
583   // Mark user auth token status as valid.
584   user_manager::UserManager::Get()->SaveUserOAuthStatus(
585       user_manager::UserManager::Get()->GetLoggedInUser()->email(),
586       user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
587
588   VLOG(1) << "Exiting after new refresh token fetched";
589
590   // We need to restart cleanly in this case to make sure OAuth2 RT is actually
591   // saved.
592   chrome::AttemptRestart();
593 }
594
595 void UserSessionManager::OnConnectionTypeChanged(
596     net::NetworkChangeNotifier::ConnectionType type) {
597   bool is_running_test =
598       base::CommandLine::ForCurrentProcess()->HasSwitch(
599           ::switches::kTestName) ||
600       base::CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestType);
601   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
602   if (type == net::NetworkChangeNotifier::CONNECTION_NONE ||
603       !user_manager->IsUserLoggedIn() ||
604       !user_manager->IsLoggedInAsRegularUser() ||
605       user_manager->IsLoggedInAsStub() || is_running_test) {
606     return;
607   }
608
609   // Need to iterate over all users and their OAuth2 session state.
610   const user_manager::UserList& users = user_manager->GetLoggedInUsers();
611   for (user_manager::UserList::const_iterator it = users.begin();
612        it != users.end();
613        ++it) {
614     if (!(*it)->is_profile_created())
615       continue;
616
617     Profile* user_profile = ProfileHelper::Get()->GetProfileByUserUnsafe(*it);
618     bool should_restore_session =
619         pending_signin_restore_sessions_.find((*it)->email()) !=
620         pending_signin_restore_sessions_.end();
621     OAuth2LoginManager* login_manager =
622         OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile);
623     if (login_manager->state() ==
624             OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) {
625       // If we come online for the first time after successful offline login,
626       // we need to kick off OAuth token verification process again.
627       login_manager->ContinueSessionRestore();
628     } else if (should_restore_session) {
629       pending_signin_restore_sessions_.erase((*it)->email());
630       RestoreAuthSessionImpl(user_profile, false /* has_auth_cookies */);
631     }
632   }
633 }
634
635 void UserSessionManager::OnProfilePrepared(Profile* profile,
636                                            bool browser_launched) {
637   if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) {
638     // Did not log in (we crashed or are debugging), need to restore Sync.
639     // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
640     // users once it is fully multi-profile aware. http://crbug.com/238987
641     // For now if we have other user pending sessions they'll override OAuth
642     // session restore for previous users.
643     UserSessionManager::GetInstance()->RestoreAuthenticationSession(profile);
644   }
645
646   // Restore other user sessions if any.
647   RestorePendingUserSessions();
648 }
649
650 void UserSessionManager::CreateUserSession(const UserContext& user_context,
651                                            bool has_auth_cookies) {
652   user_context_ = user_context;
653   has_auth_cookies_ = has_auth_cookies;
654   InitSessionRestoreStrategy();
655 }
656
657 void UserSessionManager::PreStartSession() {
658   // Switch log file as soon as possible.
659   if (base::SysInfo::IsRunningOnChromeOS())
660     logging::RedirectChromeLogging(*(CommandLine::ForCurrentProcess()));
661 }
662
663 void UserSessionManager::StartCrosSession() {
664   BootTimesLoader* btl = BootTimesLoader::Get();
665   btl->AddLoginTimeMarker("StartSession-Start", false);
666   DBusThreadManager::Get()->GetSessionManagerClient()->
667       StartSession(user_context_.GetUserID());
668   btl->AddLoginTimeMarker("StartSession-End", false);
669 }
670
671 void UserSessionManager::NotifyUserLoggedIn() {
672   BootTimesLoader* btl = BootTimesLoader::Get();
673   btl->AddLoginTimeMarker("UserLoggedIn-Start", false);
674   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
675   user_manager->UserLoggedIn(user_context_.GetUserID(),
676                              user_context_.GetUserIDHash(),
677                              false);
678   btl->AddLoginTimeMarker("UserLoggedIn-End", false);
679 }
680
681 void UserSessionManager::PrepareProfile() {
682   bool is_demo_session =
683       DemoAppLauncher::IsDemoAppSession(user_context_.GetUserID());
684
685   // TODO(nkostylev): Figure out whether demo session is using the right profile
686   // path or not. See https://codereview.chromium.org/171423009
687   g_browser_process->profile_manager()->CreateProfileAsync(
688       ProfileHelper::GetProfilePathByUserIdHash(user_context_.GetUserIDHash()),
689       base::Bind(&UserSessionManager::OnProfileCreated,
690                  AsWeakPtr(),
691                  user_context_,
692                  is_demo_session),
693       base::string16(),
694       base::string16(),
695       std::string());
696 }
697
698 void UserSessionManager::OnProfileCreated(const UserContext& user_context,
699                                           bool is_incognito_profile,
700                                           Profile* profile,
701                                           Profile::CreateStatus status) {
702   CHECK(profile);
703
704   switch (status) {
705     case Profile::CREATE_STATUS_CREATED:
706       // Profile created but before initializing extensions and promo resources.
707       InitProfilePreferences(profile, user_context);
708       break;
709     case Profile::CREATE_STATUS_INITIALIZED:
710       // Profile is created, extensions and promo resources are initialized.
711       // At this point all other Chrome OS services will be notified that it is
712       // safe to use this profile.
713       UserProfileInitialized(profile,
714                              is_incognito_profile,
715                              user_context.GetUserID());
716       break;
717     case Profile::CREATE_STATUS_LOCAL_FAIL:
718     case Profile::CREATE_STATUS_REMOTE_FAIL:
719     case Profile::CREATE_STATUS_CANCELED:
720     case Profile::MAX_CREATE_STATUS:
721       NOTREACHED();
722       break;
723   }
724 }
725
726 void UserSessionManager::InitProfilePreferences(
727     Profile* profile,
728     const UserContext& user_context) {
729   user_manager::User* user = ProfileHelper::Get()->GetUserByProfile(profile);
730   if (user->is_active()) {
731     input_method::InputMethodManager* manager =
732         input_method::InputMethodManager::Get();
733     manager->SetState(GetDefaultIMEState(profile));
734   }
735   if (user_manager::UserManager::Get()->IsCurrentUserNew()) {
736     SetFirstLoginPrefs(profile,
737                        user_context.GetPublicSessionLocale(),
738                        user_context.GetPublicSessionInputMethod());
739   }
740
741   if (user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser()) {
742     user_manager::User* active_user =
743         user_manager::UserManager::Get()->GetActiveUser();
744     std::string supervised_user_sync_id =
745         ChromeUserManager::Get()->GetSupervisedUserManager()->GetUserSyncId(
746             active_user->email());
747     profile->GetPrefs()->SetString(prefs::kSupervisedUserId,
748                                    supervised_user_sync_id);
749   } else if (user_manager::UserManager::Get()->IsLoggedInAsRegularUser()) {
750     // Prime the account tracker with this combination of gaia id/display email.
751     // Don't do this unless both email and gaia_id are valid.  They may not
752     // be when simply unlocking the profile.
753     if (!user_context.GetGaiaID().empty() &&
754         !user_context.GetUserID().empty()) {
755       AccountTrackerService* account_tracker =
756           AccountTrackerServiceFactory::GetForProfile(profile);
757       account_tracker->SeedAccountInfo(user_context.GetGaiaID(),
758                                        user_context.GetUserID());
759     }
760
761     // Make sure that the google service username is properly set (we do this
762     // on every sign in, not just the first login, to deal with existing
763     // profiles that might not have it set yet).
764     SigninManagerBase* signin_manager =
765         SigninManagerFactory::GetForProfile(profile);
766     signin_manager->SetAuthenticatedUsername(user_context.GetUserID());
767   }
768 }
769
770 void UserSessionManager::UserProfileInitialized(Profile* profile,
771                                                 bool is_incognito_profile,
772                                                 const std::string& user_id) {
773   // Demo user signed in.
774   if (is_incognito_profile) {
775     profile->OnLogin();
776
777     // Send the notification before creating the browser so additional objects
778     // that need the profile (e.g. the launcher) can be created first.
779     content::NotificationService::current()->Notify(
780         chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
781         content::NotificationService::AllSources(),
782         content::Details<Profile>(profile));
783
784     if (delegate_)
785       delegate_->OnProfilePrepared(profile, false);
786
787     return;
788   }
789
790   BootTimesLoader* btl = BootTimesLoader::Get();
791   btl->AddLoginTimeMarker("UserProfileGotten", false);
792
793   if (user_context_.IsUsingOAuth()) {
794     // Retrieve the policy that indicates whether to continue copying
795     // authentication cookies set by a SAML IdP on subsequent logins after the
796     // first.
797     bool transfer_saml_auth_cookies_on_subsequent_login = false;
798     if (has_auth_cookies_ &&
799         g_browser_process->platform_part()->
800             browser_policy_connector_chromeos()->GetUserAffiliation(user_id) ==
801                 policy::USER_AFFILIATION_MANAGED) {
802       CrosSettings::Get()->GetBoolean(
803           kAccountsPrefTransferSAMLCookies,
804           &transfer_saml_auth_cookies_on_subsequent_login);
805     }
806
807     // Transfers authentication-related data from the profile that was used for
808     // authentication to the user's profile. The proxy authentication state is
809     // transferred unconditionally. If the user authenticated via an auth
810     // extension, authentication cookies and channel IDs will be transferred as
811     // well when the user's cookie jar is empty. If the cookie jar is not empty,
812     // the authentication states in the browser context and the user's profile
813     // must be merged using /MergeSession instead. Authentication cookies set by
814     // a SAML IdP will also be transferred when the user's cookie jar is not
815     // empty if |transfer_saml_auth_cookies_on_subsequent_login| is true.
816     const bool transfer_auth_cookies_and_channel_ids_on_first_login =
817         has_auth_cookies_;
818     ProfileAuthData::Transfer(
819         authenticator_->authentication_context(),
820         profile,
821         transfer_auth_cookies_and_channel_ids_on_first_login,
822         transfer_saml_auth_cookies_on_subsequent_login,
823         base::Bind(&UserSessionManager::CompleteProfileCreateAfterAuthTransfer,
824                    AsWeakPtr(),
825                    profile));
826     return;
827   }
828
829   FinalizePrepareProfile(profile);
830 }
831
832 void UserSessionManager::CompleteProfileCreateAfterAuthTransfer(
833     Profile* profile) {
834   RestoreAuthSessionImpl(profile, has_auth_cookies_);
835   FinalizePrepareProfile(profile);
836 }
837
838 void UserSessionManager::FinalizePrepareProfile(Profile* profile) {
839   BootTimesLoader* btl = BootTimesLoader::Get();
840
841   // Own TPM device if, for any reason, it has not been done in EULA screen.
842   CryptohomeClient* client = DBusThreadManager::Get()->GetCryptohomeClient();
843   btl->AddLoginTimeMarker("TPMOwn-Start", false);
844   if (cryptohome_util::TpmIsEnabled() && !cryptohome_util::TpmIsBeingOwned()) {
845     if (cryptohome_util::TpmIsOwned())
846       client->CallTpmClearStoredPasswordAndBlock();
847     else
848       client->TpmCanAttemptOwnership(EmptyVoidDBusMethodCallback());
849   }
850   btl->AddLoginTimeMarker("TPMOwn-End", false);
851
852   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
853   if (user_manager->IsLoggedInAsRegularUser()) {
854     SAMLOfflineSigninLimiter* saml_offline_signin_limiter =
855         SAMLOfflineSigninLimiterFactory::GetForProfile(profile);
856     if (saml_offline_signin_limiter)
857       saml_offline_signin_limiter->SignedIn(user_context_.GetAuthFlow());
858   }
859
860   profile->OnLogin();
861
862   g_browser_process->platform_part()->SessionManager()->SetSessionState(
863       session_manager::SESSION_STATE_LOGGED_IN_NOT_ACTIVE);
864
865   // Send the notification before creating the browser so additional objects
866   // that need the profile (e.g. the launcher) can be created first.
867   content::NotificationService::current()->Notify(
868       chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
869       content::NotificationService::AllSources(),
870       content::Details<Profile>(profile));
871
872   // Initialize various services only for primary user.
873   const user_manager::User* user =
874       ProfileHelper::Get()->GetUserByProfile(profile);
875   if (user_manager->GetPrimaryUser() == user) {
876     InitRlz(profile);
877     InitializeCerts(profile);
878     InitializeCRLSetFetcher(user);
879   }
880
881   UpdateEasyUnlockKeys(user_context_);
882   user_context_.ClearSecrets();
883
884   // Now that profile is ready, proceed to either alternative login flows or
885   // launch browser.
886   bool browser_launched = InitializeUserSession(profile);
887
888   // TODO(nkostylev): This pointer should probably never be NULL, but it looks
889   // like LoginUtilsImpl::OnProfileCreated() may be getting called before
890   // UserSessionManager::PrepareProfile() has set |delegate_| when Chrome is
891   // killed during shutdown in tests -- see http://crosbug.com/18269.  Replace
892   // this 'if' statement with a CHECK(delegate_) once the underlying issue is
893   // resolved.
894   if (delegate_)
895     delegate_->OnProfilePrepared(profile, browser_launched);
896 }
897
898 void UserSessionManager::ActivateWizard(const std::string& screen_name) {
899   LoginDisplayHost* host = LoginDisplayHostImpl::default_host();
900   DCHECK(host);
901   if (host) {
902     scoped_ptr<base::DictionaryValue> params;
903     host->StartWizard(screen_name, params.Pass());
904   }
905 }
906
907 void UserSessionManager::InitializeStartUrls() const {
908   std::vector<std::string> start_urls;
909
910   const base::ListValue *urls;
911   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
912   bool can_show_getstarted_guide =
913       user_manager->GetActiveUser()->GetType() ==
914           user_manager::USER_TYPE_REGULAR &&
915       !user_manager->IsCurrentUserNonCryptohomeDataEphemeral();
916   if (user_manager->IsLoggedInAsDemoUser()) {
917     if (CrosSettings::Get()->GetList(kStartUpUrls, &urls)) {
918       // The retail mode user will get start URLs from a special policy if it is
919       // set.
920       for (base::ListValue::const_iterator it = urls->begin();
921            it != urls->end(); ++it) {
922         std::string url;
923         if ((*it)->GetAsString(&url))
924           start_urls.push_back(url);
925       }
926     }
927     can_show_getstarted_guide = false;
928   // Skip the default first-run behavior for public accounts.
929   } else if (!user_manager->IsLoggedInAsPublicAccount()) {
930     if (AccessibilityManager::Get()->IsSpokenFeedbackEnabled()) {
931       const char* url = kChromeVoxTutorialURLPattern;
932       PrefService* prefs = g_browser_process->local_state();
933       const std::string current_locale =
934           base::StringToLowerASCII(prefs->GetString(prefs::kApplicationLocale));
935       std::string vox_url = base::StringPrintf(url, current_locale.c_str());
936       start_urls.push_back(vox_url);
937       can_show_getstarted_guide = false;
938     }
939   }
940
941   // Only show getting started guide for a new user.
942   const bool should_show_getstarted_guide = user_manager->IsCurrentUserNew();
943
944   if (can_show_getstarted_guide && should_show_getstarted_guide) {
945     // Don't open default Chrome window if we're going to launch the first-run
946     // app. Because we dont' want the first-run app to be hidden in the
947     // background.
948     CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kSilentLaunch);
949     first_run::MaybeLaunchDialogAfterSessionStart();
950   } else {
951     for (size_t i = 0; i < start_urls.size(); ++i) {
952       CommandLine::ForCurrentProcess()->AppendArg(start_urls[i]);
953     }
954   }
955 }
956
957 bool UserSessionManager::InitializeUserSession(Profile* profile) {
958   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
959
960   // Kiosk apps has their own session initialization pipeline.
961   if (user_manager->IsLoggedInAsKioskApp())
962     return false;
963
964   if (start_session_type_ == PRIMARY_USER_SESSION) {
965     UserFlow* user_flow = ChromeUserManager::Get()->GetCurrentUserFlow();
966     WizardController* oobe_controller = WizardController::default_controller();
967     base::CommandLine* cmdline = CommandLine::ForCurrentProcess();
968     bool skip_post_login_screens =
969         user_flow->ShouldSkipPostLoginScreens() ||
970         (oobe_controller && oobe_controller->skip_post_login_screens()) ||
971         cmdline->HasSwitch(chromeos::switches::kOobeSkipPostLogin);
972
973     if (user_manager->IsCurrentUserNew() && !skip_post_login_screens) {
974       // Don't specify start URLs if the administrator has configured the start
975       // URLs via policy.
976       if (!SessionStartupPref::TypeIsManaged(profile->GetPrefs()))
977         InitializeStartUrls();
978
979       // Mark the device as registered., i.e. the second part of OOBE as
980       // completed.
981       if (!StartupUtils::IsDeviceRegistered())
982         StartupUtils::MarkDeviceRegistered(base::Closure());
983
984       ActivateWizard(WizardController::kTermsOfServiceScreenName);
985       return false;
986     }
987   }
988
989   LoginUtils::Get()->DoBrowserLaunch(profile,
990                                      LoginDisplayHostImpl::default_host());
991   return true;
992 }
993
994 void UserSessionManager::InitSessionRestoreStrategy() {
995   CommandLine* command_line = CommandLine::ForCurrentProcess();
996   bool in_app_mode = chrome::IsRunningInForcedAppMode();
997
998   // Are we in kiosk app mode?
999   if (in_app_mode) {
1000     if (command_line->HasSwitch(::switches::kAppModeOAuth2Token)) {
1001       oauth2_refresh_token_ = command_line->GetSwitchValueASCII(
1002           ::switches::kAppModeOAuth2Token);
1003     }
1004
1005     if (command_line->HasSwitch(::switches::kAppModeAuthCode)) {
1006       user_context_.SetAuthCode(command_line->GetSwitchValueASCII(
1007           ::switches::kAppModeAuthCode));
1008     }
1009
1010     DCHECK(!has_auth_cookies_);
1011     if (!user_context_.GetAuthCode().empty()) {
1012       session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE;
1013     } else if (!oauth2_refresh_token_.empty()) {
1014       session_restore_strategy_ =
1015           OAuth2LoginManager::RESTORE_FROM_PASSED_OAUTH2_REFRESH_TOKEN;
1016     } else {
1017       session_restore_strategy_ =
1018           OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN;
1019     }
1020     return;
1021   }
1022
1023   if (has_auth_cookies_) {
1024     session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR;
1025   } else if (!user_context_.GetAuthCode().empty()) {
1026     session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE;
1027   } else {
1028     session_restore_strategy_ =
1029         OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN;
1030   }
1031 }
1032
1033 void UserSessionManager::RestoreAuthSessionImpl(
1034     Profile* profile,
1035     bool restore_from_auth_cookies) {
1036   CHECK((authenticator_.get() && authenticator_->authentication_context()) ||
1037         !restore_from_auth_cookies);
1038
1039   if (chrome::IsRunningInForcedAppMode() ||
1040       CommandLine::ForCurrentProcess()->HasSwitch(
1041           chromeos::switches::kDisableGaiaServices)) {
1042     return;
1043   }
1044
1045   exit_after_session_restore_ = false;
1046
1047   // Remove legacy OAuth1 token if we have one. If it's valid, we should already
1048   // have OAuth2 refresh token in OAuth2TokenService that could be used to
1049   // retrieve all other tokens and user_context.
1050   OAuth2LoginManager* login_manager =
1051       OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile);
1052   login_manager->AddObserver(this);
1053   login_manager->RestoreSession(
1054       authenticator_.get() && authenticator_->authentication_context()
1055           ? authenticator_->authentication_context()->GetRequestContext()
1056           : NULL,
1057       session_restore_strategy_,
1058       oauth2_refresh_token_,
1059       user_context_.GetAuthCode());
1060 }
1061
1062 void UserSessionManager::InitRlzImpl(Profile* profile, bool disabled) {
1063 #if defined(ENABLE_RLZ)
1064   PrefService* local_state = g_browser_process->local_state();
1065   if (disabled) {
1066     // Empty brand code means an organic install (no RLZ pings are sent).
1067     google_brand::chromeos::ClearBrandForCurrentSession();
1068   }
1069   if (disabled != local_state->GetBoolean(prefs::kRLZDisabled)) {
1070     // When switching to RLZ enabled/disabled state, clear all recorded events.
1071     RLZTracker::ClearRlzState();
1072     local_state->SetBoolean(prefs::kRLZDisabled, disabled);
1073   }
1074   // Init the RLZ library.
1075   int ping_delay = profile->GetPrefs()->GetInteger(
1076       ::first_run::GetPingDelayPrefName().c_str());
1077   // Negative ping delay means to send ping immediately after a first search is
1078   // recorded.
1079   RLZTracker::InitRlzFromProfileDelayed(
1080       profile,
1081       user_manager::UserManager::Get()->IsCurrentUserNew(),
1082       ping_delay < 0,
1083       base::TimeDelta::FromMilliseconds(abs(ping_delay)));
1084   if (delegate_)
1085     delegate_->OnRlzInitialized();
1086 #endif
1087 }
1088
1089 void UserSessionManager::InitializeCerts(Profile* profile) {
1090   // Now that the user profile has been initialized
1091   // |GetNSSCertDatabaseForProfile| is safe to be used.
1092   if (CertLoader::IsInitialized() && base::SysInfo::IsRunningOnChromeOS()) {
1093     GetNSSCertDatabaseForProfile(profile,
1094                                  base::Bind(&OnGetNSSCertDatabaseForUser));
1095   }
1096 }
1097
1098 void UserSessionManager::InitializeCRLSetFetcher(
1099     const user_manager::User* user) {
1100   const std::string username_hash = user->username_hash();
1101   if (!username_hash.empty()) {
1102     base::FilePath path;
1103     path = ProfileHelper::GetProfilePathByUserIdHash(username_hash);
1104     component_updater::ComponentUpdateService* cus =
1105         g_browser_process->component_updater();
1106     CRLSetFetcher* crl_set = g_browser_process->crl_set_fetcher();
1107     if (crl_set && cus)
1108       crl_set->StartInitialLoad(cus, path);
1109   }
1110 }
1111
1112 void UserSessionManager::OnRestoreActiveSessions(
1113     const SessionManagerClient::ActiveSessionsMap& sessions,
1114     bool success) {
1115   if (!success) {
1116     LOG(ERROR) << "Could not get list of active user sessions after crash.";
1117     // If we could not get list of active user sessions it is safer to just
1118     // sign out so that we don't get in the inconsistent state.
1119     DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
1120     return;
1121   }
1122
1123   // One profile has been already loaded on browser start.
1124   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
1125   DCHECK(user_manager->GetLoggedInUsers().size() == 1);
1126   DCHECK(user_manager->GetActiveUser());
1127   std::string active_user_id = user_manager->GetActiveUser()->email();
1128
1129   SessionManagerClient::ActiveSessionsMap::const_iterator it;
1130   for (it = sessions.begin(); it != sessions.end(); ++it) {
1131     if (active_user_id == it->first)
1132       continue;
1133     pending_user_sessions_[it->first] = it->second;
1134   }
1135   RestorePendingUserSessions();
1136 }
1137
1138 void UserSessionManager::RestorePendingUserSessions() {
1139   if (pending_user_sessions_.empty()) {
1140     user_manager::UserManager::Get()->SwitchToLastActiveUser();
1141     NotifyPendingUserSessionsRestoreFinished();
1142     return;
1143   }
1144
1145   // Get next user to restore sessions and delete it from list.
1146   SessionManagerClient::ActiveSessionsMap::const_iterator it =
1147       pending_user_sessions_.begin();
1148   std::string user_id = it->first;
1149   std::string user_id_hash = it->second;
1150   DCHECK(!user_id.empty());
1151   DCHECK(!user_id_hash.empty());
1152   pending_user_sessions_.erase(user_id);
1153
1154   // Check that this user is not logged in yet.
1155   user_manager::UserList logged_in_users =
1156       user_manager::UserManager::Get()->GetLoggedInUsers();
1157   bool user_already_logged_in = false;
1158   for (user_manager::UserList::const_iterator it = logged_in_users.begin();
1159        it != logged_in_users.end();
1160        ++it) {
1161     const user_manager::User* user = (*it);
1162     if (user->email() == user_id) {
1163       user_already_logged_in = true;
1164       break;
1165     }
1166   }
1167   DCHECK(!user_already_logged_in);
1168
1169   if (!user_already_logged_in) {
1170     UserContext user_context(user_id);
1171     user_context.SetUserIDHash(user_id_hash);
1172     user_context.SetIsUsingOAuth(false);
1173
1174     // Will call OnProfilePrepared() once profile has been loaded.
1175     // Only handling secondary users here since primary user profile
1176     // (and session) has been loaded on Chrome startup.
1177     StartSession(user_context,
1178                  SECONDARY_USER_SESSION_AFTER_CRASH,
1179                  NULL,   // authenticator
1180                  false,  // has_auth_cookies
1181                  true,   // has_active_session, this is restart after crash
1182                  this);
1183   } else {
1184     RestorePendingUserSessions();
1185   }
1186 }
1187
1188 void UserSessionManager::NotifyPendingUserSessionsRestoreFinished() {
1189   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
1190   user_sessions_restored_ = true;
1191   user_sessions_restore_in_progress_ = false;
1192   FOR_EACH_OBSERVER(chromeos::UserSessionStateObserver,
1193                     session_state_observer_list_,
1194                     PendingUserSessionsRestoreFinished());
1195 }
1196
1197 void UserSessionManager::UpdateEasyUnlockKeys(const UserContext& user_context) {
1198   // Skip key update because FakeCryptohomeClient always return success
1199   // and RemoveKey op expects a failure to stop. As a result, some tests would
1200   // timeout.
1201   // TODO(xiyuan): Revisit this when adding tests.
1202   if (!base::SysInfo::IsRunningOnChromeOS())
1203     return;
1204
1205   // Only update Easy unlock keys for regular user.
1206   // TODO(xiyuan): Fix inconsistency user type of |user_context| introduced in
1207   // authenticator.
1208   const user_manager::User* user =
1209       user_manager::UserManager::Get()->FindUser(user_context.GetUserID());
1210   if (!user || user->GetType() != user_manager::USER_TYPE_REGULAR)
1211     return;
1212
1213   // Bail if |user_context| does not have secret.
1214   if (user_context.GetKey()->GetSecret().empty())
1215     return;
1216
1217   const base::ListValue* device_list = NULL;
1218   EasyUnlockService* easy_unlock_service = EasyUnlockService::GetForUser(*user);
1219   if (easy_unlock_service) {
1220     device_list = easy_unlock_service->GetRemoteDevices();
1221     easy_unlock_service->SetHardlockState(
1222         EasyUnlockScreenlockStateHandler::NO_HARDLOCK);
1223   }
1224
1225   EasyUnlockKeyManager* key_manager = GetEasyUnlockKeyManager();
1226   running_easy_unlock_key_ops_ = true;
1227   if (device_list) {
1228     key_manager->RefreshKeys(
1229         user_context,
1230         *device_list,
1231         base::Bind(&UserSessionManager::OnEasyUnlockKeyOpsFinished,
1232                    AsWeakPtr(),
1233                    user_context.GetUserID()));
1234   } else {
1235     key_manager->RemoveKeys(
1236         user_context,
1237         0,
1238         base::Bind(&UserSessionManager::OnEasyUnlockKeyOpsFinished,
1239                    AsWeakPtr(),
1240                    user_context.GetUserID()));
1241   }
1242 }
1243
1244 void UserSessionManager::OnEasyUnlockKeyOpsFinished(
1245     const std::string& user_id,
1246     bool success) {
1247   running_easy_unlock_key_ops_ = false;
1248   if (!easy_unlock_key_ops_finished_callback_.is_null())
1249     easy_unlock_key_ops_finished_callback_.Run();
1250
1251   const user_manager::User* user =
1252       user_manager::UserManager::Get()->FindUser(user_id);
1253   EasyUnlockService* easy_unlock_service =
1254         EasyUnlockService::GetForUser(*user);
1255   easy_unlock_service->CheckCryptohomeKeysAndMaybeHardlock();
1256 }
1257
1258 void UserSessionManager::ActiveUserChanged(
1259     const user_manager::User* active_user) {
1260   Profile* profile = ProfileHelper::Get()->GetProfileByUser(active_user);
1261   // If profile has not yet been initialized, delay initialization of IME.
1262   if (!profile)
1263     return;
1264
1265   input_method::InputMethodManager* manager =
1266       input_method::InputMethodManager::Get();
1267   manager->SetState(
1268       GetDefaultIMEState(ProfileHelper::Get()->GetProfileByUser(active_user)));
1269 }
1270
1271 scoped_refptr<input_method::InputMethodManager::State>
1272 UserSessionManager::GetDefaultIMEState(Profile* profile) {
1273   scoped_refptr<input_method::InputMethodManager::State> state =
1274       default_ime_states_[profile];
1275   if (!state.get()) {
1276     // Profile can be NULL in tests.
1277     state = input_method::InputMethodManager::Get()->CreateNewState(profile);
1278     default_ime_states_[profile] = state;
1279   }
1280   return state;
1281 }
1282
1283 EasyUnlockKeyManager* UserSessionManager::GetEasyUnlockKeyManager() {
1284   if (!easy_unlock_key_manager_)
1285     easy_unlock_key_manager_.reset(new EasyUnlockKeyManager);
1286
1287   return easy_unlock_key_manager_.get();
1288 }
1289
1290 }  // namespace chromeos