login_utils.cc revision f2477e01787aa58f445919b809d89e252beef54f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/login_utils.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h"
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/memory/weak_ptr.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_member.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
245e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h"
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/sys_info.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/task_runner_util.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/worker_pool.h"
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/about_flags.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/app_mode/app_mode_utils.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_shutdown.h"
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/boot_times_loader.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/input_method_util.h"
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/login/chrome_restart_request.h"
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/chromeos/login/input_events_blocker.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/login_display_host.h"
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/chromeos/login/oauth2_login_manager.h"
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/chromeos/login/oauth2_login_manager_factory.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/parallel_authenticator.h"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/login/profile_auth_data.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/screen_locker.h"
468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/chromeos/login/supervised_user_manager.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/first_run/first_run.h"
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google/google_util_chromeos.h"
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h"
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/pref_service_flags_storage.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/rlz/rlz.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/signin/signin_manager.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h"
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/start_page_service.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/startup/startup_browser_creator.h"
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/logging_chrome.h"
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/chromeos_switches.h"
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/cryptohome/cryptohome_util.h"
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/dbus/cryptohome_client.h"
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/dbus/dbus_method_call_status.h"
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/session_manager_client.h"
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/ime/input_method_manager.h"
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/settings/cros_settings_names.h"
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_consumer.h"
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/network_change_notifier.h"
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_RLZ)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Flag file that disables RLZ tracking, when present.
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType kRLZDisabledFlagName[] =
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FILE_PATH_LITERAL(".rlz_disabled");
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetRlzDisabledFlagPath() {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return file_util::GetHomeDir().Append(kRLZDisabledFlagName);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)struct DoBrowserLaunchOnLocaleLoadedData;
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LoginUtilsImpl
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public LoginUtils,
10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      public OAuth2LoginManager::Observer,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public net::NetworkChangeNotifier::ConnectionTypeObserver,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public base::SupportsWeakPtr<LoginUtilsImpl> {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoginUtilsImpl()
1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      : has_web_auth_cookies_(false),
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_(NULL),
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        should_restore_auth_session_(false),
11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        exit_after_session_restore_(false),
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        session_restore_strategy_(
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~LoginUtilsImpl() {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // LoginUtils implementation:
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DoBrowserLaunch(Profile* profile,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               LoginDisplayHost* login_host) OVERRIDE;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void PrepareProfile(
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const UserContext& user_context,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& display_email,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool has_cookies,
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      bool has_active_session,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoginUtils::Delegate* delegate) OVERRIDE;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DelegateDeleted(LoginUtils::Delegate* delegate) OVERRIDE;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CompleteOffTheRecordLogin(const GURL& start_url) OVERRIDE;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetFirstLoginPrefs(PrefService* prefs) OVERRIDE;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual scoped_refptr<Authenticator> CreateAuthenticator(
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoginStatusConsumer* consumer) OVERRIDE;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RestoreAuthenticationSession(Profile* profile) OVERRIDE;
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void InitRlzDelayed(Profile* user_profile) OVERRIDE;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // OAuth2LoginManager::Observer overrides.
14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void OnSessionRestoreStateChanged(
14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      Profile* user_profile,
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      OAuth2LoginManager::SessionRestoreState state) OVERRIDE;
14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual void OnNewRefreshTokenAvaiable(Profile* user_profile) OVERRIDE;
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void OnSessionAuthenticated(Profile* user_profile) OVERRIDE;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // net::NetworkChangeNotifier::ConnectionTypeObserver overrides.
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnConnectionTypeChanged(
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::NetworkChangeNotifier::ConnectionType type) OVERRIDE;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // DoBrowserLaunch is split into two parts.
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This one is called after anynchronous locale switch.
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void DoBrowserLaunchOnLocaleLoadedImpl(Profile* profile,
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                         LoginDisplayHost* login_host);
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Callback for locale_util::SwitchLanguage().
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static void DoBrowserLaunchOnLocaleLoaded(
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      scoped_ptr<DoBrowserLaunchOnLocaleLoadedData> context,
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const std::string& locale,
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const std::string& loaded_locale,
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const bool success);
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restarts OAuth session authentication check.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void KickStartAuthentication(Profile* profile);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Callback for Profile::CREATE_STATUS_CREATED profile state.
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Initializes basic preferences for newly created profile. Any other
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // early profile initialization that needs to happen before
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ProfileManager::DoFinalInit() gets called is done here.
171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void InitProfilePreferences(Profile* user_profile,
172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                              const std::string& email);
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback for asynchronous profile creation.
175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void OnProfileCreated(const std::string& email,
176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        Profile* profile,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        Profile::CreateStatus status);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Callback for Profile::CREATE_STATUS_INITIALIZED profile state.
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Profile is created, extensions and promo resources are initialized.
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UserProfileInitialized(Profile* user_profile);
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Callback to resume profile creation after transferring auth data from
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the authentication profile.
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CompleteProfileCreate(Profile* user_profile);
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Finalized profile preparation.
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void FinalizePrepareProfile(Profile* user_profile);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Initializes member variables needed for session restore process via
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // OAuthLoginManager.
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InitSessionRestoreStrategy();
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Restores GAIA auth cookies for the created user profile from OAuth2 token.
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RestoreAuthSession(Profile* user_profile,
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          bool restore_from_auth_cookies);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Initializes RLZ. If |disabled| is true, RLZ pings are disabled.
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InitRlz(Profile* user_profile, bool disabled);
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Starts signing related services. Initiates token retrieval.
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StartSignedInServices(Profile* profile);
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Attempts exiting browser process and esures this does not happen
20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // while we are still fetching new OAuth refresh tokens.
20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  void AttemptExit(Profile* profile);
20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UserContext user_context_;
20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // True if the authentication profile's cookie jar should contain
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // authentication cookies from the authentication extension log in flow.
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool has_web_auth_cookies_;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Has to be scoped_refptr, see comment for CreateAuthenticator(...).
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Authenticator> authenticator_;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delegate to be fired when the profile will be prepared.
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoginUtils::Delegate* delegate_;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if should restore authentication session when notified about
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // online state change.
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool should_restore_auth_session_;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // True if we should restart chrome right after session restore.
22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool exit_after_session_restore_;
22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sesion restore strategy.
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OAuth2LoginManager::SessionRestoreStrategy session_restore_strategy_;
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // OAuth2 refresh token for session restore.
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string oauth2_refresh_token_;
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LoginUtilsImpl);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LoginUtilsWrapper {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static LoginUtilsWrapper* GetInstance() {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Singleton<LoginUtilsWrapper>::get();
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoginUtils* get() {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock create(create_lock_);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ptr_.get())
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reset(new LoginUtilsImpl);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ptr_.get();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void reset(LoginUtils* ptr) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr_.reset(ptr);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct DefaultSingletonTraits<LoginUtilsWrapper>;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoginUtilsWrapper() {}
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Lock create_lock_;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<LoginUtils> ptr_;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LoginUtilsWrapper);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)struct DoBrowserLaunchOnLocaleLoadedData {
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DoBrowserLaunchOnLocaleLoadedData(LoginUtilsImpl* login_utils_impl,
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    Profile* profile,
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    LoginDisplayHost* display_host)
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : login_utils_impl(login_utils_impl),
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        profile(profile),
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        display_host(display_host) {}
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  LoginUtilsImpl* login_utils_impl;
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Profile* profile;
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  chromeos::LoginDisplayHost* display_host;
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Block UI events untill ResourceBundle is reloaded.
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InputEventsBlocker input_events_blocker;
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void LoginUtilsImpl::DoBrowserLaunchOnLocaleLoaded(
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<DoBrowserLaunchOnLocaleLoadedData> context,
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& /* locale */,
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& /* loaded_locale */,
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const bool /* success */) {
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  context->login_utils_impl->DoBrowserLaunchOnLocaleLoadedImpl(
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      context->profile, context->display_host);
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Called from DoBrowserLaunch() or from
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// DoBrowserLaunchOnLocaleLoaded() depending on
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// if locale switch was needed.
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void LoginUtilsImpl::DoBrowserLaunchOnLocaleLoadedImpl(
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Profile* profile,
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    LoginDisplayHost* login_host) {
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!UserManager::Get()->GetCurrentUserFlow()->ShouldLaunchBrowser()) {
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    UserManager::Get()->GetCurrentUserFlow()->LaunchExtraSteps(profile);
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CommandLine user_flags(CommandLine::NO_PROGRAM);
3007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  about_flags::PrefServiceFlagsStorage flags_storage_(profile->GetPrefs());
301d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  about_flags::ConvertFlagsToSwitches(&flags_storage_, &user_flags,
302d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                      about_flags::kAddSentinels);
303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Only restart if needed and if not going into managed mode.
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Don't restart browser if it is not first profile in session.
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (UserManager::Get()->GetLoggedInUsers().size() == 1 &&
30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      !UserManager::Get()->IsLoggedInAsLocallyManagedUser() &&
307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      !about_flags::AreSwitchesIdenticalToCurrentCommandLine(
3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          user_flags, *CommandLine::ForCurrentProcess())) {
3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    CommandLine::StringVector flags;
3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // argv[0] is the program name |CommandLine::NO_PROGRAM|.
3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    flags.assign(user_flags.argv().begin() + 1, user_flags.argv().end());
3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    VLOG(1) << "Restarting to apply per-session flags...";
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DBusThreadManager::Get()->GetSessionManagerClient()->SetFlagsForUser(
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        UserManager::Get()->GetActiveUser()->email(), flags);
31568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    AttemptExit(profile);
3167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (login_host) {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    login_host->SetStatusAreaVisible(true);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    login_host->BeforeSessionStart();
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BootTimesLoader::Get()->AddLoginTimeMarker("BrowserLaunched", false);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "Launching browser...";
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartupBrowserCreator browser_creator;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int return_code;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ?
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN;
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser_creator.LaunchBrowser(*CommandLine::ForCurrentProcess(),
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                profile,
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                base::FilePath(),
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                chrome::startup::IS_PROCESS_STARTUP,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                first_run,
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                &return_code);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Triggers app launcher start page service to load start page web contents.
3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  app_list::StartPageService::Get(profile);
3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mark login host for deletion after browser starts.  This
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // guarantees that the message loop will be referenced by the
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // browser before it is dereferenced by the login host.
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (login_host)
346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    login_host->Finalize();
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UserManager::Get()->SessionStarted();
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void LoginUtilsImpl::DoBrowserLaunch(Profile* profile,
351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     LoginDisplayHost* login_host) {
352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (browser_shutdown::IsTryingToQuit())
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  User* const user = UserManager::Get()->GetUserByProfile(profile);
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<DoBrowserLaunchOnLocaleLoadedData> data(
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new DoBrowserLaunchOnLocaleLoadedData(this, profile, login_host));
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<locale_util::SwitchLanguageCallback> callback(
360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new locale_util::SwitchLanguageCallback(
361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          base::Bind(&LoginUtilsImpl::DoBrowserLaunchOnLocaleLoaded,
362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     base::Passed(data.Pass()))));
363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!UserManager::Get()->
364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      RespectLocalePreference(profile, user, callback.Pass())) {
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DoBrowserLaunchOnLocaleLoadedImpl(profile, login_host);
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginUtilsImpl::PrepareProfile(
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const UserContext& user_context,
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& display_email,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool has_cookies,
37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    bool has_active_session,
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoginUtils::Delegate* delegate) {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BootTimesLoader* btl = BootTimesLoader::Get();
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VLOG(1) << "Completing login for " << user_context.username;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!has_active_session) {
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    btl->AddLoginTimeMarker("StartSession-Start", false);
38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DBusThreadManager::Get()->GetSessionManagerClient()->StartSession(
38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        user_context.username);
38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    btl->AddLoginTimeMarker("StartSession-End", false);
38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  btl->AddLoginTimeMarker("UserLoggedIn-Start", false);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UserManager* user_manager = UserManager::Get();
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_manager->UserLoggedIn(user_context.username,
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_context.username_hash,
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             false);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  btl->AddLoginTimeMarker("UserLoggedIn-End", false);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Switch log file as soon as possible.
3944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (base::SysInfo::IsRunningOnChromeOS())
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logging::RedirectChromeLogging(*(CommandLine::ForCurrentProcess()));
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update user's displayed email.
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!display_email.empty())
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_manager->SaveUserDisplayEmail(user_context.username, display_email);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_context_ = user_context;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  has_web_auth_cookies_ = has_cookies;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = delegate;
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitSessionRestoreStrategy();
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
407d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Can't use display_email because it is empty when existing user logs in
408d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // using sing-in pod on login screen (i.e. user didn't type email).
409d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  g_browser_process->profile_manager()->CreateProfileAsync(
410d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      user_manager->GetUserProfileDir(user_context.username),
411d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      base::Bind(&LoginUtilsImpl::OnProfileCreated, AsWeakPtr(),
412d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                 user_context.username),
413d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      string16(), string16(), std::string());
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginUtilsImpl::DelegateDeleted(LoginUtils::Delegate* delegate) {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_ == delegate)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_ = NULL;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
421d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void LoginUtilsImpl::InitProfilePreferences(Profile* user_profile,
422d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const std::string& email) {
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (UserManager::Get()->IsCurrentUserNew())
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetFirstLoginPrefs(user_profile->GetPrefs());
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (UserManager::Get()->IsLoggedInAsLocallyManagedUser()) {
4273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    User* active_user = UserManager::Get()->GetActiveUser();
4283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::string managed_user_sync_id =
4298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        UserManager::Get()->GetSupervisedUserManager()->
4308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            GetUserSyncId(active_user->email());
4313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // TODO(ibraaaa): Remove that when 97% of our users are using M31.
4333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // http://crbug.com/276163
4343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (managed_user_sync_id.empty())
4353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      managed_user_sync_id = "DUMMY_ID";
4363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    user_profile->GetPrefs()->SetString(prefs::kManagedUserId,
4383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        managed_user_sync_id);
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Make sure that the google service username is properly set (we do this
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // on every sign in, not just the first login, to deal with existing
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // profiles that might not have it set yet).
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StringPrefMember google_services_username;
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    google_services_username.Init(prefs::kGoogleServicesUsername,
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  user_profile->GetPrefs());
446d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const User* user = UserManager::Get()->FindUser(email);
447d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    google_services_username.SetValue(user ? user->display_email() : email);
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginUtilsImpl::InitSessionRestoreStrategy() {
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommandLine* command_line = CommandLine::ForCurrentProcess();
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool in_app_mode = chrome::IsRunningInForcedAppMode();
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Are we in kiosk app mode?
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (in_app_mode) {
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (command_line->HasSwitch(::switches::kAppModeOAuth2Token)) {
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      oauth2_refresh_token_ = command_line->GetSwitchValueASCII(
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          ::switches::kAppModeOAuth2Token);
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (command_line->HasSwitch(::switches::kAppModeAuthCode)) {
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_context_.auth_code = command_line->GetSwitchValueASCII(
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          ::switches::kAppModeAuthCode);
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!has_web_auth_cookies_);
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!user_context_.auth_code.empty()) {
46958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE;
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (!oauth2_refresh_token_.empty()) {
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      session_restore_strategy_ =
47258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          OAuth2LoginManager::RESTORE_FROM_PASSED_OAUTH2_REFRESH_TOKEN;
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      session_restore_strategy_ =
47558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN;
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_web_auth_cookies_) {
48158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR;
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (!user_context_.auth_code.empty()) {
48358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE;
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    session_restore_strategy_ =
48658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN;
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginUtilsImpl::OnProfileCreated(
492d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const std::string& email,
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* user_profile,
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile::CreateStatus status) {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(user_profile);
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (status) {
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Profile::CREATE_STATUS_CREATED:
499d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      InitProfilePreferences(user_profile, email);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
50168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case Profile::CREATE_STATUS_INITIALIZED:
50268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      UserProfileInitialized(user_profile);
50368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      break;
504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case Profile::CREATE_STATUS_LOCAL_FAIL:
505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case Profile::CREATE_STATUS_REMOTE_FAIL:
506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case Profile::CREATE_STATUS_CANCELED:
507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case Profile::MAX_CREATE_STATUS:
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginUtilsImpl::UserProfileInitialized(Profile* user_profile) {
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BootTimesLoader* btl = BootTimesLoader::Get();
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  btl->AddLoginTimeMarker("UserProfileGotten", false);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (user_context_.using_oauth) {
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Transfer proxy authentication cache, cookies (optionally) and server
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // bound certs from the profile that was used for authentication.  This
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // profile contains cookies that auth extension should have already put in
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // place that will ensure that the newly created session is authenticated
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // for the websites that work with the used authentication schema.
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ProfileAuthData::Transfer(authenticator_->authentication_profile(),
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              user_profile,
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              has_web_auth_cookies_,  // transfer_cookies
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              base::Bind(
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  &LoginUtilsImpl::CompleteProfileCreate,
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  AsWeakPtr(),
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  user_profile));
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5339ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  FinalizePrepareProfile(user_profile);
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginUtilsImpl::CompleteProfileCreate(Profile* user_profile) {
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RestoreAuthSession(user_profile, has_web_auth_cookies_);
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FinalizePrepareProfile(user_profile);
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginUtilsImpl::RestoreAuthSession(Profile* user_profile,
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        bool restore_from_auth_cookies) {
5437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CHECK((authenticator_.get() && authenticator_->authentication_profile()) ||
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !restore_from_auth_cookies);
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (chrome::IsRunningInForcedAppMode() ||
5473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      CommandLine::ForCurrentProcess()->HasSwitch(
5483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          chromeos::switches::kOobeSkipPostLogin))
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
55168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  exit_after_session_restore_ = false;
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove legacy OAuth1 token if we have one. If it's valid, we should already
553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // have OAuth2 refresh token in OAuth2TokenService that could be used to
554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // retrieve all other tokens and user_context.
55558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OAuth2LoginManager* login_manager =
55658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile);
55758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  login_manager->AddObserver(this);
55858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  login_manager->RestoreSession(
5597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      authenticator_.get() && authenticator_->authentication_profile()
5607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          ? authenticator_->authentication_profile()->GetRequestContext()
5617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          : NULL,
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      session_restore_strategy_,
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      oauth2_refresh_token_,
564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_context_.auth_code);
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginUtilsImpl::FinalizePrepareProfile(Profile* user_profile) {
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BootTimesLoader* btl = BootTimesLoader::Get();
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Own TPM device if, for any reason, it has not been done in EULA
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // wizard screen.
5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CryptohomeClient* client = DBusThreadManager::Get()->GetCryptohomeClient();
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  btl->AddLoginTimeMarker("TPMOwn-Start", false);
5734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (cryptohome_util::TpmIsEnabled() && !cryptohome_util::TpmIsBeingOwned()) {
5744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (cryptohome_util::TpmIsOwned()) {
5754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      client->CallTpmClearStoredPasswordAndBlock();
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      client->TpmCanAttemptOwnership(EmptyVoidDBusMethodCallback());
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  btl->AddLoginTimeMarker("TPMOwn-End", false);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  user_profile->OnLogin();
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Send the notification before creating the browser so additional objects
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that need the profile (e.g. the launcher) can be created first.
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources(),
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Details<Profile>(user_profile));
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Initialize RLZ only for primary user.
5924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (UserManager::Get()->GetPrimaryUser() ==
5934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      UserManager::Get()->GetUserByProfile(user_profile)) {
5944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    InitRlzDelayed(user_profile);
5954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(altimofeev): This pointer should probably never be NULL, but it looks
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // like LoginUtilsImpl::OnProfileCreated() may be getting called before
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // LoginUtilsImpl::PrepareProfile() has set |delegate_| when Chrome is killed
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // during shutdown in tests -- see http://crosbug.com/18269.  Replace this
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 'if' statement with a CHECK(delegate_) once the underlying issue is
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // resolved.
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnProfilePrepared(user_profile);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginUtilsImpl::InitRlzDelayed(Profile* user_profile) {
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_RLZ)
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!g_browser_process->local_state()->HasPrefPath(prefs::kRLZBrand)) {
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Read brand code asynchronously from an OEM file and repost ourselves.
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    google_util::chromeos::SetBrandFromFile(
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&LoginUtilsImpl::InitRlzDelayed, AsWeakPtr(), user_profile));
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::PostTaskAndReplyWithResult(
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::WorkerPool::GetTaskRunner(false),
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
6177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&base::PathExists, GetRlzDisabledFlagPath()),
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&LoginUtilsImpl::InitRlz, AsWeakPtr(), user_profile));
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginUtilsImpl::InitRlz(Profile* user_profile, bool disabled) {
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_RLZ)
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrefService* local_state = g_browser_process->local_state();
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (disabled) {
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty brand code means an organic install (no RLZ pings are sent).
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    google_util::chromeos::ClearBrandForCurrentSession();
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (disabled != local_state->GetBoolean(prefs::kRLZDisabled)) {
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // When switching to RLZ enabled/disabled state, clear all recorded events.
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RLZTracker::ClearRlzState();
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    local_state->SetBoolean(prefs::kRLZDisabled, disabled);
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Init the RLZ library.
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int ping_delay = user_profile->GetPrefs()->GetInteger(
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      first_run::GetPingDelayPrefName().c_str());
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Negative ping delay means to send ping immediately after a first search is
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // recorded.
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RLZTracker::InitRlzFromProfileDelayed(
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      user_profile, UserManager::Get()->IsCurrentUserNew(),
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ping_delay < 0, base::TimeDelta::FromMilliseconds(abs(ping_delay)));
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (delegate_)
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delegate_->OnRlzInitialized(user_profile);
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginUtilsImpl::StartSignedInServices(Profile* user_profile) {
648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SigninManagerBase* signin =
649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SigninManagerFactory::GetForProfile(user_profile);
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(signin);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure SigninManager is connected to our current user (this should
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // happen automatically because we set kGoogleServicesUsername in
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OnProfileCreated()).
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(UserManager::Get()->GetLoggedInUser()->display_email(),
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            signin->GetAuthenticatedUsername());
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool initialized = false;
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!initialized) {
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    initialized = true;
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Notify the sync service that signin was successful. Note: Since the sync
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // service is lazy-initialized, we need to make sure it has been created.
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProfileSyncService* sync_service =
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProfileSyncServiceFactory::GetInstance()->GetForProfile(user_profile);
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We may not always have a passphrase (for example, on a restart after a
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // browser crash). Only notify the sync service if we have a passphrase,
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // so it can do any required re-encryption.
666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!user_context_.password.empty() && sync_service) {
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GoogleServiceSigninSuccessDetails details(
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          signin->GetAuthenticatedUsername(),
669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          user_context_.password);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::current()->Notify(
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::Source<Profile>(user_profile),
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::Details<const GoogleServiceSigninSuccessDetails>(&details));
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_context_.password.clear();
677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_context_.auth_code.clear();
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginUtilsImpl::CompleteOffTheRecordLogin(const GURL& start_url) {
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "Completing incognito login";
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For guest session we ask session manager to restart Chrome with --bwsi
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // flag. We keep only some of the arguments of this process.
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine command_line(browser_command_line.GetProgram());
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string cmd_line_str = GetOffTheRecordCommandLine(start_url,
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                        browser_command_line,
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                        &command_line);
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RestartChrome(cmd_line_str);
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginUtilsImpl::SetFirstLoginPrefs(PrefService* prefs) {
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "Setting first login prefs";
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BootTimesLoader* btl = BootTimesLoader::Get();
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string locale = g_browser_process->GetApplicationLocale();
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First, we'll set kLanguagePreloadEngines.
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  input_method::InputMethodManager* manager =
701a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      input_method::InputMethodManager::Get();
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> input_method_ids;
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager->GetInputMethodUtil()->GetFirstLoginInputMethodIds(
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      locale, manager->GetCurrentInputMethod(), &input_method_ids);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Save the input methods in the user's preferences.
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPrefMember language_preload_engines;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  language_preload_engines.Init(prefs::kLanguagePreloadEngines,
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                prefs);
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  language_preload_engines.SetValue(JoinString(input_method_ids, ','));
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  btl->AddLoginTimeMarker("IMEStarted", false);
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second, we'll set kLanguagePreferredLanguages.
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> language_codes;
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The current locale should be on the top.
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  language_codes.push_back(locale);
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add input method IDs based on the input methods, as there may be
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // input methods that are unrelated to the current locale. Example: the
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // hardware keyboard layout xkb:us::eng is used for logging in, but the
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UI language is set to French. In this case, we should set "fr,en"
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to the preferred languages preference.
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> candidates;
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager->GetInputMethodUtil()->GetLanguageCodesFromInputMethodIds(
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      input_method_ids, &candidates);
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < candidates.size(); ++i) {
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& candidate = candidates[i];
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Skip if it's already in language_codes.
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (std::count(language_codes.begin(), language_codes.end(),
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   candidate) == 0) {
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      language_codes.push_back(candidate);
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Save the preferred languages in the user's preferences.
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPrefMember language_preferred_languages;
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  language_preferred_languages.Init(prefs::kLanguagePreferredLanguages,
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    prefs);
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  language_preferred_languages.SetValue(JoinString(language_codes, ','));
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Authenticator> LoginUtilsImpl::CreateAuthenticator(
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoginStatusConsumer* consumer) {
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Screen locker needs new Authenticator instance each time.
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ScreenLocker::default_screen_locker()) {
7447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (authenticator_.get())
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      authenticator_->SetConsumer(NULL);
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    authenticator_ = NULL;
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (authenticator_.get() == NULL) {
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    authenticator_ = new ParallelAuthenticator(consumer);
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(nkostylev): Fix this hack by improving Authenticator dependencies.
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    authenticator_->SetConsumer(consumer);
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return authenticator_;
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginUtilsImpl::RestoreAuthenticationSession(Profile* user_profile) {
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We don't need to restore session for demo/guest/stub/public account users.
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!UserManager::Get()->IsUserLoggedIn() ||
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UserManager::Get()->IsLoggedInAsGuest() ||
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UserManager::Get()->IsLoggedInAsPublicAccount() ||
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UserManager::Get()->IsLoggedInAsDemoUser() ||
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UserManager::Get()->IsLoggedInAsStub()) {
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!net::NetworkChangeNotifier::IsOffline()) {
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    should_restore_auth_session_ = false;
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RestoreAuthSession(user_profile, false);
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Even if we're online we should wait till initial
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // OnConnectionTypeChanged() call. Otherwise starting fetchers too early may
77458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // end up canceling all request when initial network connection type is
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // processed. See http://crbug.com/121643.
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    should_restore_auth_session_ = true;
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void LoginUtilsImpl::OnSessionRestoreStateChanged(
78158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    Profile* user_profile,
78258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    OAuth2LoginManager::SessionRestoreState state) {
78368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  User::OAuthTokenStatus user_status = User::OAUTH_TOKEN_STATUS_UNKNOWN;
78458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OAuth2LoginManager* login_manager =
78558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile);
7864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool connection_error = false;
78858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  switch (state) {
78958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case OAuth2LoginManager::SESSION_RESTORE_DONE:
79068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      user_status = User::OAUTH2_TOKEN_STATUS_VALID;
79158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      break;
79258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case OAuth2LoginManager::SESSION_RESTORE_FAILED:
79368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      user_status = User::OAUTH2_TOKEN_STATUS_INVALID;
79458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      break;
7954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED:
7964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      connection_error = true;
7974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      break;
79868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case OAuth2LoginManager::SESSION_RESTORE_NOT_STARTED:
79968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case OAuth2LoginManager::SESSION_RESTORE_PREPARING:
80068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS:
80168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return;
80258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
80368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // We should not be clearing existing token state if that was a connection
8054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // error. http://crbug.com/295245
8064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!connection_error) {
8074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // We are in one of "done" states here.
8084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    UserManager::Get()->SaveUserOAuthStatus(
8094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        UserManager::Get()->GetLoggedInUser()->email(),
8104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        user_status);
8114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
81268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  login_manager->RemoveObserver(this);
81368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
81468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
81568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void LoginUtilsImpl::OnNewRefreshTokenAvaiable(Profile* user_profile) {
81668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Check if we were waiting to restart chrome.
81768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!exit_after_session_restore_)
81868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
81968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
82068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  OAuth2LoginManager* login_manager =
82168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile);
82268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  login_manager->RemoveObserver(this);
82368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
82468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Mark user auth token status as valid.
82568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UserManager::Get()->SaveUserOAuthStatus(
82668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      UserManager::Get()->GetLoggedInUser()->email(),
82768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      User::OAUTH2_TOKEN_STATUS_VALID);
82868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
82968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  LOG(WARNING) << "Exiting after new refresh token fetched";
83068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // We need to exit cleanly in this case to make sure OAuth2 RT is actually
83168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // saved.
83268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  chrome::ExitCleanly();
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void LoginUtilsImpl::OnSessionAuthenticated(Profile* user_profile) {
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartSignedInServices(user_profile);
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginUtilsImpl::OnConnectionTypeChanged(
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::NetworkChangeNotifier::ConnectionType type) {
84158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Profile* user_profile = ProfileManager::GetDefaultProfile();
84258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OAuth2LoginManager* login_manager =
84358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile);
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type != net::NetworkChangeNotifier::CONNECTION_NONE &&
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UserManager::Get()->IsUserLoggedIn()) {
84758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (login_manager->state() ==
84858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) {
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If we come online for the first time after successful offline login,
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // we need to kick off OAuth token verification process again.
85158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      login_manager->ContinueSessionRestore();
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (should_restore_auth_session_) {
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      should_restore_auth_session_ = false;
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RestoreAuthSession(user_profile, has_web_auth_cookies_);
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void LoginUtilsImpl::AttemptExit(Profile* profile) {
86068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (session_restore_strategy_ !=
86168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR) {
86268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    chrome::AttemptExit();
86368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
86468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
86568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
86668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // We can't really quit if the session restore process that mints new
86768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // refresh token is still in progress.
86868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  OAuth2LoginManager* login_manager =
86968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile);
87068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (login_manager->state() !=
87168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          OAuth2LoginManager::SESSION_RESTORE_PREPARING &&
87268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      login_manager->state() !=
87368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) {
87468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    chrome::AttemptExit();
87568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
87668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
87768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
87868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  LOG(WARNING) << "Attempting browser restart during session restore.";
87968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  exit_after_session_restore_ = true;
88068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
88168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginUtils::RegisterPrefs(PrefRegistrySimple* registry) {
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->RegisterBooleanPref(prefs::kFactoryResetRequested, false);
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->RegisterStringPref(prefs::kRLZBrand, std::string());
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->RegisterBooleanPref(prefs::kRLZDisabled, false);
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoginUtils* LoginUtils::Get() {
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return LoginUtilsWrapper::GetInstance()->get();
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginUtils::Set(LoginUtils* mock) {
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoginUtilsWrapper::GetInstance()->reset(mock);
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool LoginUtils::IsWhitelisted(const std::string& username) {
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CrosSettings* cros_settings = CrosSettings::Get();
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool allow_new_user = false;
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (allow_new_user)
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cros_settings->FindEmailInList(kAccountsPrefUsers, username);
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
910