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