172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/login/login_utils.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include <vector>
8513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/command_line.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h"
153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_util.h"
164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/stringprintf.h"
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/synchronization/lock.h"
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/threading/thread_restrictions.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h"
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h"
22731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/chromeos/boot_times_loader.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/cros/login_library.h"
24513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/chromeos/cros/network_library.h"
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/chromeos/input_method/input_method_util.h"
2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/chromeos/login/background_view.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/login/cookie_fetcher.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/login/google_authenticator.h"
294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/chromeos/login/language_switch_menu.h"
303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/chromeos/login/ownership_service.h"
31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/chromeos/login/parallel_authenticator.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/login/user_image_downloader.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/login/user_manager.h"
34201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/chromeos/proxy_config_service.h"
3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h"
36201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/net/chrome_url_request_context.h"
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/gaia/token_service.h"
38513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/net/preconnect.h"
39201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/net/pref_proxy_config_service.h"
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/plugin_updater.h"
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_member.h"
4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile_manager.h"
44513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/sync/profile_sync_service.h"
454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser_init.h"
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_paths.h"
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_switches.h"
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/logging_chrome.h"
494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/common/net/gaia/gaia_auth_fetcher.h"
503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/net/gaia/gaia_constants.h"
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/pref_names.h"
52201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/common/url_constants.h"
53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h"
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/cookie_store.h"
56201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "net/proxy/proxy_config_service.h"
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_context.h"
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/url_request/url_request_context_getter.h"
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/widget/widget_gtk.h"
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/gfx/gl/gl_switches.h"
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace chromeos {
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Affixes for Auth token received from ClientLogin request.
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kAuthPrefix[] = "Auth=";
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kAuthSuffix[] = "\n";
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Increase logging level for Guest mode to avoid LOG(INFO) messages in logs.
714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst char kGuestModeLoggingLevel[] = "1";
724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Format of command line switch.
74201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char kSwitchFormatString[] = " --%s=\"%s\"";
75201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// User name which is used in the Guest session.
77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst char kGuestUserName[] = "";
78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
79201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Resets the proxy configuration service for the default request context.
80201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochclass ResetDefaultProxyConfigServiceTask : public Task {
81201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch public:
82201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ResetDefaultProxyConfigServiceTask(
83201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      net::ProxyConfigService* proxy_config_service)
84201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      : proxy_config_service_(proxy_config_service) {}
85201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual ~ResetDefaultProxyConfigServiceTask() {}
86201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
87201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Task override.
88201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual void Run() {
89201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    net::URLRequestContextGetter* getter = Profile::GetDefaultRequestContext();
91201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    DCHECK(getter);
92201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (getter) {
93201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      getter->GetURLRequestContext()->proxy_service()->ResetConfigService(
94201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          proxy_config_service_.release());
95201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    }
96201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
97201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
98201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch private:
99201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_ptr<net::ProxyConfigService> proxy_config_service_;
100201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
101201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(ResetDefaultProxyConfigServiceTask);
102201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch};
1034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass LoginUtilsImpl : public LoginUtils,
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       public ProfileManager::Observer {
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoginUtilsImpl()
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      : background_view_(NULL) {
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void PrepareProfile(
114513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      const std::string& username,
115513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      const std::string& password,
11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const GaiaAuthConsumer::ClientLoginResult& credentials,
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      bool pending_requests,
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      LoginUtils::Delegate* delegate);
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Invoked after the tmpfs is successfully mounted.
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Launches a browser in the incognito mode.
1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void CompleteOffTheRecordLogin(const GURL& start_url);
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Invoked when the user is logging in for the first time, or is logging in as
12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // a guest user.
12621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual void SetFirstLoginPrefs(PrefService* prefs);
12721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Creates and returns the authenticator to use. The caller owns the returned
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Authenticator and must delete it when done.
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual Authenticator* CreateAuthenticator(LoginStatusConsumer* consumer);
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
132513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Warms the url used by authentication.
133513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual void PrewarmAuthentication();
134513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Given the credentials try to exchange them for
13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // full-fledged Google authentication cookies.
13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual void FetchCookies(
13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      Profile* profile,
13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const GaiaAuthConsumer::ClientLoginResult& credentials);
14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Supply credentials for sync and others to use.
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual void FetchTokens(
14321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      Profile* profile,
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const GaiaAuthConsumer::ClientLoginResult& credentials);
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Sets the current background view.
14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void SetBackgroundView(chromeos::BackgroundView* background_view);
14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
14972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Gets the current background view.
15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual chromeos::BackgroundView* GetBackgroundView();
15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // ProfileManager::Observer implementation:
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void OnProfileCreated(Profile* profile);
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
15572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen protected:
15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual std::string GetOffTheRecordCommandLine(
15772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      const GURL& start_url,
15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      const CommandLine& base_command_line,
15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      CommandLine *command_line);
16072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
1624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Check user's profile for kApplicationLocale setting.
16372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void RespectLocalePreference(Profile* pref);
1644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
16572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // The current background view.
16672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  chromeos::BackgroundView* background_view_;
16772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string username_;
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string password_;
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GaiaAuthConsumer::ClientLoginResult credentials_;
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool pending_requests_;
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Delegate to be fired when the profile will be prepared.
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  LoginUtils::Delegate* delegate_;
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(LoginUtilsImpl);
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass LoginUtilsWrapper {
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
18121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  static LoginUtilsWrapper* GetInstance() {
18221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return Singleton<LoginUtilsWrapper>::get();
18321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoginUtils* get() {
18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    base::AutoLock create(create_lock_);
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!ptr_.get())
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reset(new LoginUtilsImpl);
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return ptr_.get();
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void reset(LoginUtils* ptr) {
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ptr_.reset(ptr);
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
19721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  friend struct DefaultSingletonTraits<LoginUtilsWrapper>;
19821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
19921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  LoginUtilsWrapper() {}
20021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::Lock create_lock_;
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<LoginUtils> ptr_;
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(LoginUtilsWrapper);
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid LoginUtilsImpl::PrepareProfile(
208513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const std::string& username,
209513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const std::string& password,
21021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const GaiaAuthConsumer::ClientLoginResult& credentials,
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool pending_requests,
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    LoginUtils::Delegate* delegate) {
213731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BootTimesLoader* btl = BootTimesLoader::Get();
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
215731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  VLOG(1) << "Completing login for " << username;
216731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  btl->AddLoginTimeMarker("CompletingLogin", false);
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (CrosLibrary::Get()->EnsureLoaded()) {
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CrosLibrary::Get()->GetLoginLibrary()->StartSession(username, "");
220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    btl->AddLoginTimeMarker("StartedSession", false);
221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserManager::Get()->UserLoggedIn(username);
224731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  btl->AddLoginTimeMarker("UserLoggedIn", false);
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Switch log file as soon as possible.
227513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  logging::RedirectChromeLogging(*(CommandLine::ForCurrentProcess()));
228731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  btl->AddLoginTimeMarker("LoggingRedirected", false);
229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  username_ = username;
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  password_ = password;
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  credentials_ = credentials;
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  pending_requests_ = pending_requests;
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delegate_ = delegate;
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The default profile will have been changed because the ProfileManager
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // will process the notification that the UserManager sends out.
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ProfileManager::CreateDefaultProfileAsync(this);
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid LoginUtilsImpl::OnProfileCreated(Profile* profile) {
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CHECK(profile);
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BootTimesLoader* btl = BootTimesLoader::Get();
245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  btl->AddLoginTimeMarker("UserProfileGotten", false);
246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
247201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Change the proxy configuration service of the default request context to
248201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // use the preference configuration from the logged-in profile. This ensures
249201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // that requests done through the default context use the proxy configuration
250201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // provided by configuration policy.
251201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  //
252201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Note: Many of the clients of the default request context should probably be
253201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // fixed to use the request context of the profile they are associated with.
254201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // This includes preconnect, autofill, metrics service to only name a few;
255201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // see http://code.google.com/p/chromium/issues/detail?id=64339 for details.
256201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  //
257201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // TODO(mnissler) Revisit when support for device-specific policy arrives, at
258201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // which point the default request context can directly be managed through
259201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // device policy.
260201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  net::ProxyConfigService* proxy_config_service =
261201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      new PrefProxyConfigService(
262201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          profile->GetProxyConfigTracker(),
263201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          new chromeos::ProxyConfigService(
264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              g_browser_process->chromeos_proxy_config_service_impl()));
265201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
266201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                          new ResetDefaultProxyConfigServiceTask(
267201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                              proxy_config_service));
268201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
26921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Since we're doing parallel authentication, only new user sign in
270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // would perform online auth before calling PrepareProfile.
27121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // For existing users there's usually a pending online auth request.
27221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Cookies will be fetched after it's is succeeded.
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!pending_requests_) {
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FetchCookies(profile, credentials_);
27521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
276731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Init extension event routers; this normally happens in browser_main
278731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // but on Chrome OS it has to be deferred until the user finishes
279731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // logging in and the profile is not OTR.
28021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (profile->GetExtensionService() &&
28121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      profile->GetExtensionService()->extensions_enabled()) {
28221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    profile->GetExtensionService()->InitEventRouters();
283731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
284731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  btl->AddLoginTimeMarker("ExtensionsServiceStarted", false);
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Supply credentials for sync and others to use. Load tokens from disk.
2873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TokenService* token_service = profile->GetTokenService();
2883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  token_service->Initialize(GaiaConstants::kChromeOSSource,
2893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            profile);
2903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  token_service->LoadTokensFromDB();
29121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
29221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // For existing users there's usually a pending online auth request.
29321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Tokens will be fetched after it's is succeeded.
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!pending_requests_) {
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FetchTokens(profile, credentials_);
2963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  btl->AddLoginTimeMarker("TokensGotten", false);
2983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Set the CrOS user by getting this constructor run with the
3003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // user's email on first retrieval.
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  profile->GetProfileSyncService(username_)->SetPassphrase(password_,
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                           false,
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                           true);
304731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  btl->AddLoginTimeMarker("SyncStarted", false);
3053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
306731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Own TPM device if, for any reason, it has not been done in EULA
307731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // wizard screen.
308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (CrosLibrary::Get()->EnsureLoaded()) {
309731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CryptohomeLibrary* cryptohome = CrosLibrary::Get()->GetCryptohomeLibrary();
310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (cryptohome->TpmIsEnabled() && !cryptohome->TpmIsBeingOwned()) {
311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      if (cryptohome->TpmIsOwned()) {
312731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        cryptohome->TpmClearStoredPassword();
313731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      } else {
314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        cryptohome->TpmCanAttemptOwnership();
315731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
316731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
317731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
318731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  btl->AddLoginTimeMarker("TPMOwned", false);
3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
32072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  RespectLocalePreference(profile);
3214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (UserManager::Get()->current_user_is_new()) {
32321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    SetFirstLoginPrefs(profile->GetPrefs());
3243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
325513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
32672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Enable/disable plugins based on user preferences.
327dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  PluginUpdater::GetInstance()->UpdatePluginGroupsStateFromPrefs(profile);
32872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  btl->AddLoginTimeMarker("PluginsStateUpdated", false);
32972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
330513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // We suck. This is a hack since we do not have the enterprise feature
331513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // done yet to pull down policies from the domain admin. We'll take this
332513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // out when we get that done properly.
333513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // TODO(xiyuan): Remove this once enterprise feature is ready.
334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (EndsWith(username_, "@google.com", true)) {
335513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    PrefService* pref_service = profile->GetPrefs();
336513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    pref_service->SetBoolean(prefs::kEnableScreenLock, true);
337513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
338513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
339dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  profile->OnLogin();
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delegate_->OnProfilePrepared(profile);
342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(altimofeev): Need to sanitize memory used to store password.
344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  password_ = "";
345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  username_ = "";
346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  credentials_ = GaiaAuthConsumer::ClientLoginResult();
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginUtilsImpl::FetchCookies(
35021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    Profile* profile,
35121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const GaiaAuthConsumer::ClientLoginResult& credentials) {
35221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Take the credentials passed in and try to exchange them for
35321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // full-fledged Google authentication cookies.  This is
35421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // best-effort; it's possible that we'll fail due to network
35521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // troubles or some such.
35621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // CookieFetcher will delete itself once done.
35721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  CookieFetcher* cf = new CookieFetcher(profile);
35821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  cf->AttemptFetch(credentials.data);
35921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  BootTimesLoader::Get()->AddLoginTimeMarker("CookieFetchStarted", false);
36021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
36121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
36221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginUtilsImpl::FetchTokens(
36321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    Profile* profile,
36421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const GaiaAuthConsumer::ClientLoginResult& credentials) {
36521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  TokenService* token_service = profile->GetTokenService();
36621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  token_service->UpdateCredentials(credentials);
36721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (token_service->AreCredentialsValid()) {
36821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    token_service->StartFetchingTokens();
36921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
37021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
37121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
37272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid LoginUtilsImpl::RespectLocalePreference(Profile* profile) {
37372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(profile != NULL);
37472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  PrefService* prefs = profile->GetPrefs();
37572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(prefs != NULL);
37672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (g_browser_process == NULL)
37772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
37872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
37972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::string pref_locale = prefs->GetString(prefs::kApplicationLocale);
38072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (pref_locale.empty())
38172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    pref_locale = prefs->GetString(prefs::kApplicationLocaleBackup);
38272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (pref_locale.empty())
38372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    pref_locale = g_browser_process->GetApplicationLocale();
38472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(!pref_locale.empty());
38572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  profile->ChangeAppLocale(pref_locale, Profile::APP_LOCALE_CHANGED_VIA_LOGIN);
386dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Here we don't enable keyboard layouts. Input methods are set up when
387dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // the user first logs in. Then the user may customize the input methods.
388dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Hence changing input methods here, just because the user's UI language
389dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // is different from the login screen UI language, is not desirable. Note
390dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // that input method preferences are synced, so users can use their
391dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // farovite input methods as soon as the preferences are synced.
39221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  LanguageSwitchMenu::SwitchLanguage(pref_locale);
3934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
3944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid LoginUtilsImpl::CompleteOffTheRecordLogin(const GURL& start_url) {
396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  VLOG(1) << "Completing incognito login";
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserManager::Get()->OffTheRecordUserLoggedIn();
3993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (CrosLibrary::Get()->EnsureLoaded()) {
401731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // For guest session we ask session manager to restart Chrome with --bwsi
402731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // flag. We keep only some of the arguments of this process.
40372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
4043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    CommandLine command_line(browser_command_line.GetProgram());
40572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    std::string cmd_line_str =
40672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        GetOffTheRecordCommandLine(start_url,
40772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                   browser_command_line,
40872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                   &command_line);
4094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
4104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    CrosLibrary::Get()->GetLoginLibrary()->RestartJob(getpid(), cmd_line_str);
4113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
41472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstd::string LoginUtilsImpl::GetOffTheRecordCommandLine(
41572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const GURL& start_url,
41672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const CommandLine& base_command_line,
41772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    CommandLine* command_line) {
41872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  static const char* kForwardSwitches[] = {
41972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      switches::kEnableLogging,
420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      switches::kEnableAcceleratedPlugins,
421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      switches::kUseGL,
42272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      switches::kUserDataDir,
42372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      switches::kScrollPixels,
42472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      switches::kEnableGView,
42572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      switches::kNoFirstRun,
42672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      switches::kLoginProfile,
42772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      switches::kCompressSystemFeedback,
42872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      switches::kDisableSeccompSandbox,
429ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      switches::kPpapiFlashInProcess,
430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      switches::kPpapiFlashPath,
431ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      switches::kPpapiFlashVersion,
43272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined(HAVE_XINPUT2)
43372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      switches::kTouchDevices,
43472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif
43572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  };
43672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  command_line->CopySwitchesFrom(base_command_line,
43772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 kForwardSwitches,
43872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 arraysize(kForwardSwitches));
43972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  command_line->AppendSwitch(switches::kGuestSession);
44072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  command_line->AppendSwitch(switches::kIncognito);
44172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  command_line->AppendSwitchASCII(switches::kLoggingLevel,
44272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 kGuestModeLoggingLevel);
44372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
444dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  command_line->AppendSwitchASCII(switches::kLoginUser, kGuestUserName);
445dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
44672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (start_url.is_valid())
44772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    command_line->AppendArg(start_url.spec());
44872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
44972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Override the value of the homepage that is set in first run mode.
45072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // TODO(altimofeev): extend action of the |kNoFirstRun| to cover this case.
45172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  command_line->AppendSwitchASCII(
45272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      switches::kHomePage,
45372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      GURL(chrome::kChromeUINewTabURL).spec());
45472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
45572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::string cmd_line_str = command_line->command_line_string();
45672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Special workaround for the arguments that should be quoted.
45772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Copying switches won't be needed when Guest mode won't need restart
45872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // http://crosbug.com/6924
45972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (base_command_line.HasSwitch(switches::kRegisterPepperPlugins)) {
46072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    cmd_line_str += base::StringPrintf(
46172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        kSwitchFormatString,
46272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        switches::kRegisterPepperPlugins,
46372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        base_command_line.GetSwitchValueNative(
46472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            switches::kRegisterPepperPlugins).c_str());
46572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
46672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
46772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return cmd_line_str;
46872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
46972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
47021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginUtilsImpl::SetFirstLoginPrefs(PrefService* prefs) {
47121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  VLOG(1) << "Setting first login prefs";
47221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  BootTimesLoader* btl = BootTimesLoader::Get();
473dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string locale = g_browser_process->GetApplicationLocale();
474dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
475dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // First, we'll set kLanguagePreloadEngines.
476dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  InputMethodLibrary* library = CrosLibrary::Get()->GetInputMethodLibrary();
477dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::vector<std::string> input_method_ids;
478dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  input_method::GetFirstLoginInputMethodIds(locale,
479dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                            library->current_input_method(),
480dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                            &input_method_ids);
481dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Save the input methods in the user's preferences.
482dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  StringPrefMember language_preload_engines;
483dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  language_preload_engines.Init(prefs::kLanguagePreloadEngines,
484dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                prefs, NULL);
485dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  language_preload_engines.SetValue(JoinString(input_method_ids, ','));
486dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  btl->AddLoginTimeMarker("IMEStarted", false);
487dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
488dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Second, we'll set kLanguagePreferredLanguages.
489dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::vector<std::string> language_codes;
490dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // The current locale should be on the top.
491dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  language_codes.push_back(locale);
492dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
493dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Add input method IDs based on the input methods, as there may be
494dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // input methods that are unrelated to the current locale. Example: the
495dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // hardware keyboard layout xkb:us::eng is used for logging in, but the
496dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // UI language is set to French. In this case, we should set "fr,en"
497dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // to the preferred languages preference.
498dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::vector<std::string> candidates;
499dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  input_method::GetLanguageCodesFromInputMethodIds(
500dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      input_method_ids, &candidates);
501dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (size_t i = 0; i < candidates.size(); ++i) {
502dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const std::string& candidate = candidates[i];
503dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Skip if it's already in language_codes.
504dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (std::count(language_codes.begin(), language_codes.end(),
505dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                   candidate) == 0) {
506dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      language_codes.push_back(candidate);
50721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
50821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
509dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Save the preferred languages in the user's preferences.
510dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  StringPrefMember language_preferred_languages;
511dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  language_preferred_languages.Init(prefs::kLanguagePreferredLanguages,
512dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                    prefs, NULL);
513dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  language_preferred_languages.SetValue(JoinString(language_codes, ','));
514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  prefs->ScheduleSavePersistentPrefs();
51521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
51621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAuthenticator* LoginUtilsImpl::CreateAuthenticator(
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    LoginStatusConsumer* consumer) {
519731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kParallelAuth))
520731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return new ParallelAuthenticator(consumer);
521731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  else
522731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return new GoogleAuthenticator(consumer);
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
525513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// We use a special class for this so that it can be safely leaked if we
526513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// never connect. At shutdown the order is not well defined, and it's possible
527513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// for the infrastructure needed to unregister might be unstable and crash.
528513209b27ff55e2841eac0e4120199c23acce758Ben Murdochclass WarmingObserver : public NetworkLibrary::NetworkManagerObserver {
529513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch public:
530513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  WarmingObserver() {
531513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    NetworkLibrary *netlib = CrosLibrary::Get()->GetNetworkLibrary();
532513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    netlib->AddNetworkManagerObserver(this);
533513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
534513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
535513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // If we're now connected, prewarm the auth url.
536513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void OnNetworkManagerChanged(NetworkLibrary* netlib) {
537513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    if (netlib->Connected()) {
538201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      const int kConnectionsNeeded = 1;
539dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      chrome_browser_net::PreconnectOnUIThread(
5404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          GURL(GaiaAuthFetcher::kClientLoginUrl),
541201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          chrome_browser_net::UrlInfo::EARLY_LOAD_MOTIVATED,
542201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          kConnectionsNeeded);
543513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      netlib->RemoveNetworkManagerObserver(this);
544513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      delete this;
545513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    }
546513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
547513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch};
548513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
549513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid LoginUtilsImpl::PrewarmAuthentication() {
550513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (CrosLibrary::Get()->EnsureLoaded()) {
551513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    NetworkLibrary *network = CrosLibrary::Get()->GetNetworkLibrary();
552513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    if (network->Connected()) {
553201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      const int kConnectionsNeeded = 1;
554dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      chrome_browser_net::PreconnectOnUIThread(
5554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          GURL(GaiaAuthFetcher::kClientLoginUrl),
556201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          chrome_browser_net::UrlInfo::EARLY_LOAD_MOTIVATED,
557201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          kConnectionsNeeded);
558513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    } else {
559513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      new WarmingObserver();
560513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    }
561513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
562513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
563513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
56472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid LoginUtilsImpl::SetBackgroundView(BackgroundView* background_view) {
56572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  background_view_ = background_view;
56672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
56772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
56872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenBackgroundView* LoginUtilsImpl::GetBackgroundView() {
56972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return background_view_;
57072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
57172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLoginUtils* LoginUtils::Get() {
57321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return LoginUtilsWrapper::GetInstance()->get();
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid LoginUtils::Set(LoginUtils* mock) {
57721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  LoginUtilsWrapper::GetInstance()->reset(mock);
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid LoginUtils::DoBrowserLaunch(Profile* profile) {
581731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BootTimesLoader::Get()->AddLoginTimeMarker("BrowserLaunched", false);
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Update command line in case loose values were added.
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CommandLine::ForCurrentProcess()->InitFromArgv(
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      CommandLine::ForCurrentProcess()->argv());
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
587731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  VLOG(1) << "Launching browser...";
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BrowserInit browser_init;
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int return_code;
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser_init.LaunchBrowser(*CommandLine::ForCurrentProcess(),
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             profile,
5923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                             FilePath(),
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             true,
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             &return_code);
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace chromeos
598