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