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/command_line.h"
     15 #include "base/file_util.h"
     16 #include "base/lazy_instance.h"
     17 #include "base/linux_util.h"
     18 #include "base/path_service.h"
     19 #include "base/prefs/pref_service.h"
     20 #include "base/strings/string_number_conversions.h"
     21 #include "base/strings/string_split.h"
     22 #include "base/sys_info.h"
     23 #include "chrome/browser/browser_process.h"
     24 #include "chrome/browser/browser_process_platform_part_chromeos.h"
     25 #include "chrome/browser/chrome_notification_types.h"
     26 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
     27 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
     28 #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h"
     29 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
     30 #include "chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.h"
     31 #include "chrome/browser/chromeos/boot_times_loader.h"
     32 #include "chrome/browser/chromeos/dbus/cros_dbus_service.h"
     33 #include "chrome/browser/chromeos/device/input_service_proxy.h"
     34 #include "chrome/browser/chromeos/events/event_rewriter.h"
     35 #include "chrome/browser/chromeos/events/event_rewriter_controller.h"
     36 #include "chrome/browser/chromeos/events/keyboard_driven_event_rewriter.h"
     37 #include "chrome/browser/chromeos/extensions/default_app_order.h"
     38 #include "chrome/browser/chromeos/extensions/extension_system_event_observer.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/input_method/input_method_util.h"
     43 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout.h"
     44 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h"
     45 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
     46 #include "chrome/browser/chromeos/language_preferences.h"
     47 #include "chrome/browser/chromeos/login/auth/authenticator.h"
     48 #include "chrome/browser/chromeos/login/auth/key.h"
     49 #include "chrome/browser/chromeos/login/auth/user_context.h"
     50 #include "chrome/browser/chromeos/login/helper.h"
     51 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
     52 #include "chrome/browser/chromeos/login/login_utils.h"
     53 #include "chrome/browser/chromeos/login/login_wizard.h"
     54 #include "chrome/browser/chromeos/login/session/session_manager.h"
     55 #include "chrome/browser/chromeos/login/startup_utils.h"
     56 #include "chrome/browser/chromeos/login/users/user.h"
     57 #include "chrome/browser/chromeos/login/users/user_manager.h"
     58 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
     59 #include "chrome/browser/chromeos/login/wizard_controller.h"
     60 #include "chrome/browser/chromeos/memory/oom_priority_manager.h"
     61 #include "chrome/browser/chromeos/net/network_portal_detector.h"
     62 #include "chrome/browser/chromeos/options/cert_library.h"
     63 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
     64 #include "chrome/browser/chromeos/policy/device_local_account.h"
     65 #include "chrome/browser/chromeos/power/idle_action_warning_observer.h"
     66 #include "chrome/browser/chromeos/power/peripheral_battery_observer.h"
     67 #include "chrome/browser/chromeos/power/power_button_observer.h"
     68 #include "chrome/browser/chromeos/power/power_data_collector.h"
     69 #include "chrome/browser/chromeos/power/power_prefs.h"
     70 #include "chrome/browser/chromeos/profiles/profile_helper.h"
     71 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h"
     72 #include "chrome/browser/chromeos/settings/device_settings_service.h"
     73 #include "chrome/browser/chromeos/settings/owner_key_util.h"
     74 #include "chrome/browser/chromeos/status/data_promo_notification.h"
     75 #include "chrome/browser/chromeos/system/input_device_settings.h"
     76 #include "chrome/browser/chromeos/upgrade_detector_chromeos.h"
     77 #include "chrome/browser/defaults.h"
     78 #include "chrome/browser/lifetime/application_lifetime.h"
     79 #include "chrome/browser/net/chrome_network_delegate.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_constants.h"
     84 #include "chrome/common/chrome_paths.h"
     85 #include "chrome/common/chrome_switches.h"
     86 #include "chrome/common/chrome_version_info.h"
     87 #include "chrome/common/logging_chrome.h"
     88 #include "chrome/common/pref_names.h"
     89 #include "chromeos/audio/audio_devices_pref_handler.h"
     90 #include "chromeos/audio/cras_audio_handler.h"
     91 #include "chromeos/cert_loader.h"
     92 #include "chromeos/chromeos_paths.h"
     93 #include "chromeos/chromeos_switches.h"
     94 #include "chromeos/cryptohome/async_method_caller.h"
     95 #include "chromeos/cryptohome/homedir_methods.h"
     96 #include "chromeos/cryptohome/system_salt_getter.h"
     97 #include "chromeos/dbus/dbus_thread_manager.h"
     98 #include "chromeos/dbus/power_policy_controller.h"
     99 #include "chromeos/dbus/session_manager_client.h"
    100 #include "chromeos/disks/disk_mount_manager.h"
    101 #include "chromeos/ime/ime_keyboard.h"
    102 #include "chromeos/ime/input_method_manager.h"
    103 #include "chromeos/login/login_state.h"
    104 #include "chromeos/network/network_change_notifier_chromeos.h"
    105 #include "chromeos/network/network_change_notifier_factory_chromeos.h"
    106 #include "chromeos/network/network_handler.h"
    107 #include "chromeos/system/statistics_provider.h"
    108 #include "chromeos/tpm_token_loader.h"
    109 #include "components/metrics/metrics_service.h"
    110 #include "content/public/browser/browser_thread.h"
    111 #include "content/public/browser/notification_service.h"
    112 #include "content/public/browser/power_save_blocker.h"
    113 #include "content/public/common/main_function_params.h"
    114 #include "grit/platform_locale_settings.h"
    115 #include "media/audio/sounds/sounds_manager.h"
    116 #include "net/base/network_change_notifier.h"
    117 #include "net/url_request/url_request.h"
    118 #include "net/url_request/url_request_context_getter.h"
    119 #include "ui/base/touch/touch_device.h"
    120 #include "ui/events/event_utils.h"
    121 
    122 // Exclude X11 dependents for ozone
    123 #if defined(USE_X11)
    124 #include "chrome/browser/chromeos/device_uma.h"
    125 #include "chrome/browser/chromeos/events/system_key_event_listener.h"
    126 #include "chrome/browser/chromeos/events/xinput_hierarchy_changed_event_listener.h"
    127 #endif
    128 
    129 namespace chromeos {
    130 
    131 namespace {
    132 
    133 void ChromeOSVersionCallback(const std::string& version) {
    134   base::SetLinuxDistro(std::string("CrOS ") + version);
    135 }
    136 
    137 // Login -----------------------------------------------------------------------
    138 
    139 // Class is used to login using passed username and password.
    140 // The instance will be deleted upon success or failure.
    141 class StubLogin : public LoginStatusConsumer,
    142                   public LoginUtils::Delegate {
    143  public:
    144   StubLogin(std::string username, std::string password)
    145       : profile_prepared_(false) {
    146     authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
    147     UserContext user_context(username);
    148     user_context.SetKey(Key(password));
    149     authenticator_.get()->AuthenticateToLogin(ProfileHelper::GetSigninProfile(),
    150                                               user_context);
    151   }
    152 
    153   virtual ~StubLogin() {
    154     LoginUtils::Get()->DelegateDeleted(this);
    155   }
    156 
    157   virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE {
    158     LOG(ERROR) << "Login Failure: " << error.GetErrorString();
    159     delete this;
    160   }
    161 
    162   virtual void OnLoginSuccess(const UserContext& user_context) OVERRIDE {
    163     if (!profile_prepared_) {
    164       // Will call OnProfilePrepared in the end.
    165       LoginUtils::Get()->PrepareProfile(user_context,
    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     const std::string login_user = login::CanonicalizeUserID(
    177         CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
    178             switches::kLoginUser));
    179     if (!policy::IsDeviceLocalAccountUser(login_user, NULL)) {
    180       profile->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
    181                                      login_user);
    182     }
    183     profile_prepared_ = true;
    184     LoginUtils::Get()->DoBrowserLaunch(profile, NULL);
    185     delete this;
    186   }
    187 
    188   scoped_refptr<Authenticator> authenticator_;
    189   bool profile_prepared_;
    190 };
    191 
    192 bool ShouldAutoLaunchKioskApp(const CommandLine& command_line) {
    193   KioskAppManager* app_manager = KioskAppManager::Get();
    194   return command_line.HasSwitch(switches::kLoginManager) &&
    195       !command_line.HasSwitch(switches::kForceLoginManagerInTests) &&
    196       app_manager->IsAutoLaunchEnabled() &&
    197       KioskAppLaunchError::Get() == KioskAppLaunchError::NONE;
    198 }
    199 
    200 void RunAutoLaunchKioskApp() {
    201   ShowLoginWizard(chromeos::WizardController::kAppLaunchSplashScreenName);
    202 
    203   // Login screen is skipped but 'login-prompt-visible' signal is still needed.
    204   VLOG(1) << "Kiosk app auto launch >> login-prompt-visible";
    205   DBusThreadManager::Get()->GetSessionManagerClient()->
    206       EmitLoginPromptVisible();
    207 }
    208 
    209 void OptionallyRunChromeOSLoginManager(const CommandLine& parsed_command_line,
    210                                        Profile* profile) {
    211   if (ShouldAutoLaunchKioskApp(parsed_command_line)) {
    212     RunAutoLaunchKioskApp();
    213   } else if (parsed_command_line.HasSwitch(switches::kLoginManager)) {
    214     ShowLoginWizard(std::string());
    215 
    216     if (KioskModeSettings::Get()->IsKioskModeEnabled())
    217       InitializeKioskModeScreensaver();
    218 
    219     // Reset reboot after update flag when login screen is shown.
    220     policy::BrowserPolicyConnectorChromeOS* connector =
    221         g_browser_process->platform_part()->browser_policy_connector_chromeos();
    222     if (!connector->IsEnterpriseManaged()) {
    223       PrefService* local_state = g_browser_process->local_state();
    224       local_state->ClearPref(prefs::kRebootAfterUpdate);
    225     }
    226   } else if (parsed_command_line.HasSwitch(switches::kLoginUser) &&
    227              parsed_command_line.HasSwitch(switches::kLoginPassword)) {
    228     BootTimesLoader::Get()->RecordLoginAttempted();
    229     new StubLogin(
    230         parsed_command_line.GetSwitchValueASCII(switches::kLoginUser),
    231         parsed_command_line.GetSwitchValueASCII(switches::kLoginPassword));
    232   } else {
    233     if (!parsed_command_line.HasSwitch(::switches::kTestName)) {
    234       // Enable CrasAudioHandler logging when chrome restarts after crashing.
    235       if (chromeos::CrasAudioHandler::IsInitialized())
    236         chromeos::CrasAudioHandler::Get()->LogErrors();
    237 
    238       // We did not log in (we crashed or are debugging), so we need to
    239       // restore Sync.
    240       SessionManager::GetInstance()->RestoreAuthenticationSession(profile);
    241     }
    242   }
    243 }
    244 
    245 }  // namespace
    246 
    247 namespace internal {
    248 
    249 // Wrapper class for initializing dbus related services and shutting them
    250 // down. This gets instantiated in a scoped_ptr so that shutdown methods in the
    251 // destructor will get called if and only if this has been instantiated.
    252 class DBusServices {
    253  public:
    254   explicit DBusServices(const content::MainFunctionParams& parameters) {
    255     // Initialize DBusThreadManager for the browser. This must be done after
    256     // the main message loop is started, as it uses the message loop.
    257     DBusThreadManager::Initialize();
    258     CrosDBusService::Initialize();
    259 
    260     // Initialize PowerDataCollector after DBusThreadManager is initialized.
    261     PowerDataCollector::Initialize();
    262 
    263     LoginState::Initialize();
    264     SystemSaltGetter::Initialize();
    265     TPMTokenLoader::Initialize();
    266     CertLoader::Initialize();
    267 
    268     // This function and SystemKeyEventListener use InputMethodManager.
    269     chromeos::input_method::Initialize(
    270         content::BrowserThread::GetMessageLoopProxyForThread(
    271             content::BrowserThread::UI),
    272         content::BrowserThread::GetMessageLoopProxyForThread(
    273             content::BrowserThread::FILE));
    274     disks::DiskMountManager::Initialize();
    275     cryptohome::AsyncMethodCaller::Initialize();
    276     cryptohome::HomedirMethods::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()
    293           ->GetImeKeyboard()
    294           ->DisableNumLock();
    295     }
    296 
    297     // Initialize the device settings service so that we'll take actions per
    298     // signals sent from the session manager. This needs to happen before
    299     // g_browser_process initializes BrowserPolicyConnector.
    300     DeviceSettingsService::Initialize();
    301     DeviceSettingsService::Get()->SetSessionManager(
    302         DBusThreadManager::Get()->GetSessionManagerClient(),
    303         OwnerKeyUtil::Create());
    304   }
    305 
    306   ~DBusServices() {
    307     CertLibrary::Shutdown();
    308     NetworkHandler::Shutdown();
    309 
    310     cryptohome::AsyncMethodCaller::Shutdown();
    311     disks::DiskMountManager::Shutdown();
    312     input_method::Shutdown();
    313 
    314     SystemSaltGetter::Shutdown();
    315     LoginState::Shutdown();
    316     CertLoader::Shutdown();
    317     TPMTokenLoader::Shutdown();
    318 
    319     CrosDBusService::Shutdown();
    320 
    321     // Shutdown the PowerDataCollector before shutting down DBusThreadManager.
    322     PowerDataCollector::Shutdown();
    323 
    324     // NOTE: This must only be called if Initialize() was called.
    325     DBusThreadManager::Shutdown();
    326   }
    327 
    328  private:
    329 
    330   DISALLOW_COPY_AND_ASSIGN(DBusServices);
    331 };
    332 
    333 }  //  namespace internal
    334 
    335 // ChromeBrowserMainPartsChromeos ----------------------------------------------
    336 
    337 ChromeBrowserMainPartsChromeos::ChromeBrowserMainPartsChromeos(
    338     const content::MainFunctionParams& parameters)
    339     : ChromeBrowserMainPartsLinux(parameters) {
    340 }
    341 
    342 ChromeBrowserMainPartsChromeos::~ChromeBrowserMainPartsChromeos() {
    343   if (KioskModeSettings::Get()->IsKioskModeEnabled())
    344     ShutdownKioskModeScreensaver();
    345 
    346   // To be precise, logout (browser shutdown) is not yet done, but the
    347   // remaining work is negligible, hence we say LogoutDone here.
    348   BootTimesLoader::Get()->AddLogoutTimeMarker("LogoutDone", false);
    349   BootTimesLoader::Get()->WriteLogoutTimes();
    350 }
    351 
    352 // content::BrowserMainParts and ChromeBrowserMainExtraParts overrides ---------
    353 
    354 void ChromeBrowserMainPartsChromeos::PreEarlyInitialization() {
    355   CommandLine* singleton_command_line = CommandLine::ForCurrentProcess();
    356 
    357   if (parsed_command_line().HasSwitch(switches::kGuestSession)) {
    358     // Disable sync and extensions if we're in "browse without sign-in" mode.
    359     singleton_command_line->AppendSwitch(::switches::kDisableSync);
    360     singleton_command_line->AppendSwitch(::switches::kDisableExtensions);
    361     browser_defaults::bookmarks_enabled = false;
    362   }
    363 
    364   // If we're not running on real Chrome OS hardware (or under VM), and are not
    365   // showing the login manager or attempting a command line login, login with a
    366   // stub user.
    367   if (!base::SysInfo::IsRunningOnChromeOS() &&
    368       !parsed_command_line().HasSwitch(switches::kLoginManager) &&
    369       !parsed_command_line().HasSwitch(switches::kLoginUser) &&
    370       !parsed_command_line().HasSwitch(switches::kGuestSession)) {
    371     singleton_command_line->AppendSwitchASCII(
    372         switches::kLoginUser, UserManager::kStubUser);
    373     if (!parsed_command_line().HasSwitch(switches::kLoginProfile)) {
    374       singleton_command_line->AppendSwitchASCII(switches::kLoginProfile,
    375                                                 chrome::kTestUserProfileDir);
    376     }
    377     LOG(WARNING) << "Running as stub user with profile dir: "
    378                  << singleton_command_line->GetSwitchValuePath(
    379                      switches::kLoginProfile).value();
    380   }
    381 
    382 #if defined(GOOGLE_CHROME_BUILD)
    383   const char kChromeOSReleaseTrack[] = "CHROMEOS_RELEASE_TRACK";
    384   std::string channel;
    385   if (base::SysInfo::GetLsbReleaseValue(kChromeOSReleaseTrack, &channel))
    386     chrome::VersionInfo::SetChannel(channel);
    387 #endif
    388 
    389   ChromeBrowserMainPartsLinux::PreEarlyInitialization();
    390 }
    391 
    392 void ChromeBrowserMainPartsChromeos::PreMainMessageLoopStart() {
    393   // Replace the default NetworkChangeNotifierFactory with ChromeOS specific
    394   // implementation. This must be done before BrowserMainLoop calls
    395   // net::NetworkChangeNotifier::Create() in MainMessageLoopStart().
    396   net::NetworkChangeNotifier::SetFactory(
    397       new NetworkChangeNotifierFactoryChromeos());
    398   ChromeBrowserMainPartsLinux::PreMainMessageLoopStart();
    399 }
    400 
    401 void ChromeBrowserMainPartsChromeos::PostMainMessageLoopStart() {
    402   base::FilePath user_data_dir;
    403   if (!base::SysInfo::IsRunningOnChromeOS() &&
    404       PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
    405     // Override some paths with stub locations so that cloud policy and
    406     // enterprise enrollment work on desktop builds, for ease of
    407     // development.
    408     chromeos::RegisterStubPathOverrides(user_data_dir);
    409   }
    410 
    411   dbus_services_.reset(new internal::DBusServices(parameters()));
    412 
    413   ChromeBrowserMainPartsLinux::PostMainMessageLoopStart();
    414 }
    415 
    416 // Threads are initialized between MainMessageLoopStart and MainMessageLoopRun.
    417 // about_flags settings are applied in ChromeBrowserMainParts::PreCreateThreads.
    418 void ChromeBrowserMainPartsChromeos::PreMainMessageLoopRun() {
    419   // Set the crypto thread after the IO thread has been created/started.
    420   TPMTokenLoader::Get()->SetCryptoTaskRunner(
    421       content::BrowserThread::GetMessageLoopProxyForThread(
    422           content::BrowserThread::IO));
    423 
    424   CrasAudioHandler::Initialize(
    425       AudioDevicesPrefHandler::Create(g_browser_process->local_state()));
    426 
    427   // Start loading machine statistics here. StatisticsProvider::Shutdown()
    428   // will ensure that loading is aborted on early exit.
    429   bool load_oem_statistics = !StartupUtils::IsOobeCompleted();
    430   system::StatisticsProvider::GetInstance()->StartLoadingMachineStatistics(
    431       content::BrowserThread::GetMessageLoopProxyForThread(
    432           content::BrowserThread::FILE),
    433       load_oem_statistics);
    434 
    435   base::FilePath downloads_directory;
    436   CHECK(PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &downloads_directory));
    437   imageburner::BurnManager::Initialize(
    438       downloads_directory, g_browser_process->system_request_context());
    439 
    440   DeviceOAuth2TokenServiceFactory::Initialize();
    441 
    442   ChromeBrowserMainPartsLinux::PreMainMessageLoopRun();
    443 }
    444 
    445 void ChromeBrowserMainPartsChromeos::PreProfileInit() {
    446   // -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
    447   // -- immediately before Profile creation().
    448 
    449   // Now that the file thread exists we can record our stats.
    450   BootTimesLoader::Get()->RecordChromeMainStats();
    451 
    452   // Trigger prefetching of ownership status.
    453   DeviceSettingsService::Get()->Load();
    454 
    455   // -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
    456   // -- just before CreateProfile().
    457 
    458   UserManager::Initialize();
    459 
    460   // Initialize the screen locker now so that it can receive
    461   // LOGIN_USER_CHANGED notification from UserManager.
    462   if (KioskModeSettings::Get()->IsKioskModeEnabled())
    463     KioskModeIdleLogout::Initialize();
    464   else
    465     ScreenLocker::InitClass();
    466 
    467   // This forces the ProfileManager to be created and register for the
    468   // notification it needs to track the logged in user.
    469   g_browser_process->profile_manager();
    470 
    471   // ProfileHelper has to be initialized after UserManager instance is created.
    472   g_browser_process->platform_part()->profile_helper()->Initialize();
    473 
    474   // TODO(abarth): Should this move to InitializeNetworkOptions()?
    475   // Allow access to file:// on ChromeOS for tests.
    476   if (parsed_command_line().HasSwitch(::switches::kAllowFileAccess))
    477     ChromeNetworkDelegate::AllowAccessToAllFiles();
    478 
    479   // There are two use cases for kLoginUser:
    480   //   1) if passed in tandem with kLoginPassword, to drive a "StubLogin"
    481   //   2) if passed alone, to signal that the indicated user has already
    482   //      logged in and we should behave accordingly.
    483   // This handles case 2.
    484   bool immediate_login =
    485       parsed_command_line().HasSwitch(switches::kLoginUser) &&
    486       !parsed_command_line().HasSwitch(switches::kLoginPassword);
    487   if (immediate_login){
    488     // Redirects Chrome logging to the user data dir.
    489     logging::RedirectChromeLogging(parsed_command_line());
    490 
    491     // Load the default app order synchronously for restarting case.
    492     app_order_loader_.reset(
    493         new default_app_order::ExternalLoader(false /* async */));
    494   }
    495 
    496   if (!app_order_loader_) {
    497     app_order_loader_.reset(
    498         new default_app_order::ExternalLoader(true /* async */));
    499   }
    500 
    501   media::SoundsManager::Create();
    502 
    503   // Initialize magnification manager before ash tray is created. And this must
    504   // be placed after UserManager::SessionStarted();
    505   AccessibilityManager::Initialize();
    506   MagnificationManager::Initialize();
    507 
    508   // Add observers for WallpaperManager. This depends on PowerManagerClient,
    509   // TimezoneSettings and CrosSettings.
    510   WallpaperManager::Get()->AddObservers();
    511 
    512   cros_version_loader_.GetVersion(VersionLoader::VERSION_FULL,
    513                                   base::Bind(&ChromeOSVersionCallback),
    514                                   &tracker_);
    515 
    516   // Make sure that wallpaper boot transition and other delays in OOBE
    517   // are disabled for tests and kiosk app launch by default.
    518   // Individual tests may enable them if they want.
    519   if (parsed_command_line().HasSwitch(::switches::kTestType) ||
    520       ShouldAutoLaunchKioskApp(parsed_command_line())) {
    521     WizardController::SetZeroDelays();
    522   }
    523 
    524   power_prefs_.reset(new PowerPrefs(
    525       DBusThreadManager::Get()->GetPowerPolicyController()));
    526 
    527   // In Aura builds this will initialize ash::Shell.
    528   ChromeBrowserMainPartsLinux::PreProfileInit();
    529 
    530   if (immediate_login) {
    531     const std::string user_id = login::CanonicalizeUserID(
    532         parsed_command_line().GetSwitchValueASCII(switches::kLoginUser));
    533     UserManager* user_manager = UserManager::Get();
    534 
    535     if (policy::IsDeviceLocalAccountUser(user_id, NULL) &&
    536         !user_manager->IsKnownUser(user_id)) {
    537       // When a device-local account is removed, its policy is deleted from disk
    538       // immediately. If a session using this account happens to be in progress,
    539       // the session is allowed to continue with policy served from an in-memory
    540       // cache. If Chrome crashes later in the session, the policy becomes
    541       // completely unavailable. Exit the session in that case, rather than
    542       // allowing it to continue without policy.
    543       chrome::AttemptUserExit();
    544       return;
    545     }
    546 
    547     // In case of multi-profiles --login-profile will contain user_id_hash.
    548     std::string user_id_hash =
    549         parsed_command_line().GetSwitchValueASCII(switches::kLoginProfile);
    550     user_manager->UserLoggedIn(user_id, user_id_hash, true);
    551     VLOG(1) << "Relaunching browser for user: " << user_id
    552             << " with hash: " << user_id_hash;
    553   }
    554 }
    555 
    556 class GuestLanguageSetCallbackData {
    557  public:
    558   explicit GuestLanguageSetCallbackData(Profile* profile) : profile(profile) {
    559   }
    560 
    561   // Must match SwitchLanguageCallback type.
    562   static void Callback(const scoped_ptr<GuestLanguageSetCallbackData>& self,
    563                        const std::string& locale,
    564                        const std::string& loaded_locale,
    565                        bool success);
    566 
    567   Profile* profile;
    568 };
    569 
    570 // static
    571 void GuestLanguageSetCallbackData::Callback(
    572     const scoped_ptr<GuestLanguageSetCallbackData>& self,
    573     const std::string& locale,
    574     const std::string& loaded_locale,
    575     bool success) {
    576   input_method::InputMethodManager* const ime_manager =
    577       input_method::InputMethodManager::Get();
    578   // Active layout must be hardware "login layout".
    579   // The previous one must be "locale default layout".
    580   // First, enable all hardware input methods.
    581   const std::vector<std::string>& input_methods =
    582       ime_manager->GetInputMethodUtil()->GetHardwareInputMethodIds();
    583   for (size_t i = 0; i < input_methods.size(); ++i)
    584     ime_manager->EnableInputMethod(input_methods[i]);
    585 
    586   // Second, enable locale based input methods.
    587   const std::string locale_default_input_method =
    588       ime_manager->GetInputMethodUtil()->
    589           GetLanguageDefaultInputMethodId(loaded_locale);
    590   if (!locale_default_input_method.empty()) {
    591     PrefService* user_prefs = self->profile->GetPrefs();
    592     user_prefs->SetString(prefs::kLanguagePreviousInputMethod,
    593                           locale_default_input_method);
    594     ime_manager->EnableInputMethod(locale_default_input_method);
    595   }
    596 
    597   // Finally, activate the first login input method.
    598   const std::vector<std::string>& login_input_methods =
    599       ime_manager->GetInputMethodUtil()->GetHardwareLoginInputMethodIds();
    600   ime_manager->ChangeInputMethod(login_input_methods[0]);
    601 }
    602 
    603 void SetGuestLocale(UserManager* const usermanager, Profile* const profile) {
    604   scoped_ptr<GuestLanguageSetCallbackData> data(
    605       new GuestLanguageSetCallbackData(profile));
    606   scoped_ptr<locale_util::SwitchLanguageCallback> callback(
    607       new locale_util::SwitchLanguageCallback(base::Bind(
    608           &GuestLanguageSetCallbackData::Callback, base::Passed(data.Pass()))));
    609   User* const user = usermanager->GetUserByProfile(profile);
    610   usermanager->RespectLocalePreference(profile, user, callback.Pass());
    611 }
    612 
    613 void ChromeBrowserMainPartsChromeos::PostProfileInit() {
    614   // -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
    615   // -- just after CreateProfile().
    616 
    617   BootTimesLoader::Get()->OnChromeProcessStart();
    618 
    619   // Restarting Chrome inside existing user session. Possible cases:
    620   // 1. Chrome is restarted after crash.
    621   // 2. Chrome is started in browser_tests skipping the login flow
    622   // 3. Chrome is started on dev machine
    623   //    i.e. not on Chrome OS device w/o login flow.
    624   if (parsed_command_line().HasSwitch(switches::kLoginUser) &&
    625       !parsed_command_line().HasSwitch(switches::kLoginPassword)) {
    626     std::string login_user = login::CanonicalizeUserID(
    627         parsed_command_line().GetSwitchValueASCII(
    628             chromeos::switches::kLoginUser));
    629     if (!base::SysInfo::IsRunningOnChromeOS() &&
    630         login_user == UserManager::kStubUser) {
    631       // For dev machines and stub user emulate as if sync has been initialized.
    632       profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
    633                                        login_user);
    634     }
    635 
    636     // This is done in SessionManager::OnProfileCreated during normal login.
    637     SessionManager::GetInstance()->InitRlz(profile());
    638 
    639     // Send the PROFILE_PREPARED notification and call SessionStarted()
    640     // so that the Launcher and other Profile dependent classes are created.
    641     content::NotificationService::current()->Notify(
    642         chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
    643         content::NotificationService::AllSources(),
    644         content::Details<Profile>(profile()));
    645     UserManager::Get()->SessionStarted();
    646 
    647     // Now is the good time to retrieve other logged in users for this session.
    648     // First user has been already marked as logged in and active in
    649     // PreProfileInit(). Chrome should tread other user in a session as active
    650     // in the background.
    651     UserManager::Get()->RestoreActiveSessions();
    652   }
    653 
    654   // Initialize the network portal detector for Chrome OS. The network
    655   // portal detector starts to listen for notifications from
    656   // NetworkStateHandler and initiates captive portal detection for
    657   // active networks. Shoule be called before call to
    658   // OptionallyRunChromeOSLoginManager, because it depends on
    659   // NetworkPortalDetector.
    660   NetworkPortalDetector::Initialize();
    661   {
    662     NetworkPortalDetector* detector = NetworkPortalDetector::Get();
    663 #if defined(GOOGLE_CHROME_BUILD)
    664     bool is_official_build = true;
    665 #else
    666     bool is_official_build = false;
    667 #endif
    668     // Enable portal detector if EULA was previously accepted or if
    669     // this is an unofficial build.
    670     if (!is_official_build || StartupUtils::IsEulaAccepted())
    671       detector->Enable(true);
    672   }
    673 
    674   // Tests should be able to tune login manager before showing it.
    675   // Thus only show login manager in normal (non-testing) mode.
    676   if (!parameters().ui_task ||
    677       parsed_command_line().HasSwitch(switches::kForceLoginManagerInTests)) {
    678     OptionallyRunChromeOSLoginManager(parsed_command_line(), profile());
    679   }
    680 
    681   // Guest user profile is never initialized with locale settings,
    682   // so we need special handling for Guest session.
    683   UserManager* const usermanager = UserManager::Get();
    684   if (usermanager->IsLoggedInAsGuest())
    685     SetGuestLocale(usermanager, profile());
    686 
    687   // These observers must be initialized after the profile because
    688   // they use the profile to dispatch extension events.
    689   extension_system_event_observer_.reset(new ExtensionSystemEventObserver());
    690   if (KioskModeSettings::Get()->IsKioskModeEnabled()) {
    691     retail_mode_power_save_blocker_ = content::PowerSaveBlocker::Create(
    692         content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
    693         "Retail mode");
    694   }
    695 
    696   peripheral_battery_observer_.reset(new PeripheralBatteryObserver());
    697 
    698   g_browser_process->platform_part()->InitializeAutomaticRebootManager();
    699 
    700   // This observer cannot be created earlier because it requires the shell to be
    701   // available.
    702   idle_action_warning_observer_.reset(new IdleActionWarningObserver());
    703 
    704   ChromeBrowserMainPartsLinux::PostProfileInit();
    705 }
    706 
    707 void ChromeBrowserMainPartsChromeos::PreBrowserStart() {
    708   // -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
    709   // -- just before MetricsService::LogNeedForCleanShutdown().
    710 
    711   // Start the external metrics service, which collects metrics from Chrome OS
    712   // and passes them to the browser process.
    713   external_metrics_ = new chromeos::ExternalMetrics;
    714   external_metrics_->Start();
    715 
    716 #if defined(USE_X11)
    717   // Listen for system key events so that the user will be able to adjust the
    718   // volume on the login screen, if Chrome is running on Chrome OS
    719   // (i.e. not Linux desktop), and in non-test mode.
    720   // Note: SystemKeyEventListener depends on the DBus thread.
    721   if (base::SysInfo::IsRunningOnChromeOS() &&
    722       !parameters().ui_task) {  // ui_task is non-NULL when running tests.
    723     SystemKeyEventListener::Initialize();
    724   }
    725 
    726   // Listen for XI_HierarchyChanged events. Note: if this is moved to
    727   // PreMainMessageLoopRun() then desktopui_PageCyclerTests fail for unknown
    728   // reasons, see http://crosbug.com/24833.
    729   XInputHierarchyChangedEventListener::GetInstance();
    730 
    731   // Start the CrOS input device UMA watcher
    732   DeviceUMA::GetInstance();
    733 #endif
    734   keyboard_event_rewriters_.reset(new EventRewriterController());
    735   keyboard_event_rewriters_->AddEventRewriter(
    736       scoped_ptr<ui::EventRewriter>(new KeyboardDrivenEventRewriter()));
    737   keyboard_event_rewriters_->AddEventRewriter(
    738       scoped_ptr<ui::EventRewriter>(new EventRewriter()));
    739 
    740   // -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
    741   // -- immediately after ChildProcess::WaitForDebugger().
    742 
    743   // Start the out-of-memory priority manager here so that we give the most
    744   // amount of time for the other services to start up before we start
    745   // adjusting the oom priority.
    746   g_browser_process->platform_part()->oom_priority_manager()->Start();
    747 
    748   if (ui::ShouldDefaultToNaturalScroll()) {
    749     CommandLine::ForCurrentProcess()->AppendSwitch(
    750         chromeos::switches::kNaturalScrollDefault);
    751     system::InputDeviceSettings::Get()->SetTapToClick(true);
    752   }
    753 
    754   ChromeBrowserMainPartsLinux::PreBrowserStart();
    755 }
    756 
    757 void ChromeBrowserMainPartsChromeos::PostBrowserStart() {
    758   // These are dependent on the ash::Shell singleton already having been
    759   // initialized.
    760   power_button_observer_.reset(new PowerButtonObserver);
    761   data_promo_notification_.reset(new DataPromoNotification()),
    762   keyboard_event_rewriters_->Init();
    763 
    764   ChromeBrowserMainPartsLinux::PostBrowserStart();
    765 }
    766 
    767 // Shut down services before the browser process, etc are destroyed.
    768 void ChromeBrowserMainPartsChromeos::PostMainMessageLoopRun() {
    769   BootTimesLoader::Get()->AddLogoutTimeMarker("UIMessageLoopEnded", true);
    770 
    771   g_browser_process->platform_part()->oom_priority_manager()->Stop();
    772 
    773   // Early wake-up of HID device service.
    774   InputServiceProxy::WarmUp();
    775 
    776   // Destroy the application name notifier for Kiosk mode.
    777   KioskModeIdleAppNameNotification::Shutdown();
    778 
    779   // Shutdown the upgrade detector for Chrome OS. The upgrade detector
    780   // stops monitoring changes from the update engine.
    781   if (UpgradeDetectorChromeos::GetInstance())
    782     UpgradeDetectorChromeos::GetInstance()->Shutdown();
    783 
    784   // Shutdown the network change notifier for Chrome OS. The network
    785   // change notifier stops monitoring changes from the power manager and
    786   // the network manager.
    787   if (NetworkChangeNotifierFactoryChromeos::GetInstance())
    788     NetworkChangeNotifierFactoryChromeos::GetInstance()->Shutdown();
    789 
    790   // Destroy UI related classes before destroying services that they may
    791   // depend on.
    792   data_promo_notification_.reset();
    793 
    794   // Tell DeviceSettingsService to stop talking to session_manager. Do not
    795   // shutdown DeviceSettingsService yet, it might still be accessed by
    796   // BrowserPolicyConnector (owned by g_browser_process).
    797   DeviceSettingsService::Get()->UnsetSessionManager();
    798 
    799   // We should remove observers attached to D-Bus clients before
    800   // DBusThreadManager is shut down.
    801   extension_system_event_observer_.reset();
    802   retail_mode_power_save_blocker_.reset();
    803   peripheral_battery_observer_.reset();
    804   power_prefs_.reset();
    805 
    806   // Let the ScreenLocker unregister itself from SessionManagerClient before
    807   // DBusThreadManager is shut down.
    808   if (!KioskModeSettings::Get()->IsKioskModeEnabled())
    809     ScreenLocker::ShutDownClass();
    810 
    811   keyboard_event_rewriters_.reset();
    812 #if defined(USE_X11)
    813   // The XInput2 event listener needs to be shut down earlier than when
    814   // Singletons are finally destroyed in AtExitManager.
    815   XInputHierarchyChangedEventListener::GetInstance()->Stop();
    816 
    817   DeviceUMA::GetInstance()->Stop();
    818 
    819   // SystemKeyEventListener::Shutdown() is always safe to call,
    820   // even if Initialize() wasn't called.
    821   SystemKeyEventListener::Shutdown();
    822 #endif
    823 
    824   imageburner::BurnManager::Shutdown();
    825   CrasAudioHandler::Shutdown();
    826 
    827   // Detach D-Bus clients before DBusThreadManager is shut down.
    828   power_button_observer_.reset();
    829   idle_action_warning_observer_.reset();
    830 
    831   MagnificationManager::Shutdown();
    832   AccessibilityManager::Shutdown();
    833 
    834   media::SoundsManager::Shutdown();
    835 
    836   system::StatisticsProvider::GetInstance()->Shutdown();
    837 
    838   // Let the UserManager and WallpaperManager unregister itself as an observer
    839   // of the CrosSettings singleton before it is destroyed. This also ensures
    840   // that the UserManager has no URLRequest pending (see
    841   // http://crbug.com/276659).
    842   UserManager::Get()->Shutdown();
    843   WallpaperManager::Get()->Shutdown();
    844 
    845   // Let the AutomaticRebootManager unregister itself as an observer of several
    846   // subsystems.
    847   g_browser_process->platform_part()->ShutdownAutomaticRebootManager();
    848 
    849   // Clean up dependency on CrosSettings and stop pending data fetches.
    850   KioskAppManager::Shutdown();
    851 
    852   // We first call PostMainMessageLoopRun and then destroy UserManager, because
    853   // Ash needs to be closed before UserManager is destroyed.
    854   ChromeBrowserMainPartsLinux::PostMainMessageLoopRun();
    855 
    856   // Stops all in-flight OAuth2 token fetchers before the IO thread stops.
    857   DeviceOAuth2TokenServiceFactory::Shutdown();
    858 
    859   // Called after
    860   // ChromeBrowserMainPartsLinux::PostMainMessageLoopRun() to be
    861   // executed after execution of chrome::CloseAsh(), because some
    862   // parts of WebUI depends on NetworkPortalDetector.
    863   NetworkPortalDetector::Shutdown();
    864 
    865   UserManager::Destroy();
    866 }
    867 
    868 void ChromeBrowserMainPartsChromeos::PostDestroyThreads() {
    869   // Destroy DBus services immediately after threads are stopped.
    870   dbus_services_.reset();
    871 
    872   ChromeBrowserMainPartsLinux::PostDestroyThreads();
    873 
    874   // Destroy DeviceSettingsService after g_browser_process.
    875   DeviceSettingsService::Shutdown();
    876 }
    877 
    878 }  //  namespace chromeos
    879