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>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <set>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/base_paths.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind.h"
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/bind_helpers.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/callback.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h"
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/memory/weak_ptr.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_member.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
265e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h"
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/sys_info.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/task_runner_util.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/worker_pool.h"
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/about_flags.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/app_mode/app_mode_utils.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_shutdown.h"
377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/boot_times_loader.h"
3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/login/chrome_restart_request.h"
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/chromeos/login/existing_user_controller.h"
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/lock/screen_locker.h"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/login/profile_auth_data.h"
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.h"
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter_factory.h"
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/chromeos/login/session/user_session_manager.h"
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h"
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h"
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/chromeos/login/startup_utils.h"
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/ui/input_events_blocker.h"
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/ui/login_display_host.h"
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/chromeos/login/user_flow.h"
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/chromeos/profiles/profile_helper.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/first_run/first_run.h"
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/google/google_brand_chromeos.h"
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h"
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/pref_service_flags_storage.h"
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/rlz/rlz.h"
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h"
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h"
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h"
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/start_page_service.h"
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/startup/startup_browser_creator.h"
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/logging_chrome.h"
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/chromeos_switches.h"
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/cryptohome/cryptohome_util.h"
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/dbus/cryptohome_client.h"
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/dbus/dbus_method_call_status.h"
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/session_manager_client.h"
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/login/auth/user_context.h"
815b892326406927b709cdaf6c384d4ababf456332Ben Murdoch#include "chromeos/login/user_names.h"
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/settings/cros_settings_names.h"
83e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_manager.h"
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/user_manager/user.h"
856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h"
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_consumer.h"
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/network_change_notifier.h"
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(USE_ATHENA)
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "athena/extensions/public/extensions_delegate.h"
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "athena/main/public/athena_launcher.h"
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace {
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void LogCustomSwitches(const std::set<std::string>& switches) {
1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!VLOG_IS_ON(1))
1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return;
1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (std::set<std::string>::const_iterator it = switches.begin();
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       it != switches.end();
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       ++it) {
1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    VLOG(1) << "Switch leading to restart: '" << *it << "'";
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // anonymous namespace
1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace {
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Returns new CommandLine with per-user flags.
120116680a4aac90f2aa7413d9095a592090648e557Ben MurdochCommandLine CreatePerSessionCommandLine(Profile* profile) {
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CommandLine user_flags(CommandLine::NO_PROGRAM);
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  about_flags::PrefServiceFlagsStorage flags_storage_(profile->GetPrefs());
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  about_flags::ConvertFlagsToSwitches(
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      &flags_storage_, &user_flags, about_flags::kAddSentinels);
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return user_flags;
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Returns true if restart is needed to apply per-session flags.
1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool NeedRestartToApplyPerSessionFlags(
1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const CommandLine& user_flags,
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    std::set<CommandLine::StringType>* out_command_line_difference) {
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Don't restart browser if it is not first profile in session.
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (user_manager::UserManager::Get()->GetLoggedInUsers().size() != 1)
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Only restart if needed and if not going into managed mode.
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser())
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (about_flags::AreSwitchesIdenticalToCurrentCommandLine(
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          user_flags,
1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          *CommandLine::ForCurrentProcess(),
1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          out_command_line_difference)) {
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return true;
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool CanPerformEarlyRestart() {
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Desktop build is used for development only. Early restart is not supported.
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!base::SysInfo::IsRunningOnChromeOS())
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1551675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  if (!ChromeUserManager::Get()->GetCurrentUserFlow()->
1561675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch          SupportsEarlyRestartToApplyFlags()) {
1571675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    return false;
1581675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  }
1591675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const ExistingUserController* controller =
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ExistingUserController::current_controller();
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!controller)
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return true;
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Early restart is possible only if OAuth token is up to date.
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (controller->password_changed())
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (controller->auth_mode() != LoginPerformer::AUTH_MODE_INTERNAL)
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // No early restart if Easy unlock key needs to be updated.
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (UserSessionManager::GetInstance()->NeedsToUpdateEasyUnlockKeys())
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return true;
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass LoginUtilsImpl : public LoginUtils,
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       public base::SupportsWeakPtr<LoginUtilsImpl>,
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       public UserSessionManagerDelegate {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoginUtilsImpl()
187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      : delegate_(NULL) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~LoginUtilsImpl() {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // LoginUtils implementation:
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void RespectLocalePreference(Profile* profile,
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       const base::Closure& callback) OVERRIDE;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DoBrowserLaunch(Profile* profile,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               LoginDisplayHost* login_host) OVERRIDE;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void PrepareProfile(
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const UserContext& user_context,
200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      bool has_auth_cookies,
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      bool has_active_session,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoginUtils::Delegate* delegate) OVERRIDE;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DelegateDeleted(LoginUtils::Delegate* delegate) OVERRIDE;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CompleteOffTheRecordLogin(const GURL& start_url) OVERRIDE;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual scoped_refptr<Authenticator> CreateAuthenticator(
206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AuthStatusConsumer* consumer) OVERRIDE;
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual bool RestartToApplyPerSessionFlagsIfNeed(Profile* profile,
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                   bool early_restart) OVERRIDE;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // UserSessionManager::Delegate implementation:
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   virtual void OnProfilePrepared(Profile* profile) OVERRIDE;
212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) #if defined(ENABLE_RLZ)
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   virtual void OnRlzInitialized() OVERRIDE;
214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) #endif
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void DoBrowserLaunchInternal(Profile* profile,
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               LoginDisplayHost* login_host,
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               bool locale_pref_checked);
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void RunCallbackOnLocaleLoaded(
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const base::Closure& callback,
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      InputEventsBlocker* input_events_blocker,
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const std::string& locale,
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const std::string& loaded_locale,
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const bool success);
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Attempts restarting the browser process and esures that this does
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // not happen while we are still fetching new OAuth refresh tokens.
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AttemptRestart(Profile* profile);
23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Has to be scoped_refptr, see comment for CreateAuthenticator(...).
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Authenticator> authenticator_;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delegate to be fired when the profile will be prepared.
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoginUtils::Delegate* delegate_;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LoginUtilsImpl);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LoginUtilsWrapper {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static LoginUtilsWrapper* GetInstance() {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Singleton<LoginUtilsWrapper>::get();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoginUtils* get() {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock create(create_lock_);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ptr_.get())
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reset(new LoginUtilsImpl);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ptr_.get();
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void reset(LoginUtils* ptr) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr_.reset(ptr);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct DefaultSingletonTraits<LoginUtilsWrapper>;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoginUtilsWrapper() {}
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Lock create_lock_;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<LoginUtils> ptr_;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LoginUtilsWrapper);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LoginUtilsImpl::DoBrowserLaunchInternal(Profile* profile,
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             LoginDisplayHost* login_host,
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             bool locale_pref_checked) {
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (browser_shutdown::IsTryingToQuit())
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!locale_pref_checked) {
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RespectLocalePreference(profile,
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            base::Bind(&LoginUtilsImpl::DoBrowserLaunchInternal,
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       base::Unretained(this),
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       profile,
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       login_host,
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       true /* locale_pref_checked */));
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!ChromeUserManager::Get()->GetCurrentUserFlow()->ShouldLaunchBrowser()) {
2866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ChromeUserManager::Get()->GetCurrentUserFlow()->LaunchExtraSteps(profile);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (RestartToApplyPerSessionFlagsIfNeed(profile, false))
2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (login_host) {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    login_host->SetStatusAreaVisible(true);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    login_host->BeforeSessionStart();
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BootTimesLoader::Get()->AddLoginTimeMarker("BrowserLaunched", false);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "Launching browser...";
301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TRACE_EVENT0("login", "LaunchBrowser");
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(USE_ATHENA)
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  athena::ExtensionsDelegate::CreateExtensionsDelegateForChrome(profile);
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  athena::StartAthenaSessionWithContext(profile);
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#else
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartupBrowserCreator browser_creator;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int return_code;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ?
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN;
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser_creator.LaunchBrowser(*CommandLine::ForCurrentProcess(),
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                profile,
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                base::FilePath(),
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                chrome::startup::IS_PROCESS_STARTUP,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                first_run,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                &return_code);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Triggers app launcher start page service to load start page web contents.
3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  app_list::StartPageService::Get(profile);
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mark login host for deletion after browser starts.  This
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // guarantees that the message loop will be referenced by the
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // browser before it is dereferenced by the login host.
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (login_host)
327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    login_host->Finalize();
3286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  user_manager::UserManager::Get()->SessionStarted();
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chromeos::BootTimesLoader::Get()->LoginDone(
3306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_manager::UserManager::Get()->IsCurrentUserNew());
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LoginUtilsImpl::RunCallbackOnLocaleLoaded(
3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::Closure& callback,
3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    InputEventsBlocker* /* input_events_blocker */,
3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& /* locale */,
3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& /* loaded_locale */,
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const bool /* success */) {
3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  callback.Run();
3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LoginUtilsImpl::RespectLocalePreference(Profile* profile,
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             const base::Closure& callback) {
345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (browser_shutdown::IsTryingToQuit())
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  user_manager::User* const user =
3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ProfileHelper::Get()->GetUserByProfile(profile);
3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<locale_util::SwitchLanguageCallback> locale_switched_callback(
3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new locale_util::SwitchLanguageCallback(base::Bind(
3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              &LoginUtilsImpl::RunCallbackOnLocaleLoaded,
3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              callback,
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              base::Owned(new InputEventsBlocker))));  // Block UI events until
3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                       // the ResourceBundle is
3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                       // reloaded.
3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!UserSessionManager::GetInstance()->RespectLocalePreference(
3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          profile,
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          user,
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          locale_switched_callback.Pass())) {
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    callback.Run();
362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LoginUtilsImpl::DoBrowserLaunch(Profile* profile,
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     LoginDisplayHost* login_host) {
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DoBrowserLaunchInternal(profile, login_host, false /* locale_pref_checked */);
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginUtilsImpl::PrepareProfile(
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const UserContext& user_context,
372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool has_auth_cookies,
37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    bool has_active_session,
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoginUtils::Delegate* delegate) {
375f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // TODO(nkostylev): We have to initialize LoginUtils delegate as long
376f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // as it coexist with SessionManager.
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = delegate;
378f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
379f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // For the transition part LoginUtils will just delegate profile
380f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // creation and initialization to SessionManager. Later LoginUtils will be
381f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // removed and all LoginUtils clients will just work with SessionManager
382f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // directly.
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  UserSessionManager::GetInstance()->StartSession(
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      user_context, authenticator_, has_auth_cookies, has_active_session, this);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginUtilsImpl::DelegateDeleted(LoginUtils::Delegate* delegate) {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_ == delegate)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_ = NULL;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool LoginUtilsImpl::RestartToApplyPerSessionFlagsIfNeed(Profile* profile,
393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         bool early_restart) {
394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (ProfileHelper::IsSigninProfile(profile))
395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (early_restart && !CanPerformEarlyRestart())
398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const CommandLine user_flags(CreatePerSessionCommandLine(profile));
4016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::set<CommandLine::StringType> command_line_difference;
4026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!NeedRestartToApplyPerSessionFlags(user_flags, &command_line_difference))
403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  LogCustomSwitches(command_line_difference);
4066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  about_flags::ReportCustomFlags("Login.CustomFlags", command_line_difference);
4086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CommandLine::StringVector flags;
410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // argv[0] is the program name |CommandLine::NO_PROGRAM|.
411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  flags.assign(user_flags.argv().begin() + 1, user_flags.argv().end());
4121675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  LOG(WARNING) << "Restarting to apply per-session flags...";
413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DBusThreadManager::Get()->GetSessionManagerClient()->SetFlagsForUser(
4146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_manager::UserManager::Get()->GetActiveUser()->email(), flags);
415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AttemptRestart(profile);
416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return true;
417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginUtilsImpl::CompleteOffTheRecordLogin(const GURL& start_url) {
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "Completing incognito login";
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For guest session we ask session manager to restart Chrome with --bwsi
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // flag. We keep only some of the arguments of this process.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine command_line(browser_command_line.GetProgram());
426effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::string cmd_line_str =
427effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      GetOffTheRecordCommandLine(start_url,
428effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                 StartupUtils::IsOobeCompleted(),
429effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                 browser_command_line,
430effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                 &command_line);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  // This makes sure that Chrome restarts with no per-session flags. The guest
4335b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  // profile will always have empty set of per-session flags. If this is not
4345b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  // done and device owner has some per-session flags, when Chrome is relaunched
4355b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  // the guest profile session flags will not match the current command line and
4365b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  // another restart will be attempted in order to reset the user flags for the
4375b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  // guest user.
4385b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  const CommandLine user_flags(CommandLine::NO_PROGRAM);
4395b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  if (!about_flags::AreSwitchesIdenticalToCurrentCommandLine(
4405b892326406927b709cdaf6c384d4ababf456332Ben Murdoch           user_flags,
4415b892326406927b709cdaf6c384d4ababf456332Ben Murdoch           *CommandLine::ForCurrentProcess(),
4425b892326406927b709cdaf6c384d4ababf456332Ben Murdoch           NULL)) {
4435b892326406927b709cdaf6c384d4ababf456332Ben Murdoch    DBusThreadManager::Get()->GetSessionManagerClient()->SetFlagsForUser(
4445b892326406927b709cdaf6c384d4ababf456332Ben Murdoch        chromeos::login::kGuestUserName,
4455b892326406927b709cdaf6c384d4ababf456332Ben Murdoch        CommandLine::StringVector());
4465b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  }
4475b892326406927b709cdaf6c384d4ababf456332Ben Murdoch
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RestartChrome(cmd_line_str);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Authenticator> LoginUtilsImpl::CreateAuthenticator(
452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AuthStatusConsumer* consumer) {
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Screen locker needs new Authenticator instance each time.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ScreenLocker::default_screen_locker()) {
4557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (authenticator_.get())
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      authenticator_->SetConsumer(NULL);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    authenticator_ = NULL;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (authenticator_.get() == NULL) {
46103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    authenticator_ = new ChromeCryptohomeAuthenticator(consumer);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(nkostylev): Fix this hack by improving Authenticator dependencies.
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    authenticator_->SetConsumer(consumer);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return authenticator_;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
469f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void LoginUtilsImpl::OnProfilePrepared(Profile* profile) {
470f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (delegate_)
471f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    delegate_->OnProfilePrepared(profile);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
474f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(ENABLE_RLZ)
475f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void LoginUtilsImpl::OnRlzInitialized() {
476f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (delegate_)
477f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    delegate_->OnRlzInitialized();
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
479f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void LoginUtilsImpl::AttemptRestart(Profile* profile) {
4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (UserSessionManager::GetInstance()
4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          ->CheckEasyUnlockKeyOps(
4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              base::Bind(&LoginUtilsImpl::AttemptRestart,
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         base::Unretained(this),
4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         profile))) {
4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
490116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (UserSessionManager::GetInstance()->GetSigninSessionRestoreStrategy() !=
49168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR) {
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    chrome::AttemptRestart();
49368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
49468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
49568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
49668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // We can't really quit if the session restore process that mints new
49768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // refresh token is still in progress.
49868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  OAuth2LoginManager* login_manager =
49968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile);
50068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (login_manager->state() !=
50168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          OAuth2LoginManager::SESSION_RESTORE_PREPARING &&
50268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      login_manager->state() !=
50368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) {
5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    chrome::AttemptRestart();
50568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
50668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
50768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
50868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  LOG(WARNING) << "Attempting browser restart during session restore.";
509116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  UserSessionManager::GetInstance()->set_exit_after_session_restore(true);
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoginUtils* LoginUtils::Get() {
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return LoginUtilsWrapper::GetInstance()->get();
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginUtils::Set(LoginUtils* mock) {
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoginUtilsWrapper::GetInstance()->reset(mock);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool LoginUtils::IsWhitelisted(const std::string& username,
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               bool* wildcard_match) {
525a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Skip whitelist check for tests.
526a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
527a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      chromeos::switches::kOobeSkipPostLogin)) {
528a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return true;
529a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CrosSettings* cros_settings = CrosSettings::Get();
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool allow_new_user = false;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (allow_new_user)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return cros_settings->FindEmailInList(
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      kAccountsPrefUsers, username, wildcard_match);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
541