chrome_browser_main_chromeos.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/chromeos/chrome_browser_main_chromeos.h"
6
7#include <string>
8#include <vector>
9
10#include "ash/ash_switches.h"
11#include "ash/shell.h"
12#include "base/bind.h"
13#include "base/callback.h"
14#include "base/command_line.h"
15#include "base/file_util.h"
16#include "base/lazy_instance.h"
17#include "base/linux_util.h"
18#include "base/message_loop/message_loop.h"
19#include "base/path_service.h"
20#include "base/prefs/pref_service.h"
21#include "base/strings/string_number_conversions.h"
22#include "base/strings/string_split.h"
23#include "base/sys_info.h"
24#include "chrome/browser/browser_process.h"
25#include "chrome/browser/browser_process_platform_part_chromeos.h"
26#include "chrome/browser/chrome_notification_types.h"
27#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
28#include "chrome/browser/chromeos/accessibility/magnification_manager.h"
29#include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h"
30#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
31#include "chrome/browser/chromeos/boot_times_loader.h"
32#include "chrome/browser/chromeos/contacts/contact_manager.h"
33#include "chrome/browser/chromeos/dbus/cros_dbus_service.h"
34#include "chrome/browser/chromeos/display/display_configuration_observer.h"
35#include "chrome/browser/chromeos/extensions/default_app_order.h"
36#include "chrome/browser/chromeos/extensions/extension_system_event_observer.h"
37#include "chrome/browser/chromeos/external_metrics.h"
38#include "chrome/browser/chromeos/imageburner/burn_manager.h"
39#include "chrome/browser/chromeos/input_method/input_method_configuration.h"
40#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout.h"
41#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h"
42#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
43#include "chrome/browser/chromeos/login/authenticator.h"
44#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h"
45#include "chrome/browser/chromeos/login/login_utils.h"
46#include "chrome/browser/chromeos/login/login_wizard.h"
47#include "chrome/browser/chromeos/login/screen_locker.h"
48#include "chrome/browser/chromeos/login/startup_utils.h"
49#include "chrome/browser/chromeos/login/user_manager.h"
50#include "chrome/browser/chromeos/login/wallpaper_manager.h"
51#include "chrome/browser/chromeos/login/wizard_controller.h"
52#include "chrome/browser/chromeos/memory/oom_priority_manager.h"
53#include "chrome/browser/chromeos/net/network_portal_detector.h"
54#include "chrome/browser/chromeos/options/cert_library.h"
55#include "chrome/browser/chromeos/power/idle_action_warning_observer.h"
56#include "chrome/browser/chromeos/power/peripheral_battery_observer.h"
57#include "chrome/browser/chromeos/power/power_button_observer.h"
58#include "chrome/browser/chromeos/power/power_prefs.h"
59#include "chrome/browser/chromeos/profiles/profile_helper.h"
60#include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h"
61#include "chrome/browser/chromeos/settings/device_settings_service.h"
62#include "chrome/browser/chromeos/settings/owner_key_util.h"
63#include "chrome/browser/chromeos/status/data_promo_notification.h"
64#include "chrome/browser/chromeos/system_key_event_listener.h"
65#include "chrome/browser/chromeos/upgrade_detector_chromeos.h"
66#include "chrome/browser/chromeos/xinput_hierarchy_changed_event_listener.h"
67#include "chrome/browser/defaults.h"
68#include "chrome/browser/metrics/metrics_service.h"
69#include "chrome/browser/net/chrome_network_delegate.h"
70#include "chrome/browser/policy/browser_policy_connector.h"
71#include "chrome/browser/profiles/profile.h"
72#include "chrome/browser/profiles/profile_manager.h"
73#include "chrome/browser/rlz/rlz.h"
74#include "chrome/common/chrome_constants.h"
75#include "chrome/common/chrome_paths.h"
76#include "chrome/common/chrome_switches.h"
77#include "chrome/common/chrome_version_info.h"
78#include "chrome/common/logging_chrome.h"
79#include "chrome/common/pref_names.h"
80#include "chromeos/audio/audio_devices_pref_handler.h"
81#include "chromeos/audio/cras_audio_handler.h"
82#include "chromeos/chromeos_paths.h"
83#include "chromeos/chromeos_switches.h"
84#include "chromeos/cryptohome/async_method_caller.h"
85#include "chromeos/cryptohome/system_salt_getter.h"
86#include "chromeos/dbus/dbus_thread_manager.h"
87#include "chromeos/dbus/power_policy_controller.h"
88#include "chromeos/dbus/session_manager_client.h"
89#include "chromeos/disks/disk_mount_manager.h"
90#include "chromeos/ime/input_method_manager.h"
91#include "chromeos/ime/xkeyboard.h"
92#include "chromeos/login/login_state.h"
93#include "chromeos/network/network_change_notifier_chromeos.h"
94#include "chromeos/network/network_change_notifier_factory_chromeos.h"
95#include "chromeos/network/network_handler.h"
96#include "chromeos/system/statistics_provider.h"
97#include "content/public/browser/browser_thread.h"
98#include "content/public/browser/notification_service.h"
99#include "content/public/browser/power_save_blocker.h"
100#include "content/public/common/main_function_params.h"
101#include "grit/platform_locale_settings.h"
102#include "net/base/network_change_notifier.h"
103#include "net/url_request/url_request.h"
104#include "net/url_request/url_request_context_getter.h"
105#include "ui/base/touch/touch_device.h"
106#include "ui/events/event_utils.h"
107
108// Exclude X11 dependents for ozone
109#if defined(USE_X11)
110#include "chrome/browser/chromeos/device_uma.h"
111#endif
112
113namespace chromeos {
114
115namespace {
116
117void ChromeOSVersionCallback(const std::string& version) {
118  base::SetLinuxDistro(std::string("CrOS ") + version);
119}
120
121class MessageLoopObserver : public base::MessageLoopForUI::Observer {
122  virtual base::EventStatus WillProcessEvent(
123      const base::NativeEvent& event) OVERRIDE {
124    return base::EVENT_CONTINUE;
125  }
126
127  virtual void DidProcessEvent(
128      const base::NativeEvent& event) OVERRIDE {
129  }
130};
131
132static base::LazyInstance<MessageLoopObserver> g_message_loop_observer =
133    LAZY_INSTANCE_INITIALIZER;
134
135// Login -----------------------------------------------------------------------
136
137// Class is used to login using passed username and password.
138// The instance will be deleted upon success or failure.
139class StubLogin : public LoginStatusConsumer,
140                  public LoginUtils::Delegate {
141 public:
142  StubLogin(std::string username, std::string password)
143      : profile_prepared_(false) {
144    authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
145    authenticator_.get()->AuthenticateToLogin(
146        g_browser_process->profile_manager()->GetDefaultProfile(),
147        UserContext(username,
148                    password,
149                    std::string()));  // auth_code
150  }
151
152  virtual ~StubLogin() {
153    LoginUtils::Get()->DelegateDeleted(this);
154  }
155
156  virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE {
157    LOG(ERROR) << "Login Failure: " << error.GetErrorString();
158    delete this;
159  }
160
161  virtual void OnLoginSuccess(const UserContext& user_context) OVERRIDE {
162    if (!profile_prepared_) {
163      // Will call OnProfilePrepared in the end.
164      LoginUtils::Get()->PrepareProfile(user_context,
165                                        std::string(),  // display_email
166                                        false,          // has_cookies
167                                        true,           // has_active_session
168                                        this);
169    } else {
170      delete this;
171    }
172  }
173
174  // LoginUtils::Delegate implementation:
175  virtual void OnProfilePrepared(Profile* profile) OVERRIDE {
176    profile_prepared_ = true;
177    LoginUtils::Get()->DoBrowserLaunch(profile, NULL);
178    delete this;
179  }
180
181  scoped_refptr<Authenticator> authenticator_;
182  bool profile_prepared_;
183};
184
185bool ShouldAutoLaunchKioskApp(const CommandLine& command_line) {
186  KioskAppManager* app_manager = KioskAppManager::Get();
187  return command_line.HasSwitch(switches::kLoginManager) &&
188      !command_line.HasSwitch(switches::kForceLoginManagerInTests) &&
189      app_manager->IsAutoLaunchEnabled() &&
190      KioskAppLaunchError::Get() == KioskAppLaunchError::NONE;
191}
192
193void RunAutoLaunchKioskApp() {
194  ShowLoginWizard(chromeos::WizardController::kAppLaunchSplashScreenName);
195
196  // Login screen is skipped but 'login-prompt-visible' signal is still needed.
197  LOG(INFO) << "Kiosk app auto launch >> login-prompt-visible";
198  DBusThreadManager::Get()->GetSessionManagerClient()->
199      EmitLoginPromptVisible();
200}
201
202void OptionallyRunChromeOSLoginManager(const CommandLine& parsed_command_line,
203                                       Profile* profile) {
204  if (ShouldAutoLaunchKioskApp(parsed_command_line)) {
205    RunAutoLaunchKioskApp();
206  } else if (parsed_command_line.HasSwitch(switches::kLoginManager)) {
207    const std::string first_screen =
208        parsed_command_line.HasSwitch(switches::kLoginScreen) ?
209            WizardController::kLoginScreenName : std::string();
210    ShowLoginWizard(first_screen);
211
212    if (KioskModeSettings::Get()->IsKioskModeEnabled())
213      InitializeKioskModeScreensaver();
214
215    // Reset reboot after update flag when login screen is shown.
216    if (!g_browser_process->browser_policy_connector()->
217        IsEnterpriseManaged()) {
218      PrefService* local_state = g_browser_process->local_state();
219      local_state->ClearPref(prefs::kRebootAfterUpdate);
220    }
221  } else if (parsed_command_line.HasSwitch(switches::kLoginUser) &&
222             parsed_command_line.HasSwitch(switches::kLoginPassword)) {
223    BootTimesLoader::Get()->RecordLoginAttempted();
224    new StubLogin(
225        parsed_command_line.GetSwitchValueASCII(switches::kLoginUser),
226        parsed_command_line.GetSwitchValueASCII(switches::kLoginPassword));
227  } else {
228    if (!parsed_command_line.HasSwitch(::switches::kTestName)) {
229      // Enable CrasAudioHandler logging when chrome restarts after crashing.
230      if (chromeos::CrasAudioHandler::IsInitialized())
231        chromeos::CrasAudioHandler::Get()->LogErrors();
232
233      // We did not log in (we crashed or are debugging), so we need to
234      // restore Sync.
235      LoginUtils::Get()->RestoreAuthenticationSession(profile);
236    }
237  }
238}
239
240}  // namespace
241
242namespace internal {
243
244// Wrapper class for initializing dbus related services and shutting them
245// down. This gets instantiated in a scoped_ptr so that shutdown methods in the
246// destructor will get called if and only if this has been instantiated.
247class DBusServices {
248 public:
249  explicit DBusServices(const content::MainFunctionParams& parameters) {
250    if (!base::SysInfo::IsRunningOnChromeOS()) {
251      // Override this path on the desktop, so that the user policy key can be
252      // stored by the stub SessionManagerClient.
253      base::FilePath user_data_dir;
254      if (PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
255        PathService::Override(chromeos::DIR_USER_POLICY_KEYS,
256                              user_data_dir.AppendASCII("stub_user_policy"));
257      }
258    }
259
260    // Initialize DBusThreadManager for the browser. This must be done after
261    // the main message loop is started, as it uses the message loop.
262    DBusThreadManager::Initialize();
263    CrosDBusService::Initialize();
264
265    LoginState::Initialize();
266    SystemSaltGetter::Initialize();
267    CertLoader::Initialize();
268
269    // This function and SystemKeyEventListener use InputMethodManager.
270    chromeos::input_method::Initialize(
271        content::BrowserThread::GetMessageLoopProxyForThread(
272            content::BrowserThread::UI),
273        content::BrowserThread::GetMessageLoopProxyForThread(
274            content::BrowserThread::FILE));
275    disks::DiskMountManager::Initialize();
276    cryptohome::AsyncMethodCaller::Initialize();
277
278    NetworkHandler::Initialize();
279    CertLibrary::Initialize();
280
281    // Initialize the network change notifier for Chrome OS. The network
282    // change notifier starts to monitor changes from the power manager and
283    // the network manager.
284    NetworkChangeNotifierFactoryChromeos::GetInstance()->Initialize();
285
286    // Likewise, initialize the upgrade detector for Chrome OS. The upgrade
287    // detector starts to monitor changes from the update engine.
288    UpgradeDetectorChromeos::GetInstance()->Init();
289
290    if (base::SysInfo::IsRunningOnChromeOS()) {
291      // Disable Num Lock on X start up for http://crosbug.com/29169.
292      input_method::InputMethodManager::Get()->GetXKeyboard()->
293          SetNumLockEnabled(false);
294    }
295
296    // Initialize the device settings service so that we'll take actions per
297    // signals sent from the session manager. This needs to happen before
298    // g_browser_process initializes BrowserPolicyConnector.
299    DeviceSettingsService::Initialize();
300    DeviceSettingsService::Get()->SetSessionManager(
301        DBusThreadManager::Get()->GetSessionManagerClient(),
302        OwnerKeyUtil::Create());
303  }
304
305  ~DBusServices() {
306    CertLibrary::Shutdown();
307    NetworkHandler::Shutdown();
308
309    cryptohome::AsyncMethodCaller::Shutdown();
310    disks::DiskMountManager::Shutdown();
311    input_method::Shutdown();
312
313    SystemSaltGetter::Shutdown();
314    LoginState::Shutdown();
315
316    CrosDBusService::Shutdown();
317
318    // NOTE: This must only be called if Initialize() was called.
319    DBusThreadManager::Shutdown();
320  }
321
322 private:
323
324  DISALLOW_COPY_AND_ASSIGN(DBusServices);
325};
326
327}  //  namespace internal
328
329// ChromeBrowserMainPartsChromeos ----------------------------------------------
330
331ChromeBrowserMainPartsChromeos::ChromeBrowserMainPartsChromeos(
332    const content::MainFunctionParams& parameters)
333    : ChromeBrowserMainPartsLinux(parameters) {
334}
335
336ChromeBrowserMainPartsChromeos::~ChromeBrowserMainPartsChromeos() {
337  if (KioskModeSettings::Get()->IsKioskModeEnabled())
338    ShutdownKioskModeScreensaver();
339
340  // To be precise, logout (browser shutdown) is not yet done, but the
341  // remaining work is negligible, hence we say LogoutDone here.
342  BootTimesLoader::Get()->AddLogoutTimeMarker("LogoutDone", false);
343  BootTimesLoader::Get()->WriteLogoutTimes();
344}
345
346// content::BrowserMainParts and ChromeBrowserMainExtraParts overrides ---------
347
348void ChromeBrowserMainPartsChromeos::PreEarlyInitialization() {
349  CommandLine* singleton_command_line = CommandLine::ForCurrentProcess();
350
351  if (parsed_command_line().HasSwitch(switches::kGuestSession)) {
352    // Disable sync and extensions if we're in "browse without sign-in" mode.
353    singleton_command_line->AppendSwitch(::switches::kDisableSync);
354    singleton_command_line->AppendSwitch(::switches::kDisableExtensions);
355    browser_defaults::bookmarks_enabled = false;
356  }
357
358  // If we're not running on real ChromeOS hardware (or under VM), and are not
359  // showing the login manager or attempting a command line login, login with a
360  // stub user.
361  if (!base::SysInfo::IsRunningOnChromeOS() &&
362      !parsed_command_line().HasSwitch(switches::kLoginManager) &&
363      !parsed_command_line().HasSwitch(switches::kLoginUser) &&
364      !parsed_command_line().HasSwitch(switches::kGuestSession)) {
365    singleton_command_line->AppendSwitchASCII(
366        switches::kLoginUser, UserManager::kStubUser);
367    if (!parsed_command_line().HasSwitch(switches::kLoginProfile)) {
368      singleton_command_line->AppendSwitchASCII(switches::kLoginProfile,
369                                                chrome::kTestUserProfileDir);
370    }
371    LOG(INFO) << "Running as stub user with profile dir: "
372              << singleton_command_line->GetSwitchValuePath(
373                  switches::kLoginProfile).value();
374  }
375
376#if defined(GOOGLE_CHROME_BUILD)
377  const char kChromeOSReleaseTrack[] = "CHROMEOS_RELEASE_TRACK";
378  std::string channel;
379  if (base::SysInfo::GetLsbReleaseValue(kChromeOSReleaseTrack, &channel))
380    chrome::VersionInfo::SetChannel(channel);
381#endif
382
383  ChromeBrowserMainPartsLinux::PreEarlyInitialization();
384}
385
386void ChromeBrowserMainPartsChromeos::PreMainMessageLoopStart() {
387  // Replace the default NetworkChangeNotifierFactory with ChromeOS specific
388  // implementation. This must be done before BrowserMainLoop calls
389  // net::NetworkChangeNotifier::Create() in MainMessageLoopStart().
390  net::NetworkChangeNotifier::SetFactory(
391      new NetworkChangeNotifierFactoryChromeos());
392  ChromeBrowserMainPartsLinux::PreMainMessageLoopStart();
393}
394
395void ChromeBrowserMainPartsChromeos::PostMainMessageLoopStart() {
396  base::MessageLoopForUI* message_loop = base::MessageLoopForUI::current();
397  message_loop->AddObserver(g_message_loop_observer.Pointer());
398
399  dbus_services_.reset(new internal::DBusServices(parameters()));
400
401  ChromeBrowserMainPartsLinux::PostMainMessageLoopStart();
402}
403
404// Threads are initialized between MainMessageLoopStart and MainMessageLoopRun.
405// about_flags settings are applied in ChromeBrowserMainParts::PreCreateThreads.
406void ChromeBrowserMainPartsChromeos::PreMainMessageLoopRun() {
407  // Set the crypto thread after the IO thread has been created/started.
408  CertLoader::Get()->SetCryptoTaskRunner(
409      content::BrowserThread::GetMessageLoopProxyForThread(
410          content::BrowserThread::IO));
411
412  CrasAudioHandler::Initialize(
413      AudioDevicesPrefHandler::Create(g_browser_process->local_state()));
414
415  // Start loading machine statistics here. StatisticsProvider::Shutdown()
416  // will ensure that loading is aborted on early exit.
417  bool load_oem_statistics = !StartupUtils::IsOobeCompleted();
418  system::StatisticsProvider::GetInstance()->StartLoadingMachineStatistics(
419      content::BrowserThread::GetMessageLoopProxyForThread(
420          content::BrowserThread::FILE),
421      load_oem_statistics);
422
423  base::FilePath downloads_directory;
424  CHECK(PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &downloads_directory));
425  imageburner::BurnManager::Initialize(
426      downloads_directory, g_browser_process->system_request_context());
427
428  // Listen for system key events so that the user will be able to adjust the
429  // volume on the login screen, if Chrome is running on Chrome OS
430  // (i.e. not Linux desktop), and in non-test mode.
431  // Note: SystemKeyEventListener depends on the DBus thread.
432  if (base::SysInfo::IsRunningOnChromeOS() &&
433      !parameters().ui_task) {  // ui_task is non-NULL when running tests.
434    SystemKeyEventListener::Initialize();
435  }
436
437  DeviceOAuth2TokenServiceFactory::Initialize();
438
439  ChromeBrowserMainPartsLinux::PreMainMessageLoopRun();
440}
441
442void ChromeBrowserMainPartsChromeos::PreProfileInit() {
443  // -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
444  // -- immediately before Profile creation().
445
446  // Now that the file thread exists we can record our stats.
447  BootTimesLoader::Get()->RecordChromeMainStats();
448
449  // Trigger prefetching of ownership status.
450  DeviceSettingsService::Get()->Load();
451
452  // -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
453  // -- just before CreateProfile().
454
455  UserManager::Initialize();
456
457  // Initialize the screen locker now so that it can receive
458  // LOGIN_USER_CHANGED notification from UserManager.
459  if (KioskModeSettings::Get()->IsKioskModeEnabled()) {
460    KioskModeIdleLogout::Initialize();
461  } else {
462    ScreenLocker::InitClass();
463  }
464
465  // This forces the ProfileManager to be created and register for the
466  // notification it needs to track the logged in user.
467  g_browser_process->profile_manager();
468
469  // ProfileHelper has to be initialized after UserManager instance is created.
470  g_browser_process->platform_part()->profile_helper()->Initialize();
471
472  // TODO(abarth): Should this move to InitializeNetworkOptions()?
473  // Allow access to file:// on ChromeOS for tests.
474  if (parsed_command_line().HasSwitch(::switches::kAllowFileAccess))
475    ChromeNetworkDelegate::AllowAccessToAllFiles();
476
477  if (parsed_command_line().HasSwitch(::switches::kEnableContacts)) {
478    contact_manager_.reset(new contacts::ContactManager());
479    contact_manager_->Init();
480  }
481
482  // There are two use cases for kLoginUser:
483  //   1) if passed in tandem with kLoginPassword, to drive a "StubLogin"
484  //   2) if passed alone, to signal that the indicated user has already
485  //      logged in and we should behave accordingly.
486  // This handles case 2.
487  bool immediate_login =
488      parsed_command_line().HasSwitch(switches::kLoginUser) &&
489      !parsed_command_line().HasSwitch(switches::kLoginPassword);
490  if (immediate_login){
491    // Redirects Chrome logging to the user data dir.
492    logging::RedirectChromeLogging(parsed_command_line());
493
494    // Load the default app order synchronously for restarting case.
495    app_order_loader_.reset(
496        new default_app_order::ExternalLoader(false /* async */));
497  }
498
499  if (!app_order_loader_) {
500    app_order_loader_.reset(
501        new default_app_order::ExternalLoader(true /* async */));
502  }
503
504  // Initialize magnification manager before ash tray is created. And this must
505  // be placed after UserManager::SessionStarted();
506  AccessibilityManager::Initialize();
507  MagnificationManager::Initialize();
508
509  // Add observers for WallpaperManager. This depends on PowerManagerClient,
510  // TimezoneSettings and CrosSettings.
511  WallpaperManager::Get()->AddObservers();
512
513  cros_version_loader_.GetVersion(VersionLoader::VERSION_FULL,
514                                  base::Bind(&ChromeOSVersionCallback),
515                                  &tracker_);
516
517  // Make sure that wallpaper boot transition and other delays in OOBE
518  // are disabled for tests and kiosk app launch by default.
519  // Individual tests may enable them if they want.
520  if (parsed_command_line().HasSwitch(::switches::kTestType) ||
521      ShouldAutoLaunchKioskApp(parsed_command_line())) {
522    WizardController::SetZeroDelays();
523  }
524
525  power_prefs_.reset(new PowerPrefs(
526      DBusThreadManager::Get()->GetPowerPolicyController()));
527
528  // In Aura builds this will initialize ash::Shell.
529  ChromeBrowserMainPartsLinux::PreProfileInit();
530
531  if (immediate_login) {
532    std::string username =
533        parsed_command_line().GetSwitchValueASCII(switches::kLoginUser);
534    UserManager* user_manager = UserManager::Get();
535    // In case of multi-profiles --login-profile will contain user_id_hash.
536    std::string username_hash =
537        parsed_command_line().GetSwitchValueASCII(switches::kLoginProfile);
538    user_manager->UserLoggedIn(username, username_hash, true);
539    VLOG(1) << "Relaunching browser for user: " << username
540            << " with hash: " << username_hash;
541  }
542}
543
544void ChromeBrowserMainPartsChromeos::PostProfileInit() {
545  // -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
546  // -- just after CreateProfile().
547
548  // Restarting Chrome inside existing user session. Possible cases:
549  // 1. Chrome is restarted after crash.
550  // 2. Chrome is started in browser_tests skipping the login flow
551  // 3. Chrome is started on dev machine
552  //    i.e. not on Chrome OS device w/o login flow.
553  if (parsed_command_line().HasSwitch(switches::kLoginUser) &&
554      !parsed_command_line().HasSwitch(switches::kLoginPassword)) {
555    // This is done in LoginUtils::OnProfileCreated during normal login.
556    LoginUtils::Get()->InitRlzDelayed(profile());
557
558    // Send the PROFILE_PREPARED notification and call SessionStarted()
559    // so that the Launcher and other Profile dependent classes are created.
560    content::NotificationService::current()->Notify(
561        chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
562        content::NotificationService::AllSources(),
563        content::Details<Profile>(profile()));
564    UserManager::Get()->SessionStarted();
565
566    // Now is the good time to retrieve other logged in users for this session.
567    // First user has been already marked as logged in and active in
568    // PreProfileInit(). Chrome should tread other user in a session as active
569    // in the background.
570    UserManager::Get()->RestoreActiveSessions();
571  }
572
573  // Initialize the network portal detector for Chrome OS. The network
574  // portal detector starts to listen for notifications from
575  // NetworkStateHandler and initiates captive portal detection for
576  // active networks. Shoule be called before call to
577  // OptionallyRunChromeOSLoginManager, because it depends on
578  // NetworkPortalDetector.
579  NetworkPortalDetector::Initialize();
580  {
581    NetworkPortalDetector* detector = NetworkPortalDetector::Get();
582#if defined(GOOGLE_CHROME_BUILD)
583    bool is_official_build = true;
584#else
585    bool is_official_build = false;
586#endif
587    // Enable portal detector if EULA was previously accepted or if
588    // this is an unofficial build.
589    if (!is_official_build || StartupUtils::IsEulaAccepted())
590      detector->Enable(true);
591  }
592
593  // Tests should be able to tune login manager before showing it.
594  // Thus only show login manager in normal (non-testing) mode.
595  if (!parameters().ui_task ||
596      parsed_command_line().HasSwitch(switches::kForceLoginManagerInTests)) {
597    OptionallyRunChromeOSLoginManager(parsed_command_line(), profile());
598  }
599
600  // These observers must be initialized after the profile because
601  // they use the profile to dispatch extension events.
602  extension_system_event_observer_.reset(new ExtensionSystemEventObserver());
603  if (KioskModeSettings::Get()->IsKioskModeEnabled()) {
604    retail_mode_power_save_blocker_ = content::PowerSaveBlocker::Create(
605        content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
606        "Retail mode");
607  }
608
609  peripheral_battery_observer_.reset(new PeripheralBatteryObserver());
610
611  display_configuration_observer_.reset(
612      new DisplayConfigurationObserver());
613
614  g_browser_process->platform_part()->InitializeAutomaticRebootManager();
615
616  // This observer cannot be created earlier because it requires the shell to be
617  // available.
618  idle_action_warning_observer_.reset(new IdleActionWarningObserver());
619
620  ChromeBrowserMainPartsLinux::PostProfileInit();
621}
622
623void ChromeBrowserMainPartsChromeos::PreBrowserStart() {
624  // -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
625  // -- just before MetricsService::LogNeedForCleanShutdown().
626
627  g_browser_process->metrics_service()->StartExternalMetrics();
628
629  // Listen for XI_HierarchyChanged events. Note: if this is moved to
630  // PreMainMessageLoopRun() then desktopui_PageCyclerTests fail for unknown
631  // reasons, see http://crosbug.com/24833.
632  XInputHierarchyChangedEventListener::GetInstance();
633
634#if defined(USE_X11)
635  // Start the CrOS input device UMA watcher
636  DeviceUMA::GetInstance();
637#endif
638
639  // -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
640  // -- immediately after ChildProcess::WaitForDebugger().
641
642  // Start the out-of-memory priority manager here so that we give the most
643  // amount of time for the other services to start up before we start
644  // adjusting the oom priority.
645  g_browser_process->platform_part()->oom_priority_manager()->Start();
646
647  // Turn on natural scroll if we have a touch screen.
648  if (ui::IsTouchDevicePresent()) {
649    CommandLine::ForCurrentProcess()->AppendSwitch(
650        chromeos::switches::kNaturalScrollDefault);
651    ui::SetNaturalScroll(true);
652  }
653
654  ChromeBrowserMainPartsLinux::PreBrowserStart();
655}
656
657void ChromeBrowserMainPartsChromeos::PostBrowserStart() {
658  // These are dependent on the ash::Shell singleton already having been
659  // initialized.
660  power_button_observer_.reset(new PowerButtonObserver);
661  data_promo_notification_.reset(new DataPromoNotification()),
662
663  ChromeBrowserMainPartsLinux::PostBrowserStart();
664}
665
666// Shut down services before the browser process, etc are destroyed.
667void ChromeBrowserMainPartsChromeos::PostMainMessageLoopRun() {
668  BootTimesLoader::Get()->AddLogoutTimeMarker("UIMessageLoopEnded", true);
669
670  g_browser_process->platform_part()->oom_priority_manager()->Stop();
671
672  // Stops all in-flight OAuth2 token fetchers before the IO thread stops.
673  DeviceOAuth2TokenServiceFactory::Shutdown();
674
675  // Shutdown the upgrade detector for Chrome OS. The upgrade detector
676  // stops monitoring changes from the update engine.
677  if (UpgradeDetectorChromeos::GetInstance())
678    UpgradeDetectorChromeos::GetInstance()->Shutdown();
679
680  // Shutdown the network change notifier for Chrome OS. The network
681  // change notifier stops monitoring changes from the power manager and
682  // the network manager.
683  if (NetworkChangeNotifierFactoryChromeos::GetInstance())
684    NetworkChangeNotifierFactoryChromeos::GetInstance()->Shutdown();
685
686  // Destroy UI related classes before destroying services that they may
687  // depend on.
688  data_promo_notification_.reset();
689
690  // Tell DeviceSettingsService to stop talking to session_manager. Do not
691  // shutdown DeviceSettingsService yet, it might still be accessed by
692  // BrowserPolicyConnector (owned by g_browser_process).
693  DeviceSettingsService::Get()->UnsetSessionManager();
694
695  // We should remove observers attached to D-Bus clients before
696  // DBusThreadManager is shut down.
697  extension_system_event_observer_.reset();
698  retail_mode_power_save_blocker_.reset();
699  peripheral_battery_observer_.reset();
700  power_prefs_.reset();
701
702  // The XInput2 event listener needs to be shut down earlier than when
703  // Singletons are finally destroyed in AtExitManager.
704  XInputHierarchyChangedEventListener::GetInstance()->Stop();
705
706#if defined(USE_X11)
707  DeviceUMA::GetInstance()->Stop();
708#endif
709
710  // SystemKeyEventListener::Shutdown() is always safe to call,
711  // even if Initialize() wasn't called.
712  SystemKeyEventListener::Shutdown();
713  imageburner::BurnManager::Shutdown();
714  CrasAudioHandler::Shutdown();
715
716  // Let classes unregister themselves as observers of the ash::Shell singleton
717  // before the shell is destroyed.
718  display_configuration_observer_.reset();
719
720  // Detach D-Bus clients before DBusThreadManager is shut down.
721  power_button_observer_.reset();
722  idle_action_warning_observer_.reset();
723
724  // Delete ContactManager while |g_browser_process| is still alive.
725  contact_manager_.reset();
726
727  MagnificationManager::Shutdown();
728  AccessibilityManager::Shutdown();
729  system::StatisticsProvider::GetInstance()->Shutdown();
730
731  // Let the UserManager and WallpaperManager unregister itself as an observer
732  // of the CrosSettings singleton before it is destroyed. This also ensures
733  // that the UserManager has no URLRequest pending (see
734  // http://crbug.com/276659).
735  UserManager::Get()->Shutdown();
736  WallpaperManager::Get()->Shutdown();
737
738  // Let the AutomaticRebootManager unregister itself as an observer of several
739  // subsystems.
740  g_browser_process->platform_part()->ShutdownAutomaticRebootManager();
741
742  // Clean up dependency on CrosSettings and stop pending data fetches.
743  KioskAppManager::Shutdown();
744
745  // We first call PostMainMessageLoopRun and then destroy UserManager, because
746  // Ash needs to be closed before UserManager is destroyed. Also, on some tests
747  // MergeSessionThrottle::ShouldShowMergeSessionPage gets triggered during
748  // PostMainMessageLoopRun, which also requires UserManager to live (see
749  // http://crbug.com/243364).
750  ChromeBrowserMainPartsLinux::PostMainMessageLoopRun();
751
752  // Called after
753  // ChromeBrowserMainPartsLinux::PostMainMessageLoopRun() to be
754  // executed after execution of chrome::CloseAsh(), because some
755  // parts of WebUI depends on NetworkPortalDetector.
756  NetworkPortalDetector::Shutdown();
757
758  UserManager::Destroy();
759}
760
761void ChromeBrowserMainPartsChromeos::PostDestroyThreads() {
762  // Destroy DBus services immediately after threads are stopped.
763  dbus_services_.reset();
764
765  ChromeBrowserMainPartsLinux::PostDestroyThreads();
766
767  // Destroy DeviceSettingsService after g_browser_process.
768  DeviceSettingsService::Shutdown();
769}
770
771void ChromeBrowserMainPartsChromeos::SetupPlatformFieldTrials() {
772  default_pinned_apps_field_trial::SetupTrial();
773}
774
775}  //  namespace chromeos
776