Upstream version 10.38.208.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chrome_browser_main.cc
index 5025758..06c0a28 100644 (file)
@@ -4,10 +4,7 @@
 
 #include "chrome/browser/chrome_browser_main.h"
 
-#if defined(TOOLKIT_GTK)
-#include <gtk/gtk.h>
-#endif
-
+#include <set>
 #include <string>
 #include <vector>
 
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chrome/browser/browser_shutdown.h"
 #include "chrome/browser/chrome_browser_main_extra_parts.h"
+#include "chrome/browser/component_updater/cld_component_installer.h"
 #include "chrome/browser/component_updater/component_updater_service.h"
+#include "chrome/browser/component_updater/ev_whitelist_component_installer.h"
 #include "chrome/browser/component_updater/flash_component_installer.h"
 #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h"
 #include "chrome/browser/component_updater/recovery_component_installer.h"
 #include "chrome/browser/component_updater/swiftshader_component_installer.h"
 #include "chrome/browser/component_updater/widevine_cdm_component_installer.h"
 #include "chrome/browser/defaults.h"
-#include "chrome/browser/extensions/extension_protocols.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/startup_helper.h"
 #include "chrome/browser/first_run/first_run.h"
 #include "chrome/browser/first_run/upgrade_util.h"
 #include "chrome/browser/google/google_search_counter.h"
-#include "chrome/browser/google/google_util.h"
 #include "chrome/browser/gpu/gl_string_manager.h"
-#include "chrome/browser/jankometer.h"
+#include "chrome/browser/gpu/three_d_api_observer.h"
 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
 #include "chrome/browser/metrics/field_trial_synchronizer.h"
-#include "chrome/browser/metrics/metrics_log.h"
-#include "chrome/browser/metrics/metrics_service.h"
 #include "chrome/browser/metrics/thread_watcher.h"
 #include "chrome/browser/metrics/tracking_synchronizer.h"
-#include "chrome/browser/metrics/variations/variations_http_header_provider.h"
 #include "chrome/browser/metrics/variations/variations_service.h"
 #include "chrome/browser/nacl_host/nacl_browser_delegate_impl.h"
 #include "chrome/browser/net/chrome_net_log.h"
 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h"
 #include "chrome/browser/process_singleton.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_impl.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/profiles/profiles_state.h"
 #include "chrome/browser/shell_integration.h"
-#include "chrome/browser/three_d_api_observer.h"
-#include "chrome/browser/translate/translate_manager.h"
+#include "chrome/browser/translate/translate_service.h"
 #include "chrome/browser/ui/app_list/app_list_service.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/host_desktop.h"
+#include "chrome/browser/ui/startup/bad_flags_prompt.h"
 #include "chrome/browser/ui/startup/default_browser_prompt.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
 #include "chrome/browser/ui/uma_browsing_activity_observer.h"
-#include "chrome/browser/ui/user_data_dir_dialog.h"
 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
-#include "chrome/browser/user_data_dir_extractor.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_result_codes.h"
 #include "chrome/common/logging_chrome.h"
 #include "chrome/common/net/net_resource_provider.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/common/profile_management_switches.h"
 #include "chrome/common/profiling.h"
 #include "chrome/installer/util/google_update_settings.h"
+#include "components/google/core/browser/google_util.h"
 #include "components/language_usage_metrics/language_usage_metrics.h"
+#include "components/metrics/metrics_service.h"
 #include "components/nacl/browser/nacl_browser.h"
-#include "components/nacl/browser/nacl_process_host.h"
+#include "components/rappor/rappor_service.h"
+#include "components/signin/core/common/profile_management_switches.h"
 #include "components/startup_metric_utils/startup_metric_utils.h"
+#include "components/translate/content/common/cld_data_source.h"
+#include "components/translate/core/browser/translate_download_manager.h"
+#include "components/variations/variations_http_header_provider.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/main_function_params.h"
+#include "extensions/browser/extension_protocols.h"
 #include "grit/app_locale_settings.h"
 #include "grit/browser_resources.h"
 #include "grit/chromium_strings.h"
 #include "ui/base/layout.h"
 #include "ui/base/resource/resource_bundle.h"
 
+#if defined(OS_ANDROID)
+#include "chrome/browser/metrics/thread_watcher_android.h"
+#else
+#include "chrome/browser/feedback/feedback_profile_observer.h"
+#endif
+
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
 #include "chrome/browser/first_run/upgrade_util_linux.h"
 #include "chrome/browser/sxs_linux.h"
 #include "base/win/windows_version.h"
 #include "chrome/browser/browser_util_win.h"
 #include "chrome/browser/chrome_browser_main_win.h"
+#include "chrome/browser/chrome_select_file_dialog_factory_win.h"
+#include "chrome/browser/component_updater/sw_reporter_installer_win.h"
 #include "chrome/browser/first_run/try_chrome_dialog_view.h"
 #include "chrome/browser/first_run/upgrade_util_win.h"
 #include "chrome/browser/ui/network_profile_bubble.h"
-#include "chrome/common/net/url_fixer_upper.h"
 #include "chrome/installer/util/helper.h"
 #include "chrome/installer/util/install_util.h"
 #include "chrome/installer/util/shell_util.h"
 #include "net/base/net_util.h"
-#include "printing/printed_document.h"
 #include "ui/base/l10n/l10n_util_win.h"
 #include "ui/gfx/win/dpi.h"
+#include "ui/shell_dialogs/select_file_dialog.h"
 #endif  // defined(OS_WIN)
 
 #if defined(OS_MACOSX)
 #include "chrome/browser/mac/keystone_glue.h"
 #endif
 
+#if !defined(DISABLE_NACL)
+#include "components/nacl/browser/nacl_process_host.h"
+#endif
+
+#if defined(ENABLE_FULL_PRINTING) && !defined(OFFICIAL_BUILD)
+#include "printing/printed_document.h"
+#endif
+
 #if defined(ENABLE_RLZ)
 #include "chrome/browser/rlz/rlz.h"
 #endif
 
-#if defined(TOOLKIT_VIEWS)
-#include "ui/views/focus/accelerator_handler.h"
+#if defined(ENABLE_WEBRTC)
+#include "chrome/browser/media/webrtc_log_util.h"
 #endif
 
 #if defined(USE_AURA)
@@ -246,10 +257,10 @@ PrefService* InitializeLocalState(
     // language the user selected when downloading the installer. This
     // becomes our default language in the prefs.
     // Other platforms obey the system locale.
-    std::wstring install_lang;
+    base::string16 install_lang;
     if (GoogleUpdateSettings::GetLanguage(&install_lang)) {
       local_state->SetString(prefs::kApplicationLocale,
-                             WideToASCII(install_lang));
+                             base::UTF16ToASCII(install_lang));
     }
   }
 #endif  // defined(OS_WIN)
@@ -332,6 +343,13 @@ Profile* CreatePrimaryProfile(const content::MainFunctionParams& parameters,
 #else
   base::FilePath profile_path =
       GetStartupProfilePath(user_data_dir, parsed_command_line);
+
+  // Without NewAvatarMenu, replace guest with any existing profile.
+  if (!switches::IsNewAvatarMenu() &&
+      profile_path == ProfileManager::GetGuestProfilePath()) {
+    profile_path = g_browser_process->profile_manager()->GetProfileInfoCache().
+        GetPathOfProfileAtIndex(0);
+  }
   profile = g_browser_process->profile_manager()->GetProfile(
       profile_path);
 
@@ -372,7 +390,7 @@ OSStatus KeychainCallback(SecKeychainEvent keychain_event,
 }
 #endif
 
-void RegisterComponentsForUpdate(const CommandLine& command_line) {
+void RegisterComponentsForUpdate() {
   component_updater::ComponentUpdateService* cus =
       g_browser_process->component_updater();
 
@@ -383,22 +401,36 @@ void RegisterComponentsForUpdate(const CommandLine& command_line) {
   RegisterRecoveryComponent(cus, g_browser_process->local_state());
   RegisterPepperFlashComponent(cus);
   RegisterSwiftShaderComponent(cus);
+  RegisterWidevineCdmComponent(cus);
+  g_browser_process->pnacl_component_installer()->RegisterPnaclComponent(cus);
 #endif
 
-#if !defined(OS_ANDROID)
-  g_browser_process->pnacl_component_installer()->RegisterPnaclComponent(
-      cus, command_line);
+  if (translate::CldDataSource::ShouldRegisterForComponentUpdates()) {
+    RegisterCldComponent(cus);
+  }
+
+  base::FilePath path;
+  if (PathService::Get(chrome::DIR_USER_DATA, &path)) {
+#if defined(OS_ANDROID)
+    // The CRLSet component was enabled for some releases. This code attempts to
+    // delete it from the local disk of those how may have downloaded it.
+    g_browser_process->crl_set_fetcher()->DeleteFromDisk(path);
+#elif !defined(OS_CHROMEOS)
+    // CRLSetFetcher attempts to load a CRL set from either the local disk or
+    // network.
+    // For Chrome OS this registration is delayed until user login.
+    g_browser_process->crl_set_fetcher()->StartInitialLoad(cus, path);
 #endif
+  }
 
-#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
-  RegisterWidevineCdmComponent(cus);
+#if !defined(OS_ANDROID)
+  // Android does not currently have the EV indicator. No need to get the
+  // EV certs whitelist on Android, then.
+  RegisterEVWhitelistComponent(cus);
 #endif
 
-#if !defined(OS_CHROMEOS)
-  // CRLSetFetcher attempts to load a CRL set from either the local disk or
-  // network.
-  if (!command_line.HasSwitch(switches::kDisableCRLSets))
-    g_browser_process->crl_set_fetcher()->StartInitialLoad(cus);
+#if defined(OS_WIN)
+  ExecutePendingSwReporter(cus, g_browser_process->local_state());
 #endif
 
   cus->Start();
@@ -432,27 +464,6 @@ bool ProcessSingletonNotificationCallback(
   g_browser_process->platform_part()->PlatformSpecificCommandLineProcessing(
       command_line);
 
-  // TODO(erikwright): Consider removing this - AFAIK it is no longer used.
-  // Handle the --uninstall-extension startup action. This needs to done here in
-  // the process that is running with the target profile, otherwise the
-  // uninstall will fail to unload and remove all components.
-  if (command_line.HasSwitch(switches::kUninstallExtension)) {
-    // The uninstall extension switch can't be combined with the profile
-    // directory switch.
-    DCHECK(!command_line.HasSwitch(switches::kProfileDirectory));
-
-    Profile* profile = ProfileManager::GetLastUsedProfile();
-    if (!profile) {
-      // We should never be called before the profile has been created.
-      NOTREACHED();
-      return true;
-    }
-
-    extensions::StartupHelper extension_startup_helper;
-    extension_startup_helper.UninstallExtension(command_line, profile);
-    return true;
-  }
-
   base::FilePath user_data_dir =
       g_browser_process->profile_manager()->user_data_dir();
   base::FilePath startup_profile_dir =
@@ -469,17 +480,11 @@ void LaunchDevToolsHandlerIfNeeded(const CommandLine& command_line) {
     std::string port_str =
         command_line.GetSwitchValueASCII(::switches::kRemoteDebuggingPort);
     int port;
-    if (base::StringToInt(port_str, &port) && port > 0 && port < 65535) {
-      std::string frontend_str;
-      if (command_line.HasSwitch(::switches::kRemoteDebuggingFrontend)) {
-        frontend_str = command_line.GetSwitchValueASCII(
-            ::switches::kRemoteDebuggingFrontend);
-      }
+    if (base::StringToInt(port_str, &port) && port >= 0 && port < 65535) {
       g_browser_process->CreateDevToolsHttpProtocolHandler(
           chrome::HOST_DESKTOP_TYPE_NATIVE,
           "127.0.0.1",
-          port,
-          frontend_str);
+          port);
     } else {
       DLOG(WARNING) << "Invalid http debugger port number " << port;
     }
@@ -511,24 +516,22 @@ class LoadCompleteListener : public content::NotificationObserver {
   DISALLOW_COPY_AND_ASSIGN(LoadCompleteListener);
 };
 
-void InitializeAllPrefHashStores() {
-  ProfileInfoCache& profile_info_cache =
-      g_browser_process->profile_manager()->GetProfileInfoCache();
-  size_t n_profiles = profile_info_cache.GetNumberOfProfiles();
-  for (size_t i = 0; i < n_profiles; ++i) {
-    base::FilePath profile_path =
-        profile_info_cache.GetPathOfProfileAtIndex(i);
-    ProfileImpl::InitializePrefHashStoreIfRequired(profile_path);
-  }
-}
 }  // namespace
 
 namespace chrome_browser {
+
 // This error message is not localized because we failed to load the
 // localization data files.
+#if defined(OS_WIN)
 const char kMissingLocaleDataTitle[] = "Missing File Error";
+#endif
+
+#if defined(OS_WIN)
+// TODO(port) This should be used on Linux Aura as well. http://crbug.com/338969
 const char kMissingLocaleDataMessage[] =
     "Unable to find locale data files. Please reinstall.";
+#endif
+
 }  // namespace chrome_browser
 
 // BrowserMainParts ------------------------------------------------------------
@@ -546,7 +549,6 @@ ChromeBrowserMainParts::ChromeBrowserMainParts(
       shutdown_watcher_(new ShutdownWatcherHelper()),
       startup_timer_(new performance_monitor::StartupTimer()),
       browser_field_trials_(parameters.command_line),
-      translate_manager_(NULL),
       profile_(NULL),
       run_message_loop_(true),
       notify_result_(ProcessSingleton::PROCESS_NONE),
@@ -575,42 +577,38 @@ void ChromeBrowserMainParts::SetupMetricsAndFieldTrials() {
   // Must initialize metrics after labs have been converted into switches,
   // but before field trials are set up (so that client ID is available for
   // one-time randomized field trials).
-#if defined(ARCH_CPU_64_BITS)
-  MetricsLog::set_version_extension("-64");
-#endif  // defined(ARCH_CPU_64_BITS)
 
   // Initialize FieldTrialList to support FieldTrials that use one-time
   // randomization.
   MetricsService* metrics = browser_process_->metrics_service();
-  MetricsService::ReportingState reporting_state =
-      IsMetricsReportingEnabled() ? MetricsService::REPORTING_ENABLED :
-                                    MetricsService::REPORTING_DISABLED;
-  if (reporting_state == MetricsService::REPORTING_ENABLED)
-    metrics->ForceClientIdCreation();  // Needed below.
   field_trial_list_.reset(
-      new base::FieldTrialList(
-          metrics->CreateEntropyProvider(reporting_state).release()));
+      new base::FieldTrialList(metrics->CreateEntropyProvider().release()));
 
   const CommandLine* command_line = CommandLine::ForCurrentProcess();
   if (command_line->HasSwitch(switches::kEnableBenchmarking))
     base::FieldTrial::EnableBenchmarking();
 
   // Ensure any field trials specified on the command line are initialized.
-  // Also stop the metrics service so that we don't pollute UMA.
   if (command_line->HasSwitch(switches::kForceFieldTrials)) {
+    std::set<std::string> unforceable_field_trials;
+#if defined(OFFICIAL_BUILD)
+    unforceable_field_trials.insert("SettingsEnforcement");
+#endif  // defined(OFFICIAL_BUILD)
+
     // Create field trials without activating them, so that this behaves in a
     // consistent manner with field trials created from the server.
     bool result = base::FieldTrialList::CreateTrialsFromString(
         command_line->GetSwitchValueASCII(switches::kForceFieldTrials),
-        base::FieldTrialList::DONT_ACTIVATE_TRIALS);
+        base::FieldTrialList::DONT_ACTIVATE_TRIALS,
+        unforceable_field_trials);
     CHECK(result) << "Invalid --" << switches::kForceFieldTrials
                   << " list specified.";
   }
   if (command_line->HasSwitch(switches::kForceVariationIds)) {
     // Create default variation ids which will always be included in the
     // X-Client-Data request header.
-    chrome_variations::VariationsHttpHeaderProvider* provider =
-        chrome_variations::VariationsHttpHeaderProvider::GetInstance();
+    variations::VariationsHttpHeaderProvider* provider =
+        variations::VariationsHttpHeaderProvider::GetInstance();
     bool result = provider->SetDefaultVariationIds(
         command_line->GetSwitchValueASCII(switches::kForceVariationIds));
     CHECK(result) << "Invalid --" << switches::kForceVariationIds
@@ -621,8 +619,9 @@ void ChromeBrowserMainParts::SetupMetricsAndFieldTrials() {
   if (variations_service)
     variations_service->CreateTrialsFromSeed();
 
-  // This must be called after the local state is initialized.
-  browser_field_trials_.SetupFieldTrials(local_state_);
+  // This must be called after |local_state_| is initialized.
+  browser_field_trials_.SetupFieldTrials(
+      base::Time::FromTimeT(metrics->GetInstallDate()), local_state_);
 
   // Initialize FieldTrialSynchronizer system. This is a singleton and is used
   // for posting tasks via base::Bind. Its deleted when it goes out of scope.
@@ -631,7 +630,7 @@ void ChromeBrowserMainParts::SetupMetricsAndFieldTrials() {
   field_trial_synchronizer_ = new FieldTrialSynchronizer();
 
   // Now that field trials have been created, initializes metrics recording.
-  metrics->InitializeMetricsRecordingState(reporting_state);
+  metrics->InitializeMetricsRecordingState();
 }
 
 // ChromeBrowserMainParts: |SetupMetricsAndFieldTrials()| related --------------
@@ -650,32 +649,15 @@ void ChromeBrowserMainParts::StartMetricsRecording() {
     return;
   }
 
-  if (IsMetricsReportingEnabled())
-    metrics->Start();
-}
-
-bool ChromeBrowserMainParts::IsMetricsReportingEnabled() {
-  // If the user permits metrics reporting with the checkbox in the
-  // prefs, we turn on recording.  We disable metrics completely for
-  // non-official builds.  This can be forced with a flag.
-  const CommandLine* command_line = CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(switches::kEnableMetricsReportingForTesting))
-    return true;
-
-  bool enabled = false;
-  // The debug build doesn't send UMA logs when FieldTrials are forced.
-  if (command_line->HasSwitch(switches::kForceFieldTrials))
-    return false;
-
-#if defined(GOOGLE_CHROME_BUILD)
-#if defined(OS_CHROMEOS)
-  chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref,
-                                            &enabled);
-#else
-  enabled = local_state_->GetBoolean(prefs::kMetricsReportingEnabled);
-#endif  // #if defined(OS_CHROMEOS)
-#endif  // defined(GOOGLE_CHROME_BUILD)
-  return enabled;
+  metrics->CheckForClonedInstall(
+      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
+  const bool metrics_enabled = metrics->StartIfMetricsReportingEnabled();
+  // TODO(asvitkine): Since this function is not run on Android, RAPPOR is
+  // currently disabled there. http://crbug.com/370041
+  browser_process_->rappor_service()->Start(
+      browser_process_->local_state(),
+      browser_process_->system_request_context(),
+      metrics_enabled);
 }
 
 void ChromeBrowserMainParts::RecordBrowserStartupTime() {
@@ -768,13 +750,13 @@ void ChromeBrowserMainParts::PostMainMessageLoopStart() {
 int ChromeBrowserMainParts::PreCreateThreads() {
   TRACE_EVENT0("startup", "ChromeBrowserMainParts::PreCreateThreads");
   result_code_ = PreCreateThreadsImpl();
-  // These members must be initialized before returning from this function.
+
+  if (result_code_ == content::RESULT_CODE_NORMAL_EXIT) {
 #if !defined(OS_ANDROID)
-  DCHECK(master_prefs_.get());
-  DCHECK(browser_creator_.get());
+    // These members must be initialized before exiting this function normally.
+    DCHECK(master_prefs_.get());
+    DCHECK(browser_creator_.get());
 #endif
-
-  if (result_code_ == 0) {
     for (size_t i = 0; i < chrome_extra_parts_.size(); ++i)
       chrome_extra_parts_[i]->PreCreateThreads();
   }
@@ -785,11 +767,11 @@ int ChromeBrowserMainParts::PreCreateThreads() {
 int ChromeBrowserMainParts::PreCreateThreadsImpl() {
   TRACE_EVENT0("startup", "ChromeBrowserMainParts::PreCreateThreadsImpl")
   run_message_loop_ = false;
-  {
-    TRACE_EVENT0("startup",
-      "ChromeBrowserMainParts::PreCreateThreadsImpl:GetUserDataDir");
-    user_data_dir_ = chrome::GetUserDataDir(parameters());
-  }
+#if !defined(OS_ANDROID)
+  chrome::MaybeShowInvalidUserDataDirWarningDialog();
+#endif
+  if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir_))
+    return chrome::RESULT_CODE_MISSING_DATA;
 
   // Force MediaCaptureDevicesDispatcher to be created on UI thread.
   MediaCaptureDevicesDispatcher::GetInstance();
@@ -873,53 +855,45 @@ int ChromeBrowserMainParts::PreCreateThreadsImpl() {
   // just changed it to include experiments.
   crash_keys::SetSwitchesFromCommandLine(CommandLine::ForCurrentProcess());
 
-  // If we're running tests (ui_task is non-null), then the ResourceBundle
-  // has already been initialized.
-  if (parameters().ui_task &&
-      !local_state_->IsManagedPreference(prefs::kApplicationLocale)) {
-    browser_process_->SetApplicationLocale("en-US");
-  } else {
-    // Mac starts it earlier in |PreMainMessageLoopStart()| (because it is
-    // needed when loading the MainMenu.nib and the language doesn't depend on
-    // anything since it comes from Cocoa.
+  // Mac starts it earlier in |PreMainMessageLoopStart()| (because it is
+  // needed when loading the MainMenu.nib and the language doesn't depend on
+  // anything since it comes from Cocoa.
 #if defined(OS_MACOSX)
-    browser_process_->SetApplicationLocale(l10n_util::GetLocaleOverride());
+  std::string locale =
+      parameters().ui_task ? "en-US" : l10n_util::GetLocaleOverride();
+  browser_process_->SetApplicationLocale(locale);
 #else
-    const std::string locale =
-        local_state_->GetString(prefs::kApplicationLocale);
-
-    // On a POSIX OS other than ChromeOS, the parameter that is passed to the
-    // method InitSharedInstance is ignored.
-
-    TRACE_EVENT_BEGIN0("startup",
-        "ChromeBrowserMainParts::PreCreateThreadsImpl:InitResourceBundle");
-    const std::string loaded_locale =
-        ResourceBundle::InitSharedInstanceWithLocale(locale, NULL);
-    TRACE_EVENT_END0("startup",
-        "ChromeBrowserMainParts::PreCreateThreadsImpl:InitResourceBundle");
-
-    if (loaded_locale.empty() &&
-        !parsed_command_line().HasSwitch(switches::kNoErrorDialogs)) {
-      ShowMissingLocaleMessageBox();
-      return chrome::RESULT_CODE_MISSING_DATA;
-    }
-    CHECK(!loaded_locale.empty()) << "Locale could not be found for " << locale;
-    browser_process_->SetApplicationLocale(loaded_locale);
-
-    base::FilePath resources_pack_path;
-    PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path);
-    {
-      TRACE_EVENT0("startup",
-          "ChromeBrowserMainParts::PreCreateThreadsImpl:AddDataPack");
-      ResourceBundle::GetSharedInstance().AddDataPackFromPath(
-          resources_pack_path, ui::SCALE_FACTOR_NONE);
-    }
-#endif  // defined(OS_MACOSX)
+  const std::string locale =
+      local_state_->GetString(prefs::kApplicationLocale);
+
+  // On a POSIX OS other than ChromeOS, the parameter that is passed to the
+  // method InitSharedInstance is ignored.
+
+  TRACE_EVENT_BEGIN0("startup",
+      "ChromeBrowserMainParts::PreCreateThreadsImpl:InitResourceBundle");
+  const std::string loaded_locale =
+      ui::ResourceBundle::InitSharedInstanceWithLocale(
+          locale, NULL, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
+  TRACE_EVENT_END0("startup",
+      "ChromeBrowserMainParts::PreCreateThreadsImpl:InitResourceBundle");
+
+  if (loaded_locale.empty() &&
+      !parsed_command_line().HasSwitch(switches::kNoErrorDialogs)) {
+    ShowMissingLocaleMessageBox();
+    return chrome::RESULT_CODE_MISSING_DATA;
   }
+  CHECK(!loaded_locale.empty()) << "Locale could not be found for " << locale;
+  browser_process_->SetApplicationLocale(loaded_locale);
 
-#if defined(TOOLKIT_GTK)
-  g_set_application_name(l10n_util::GetStringUTF8(IDS_PRODUCT_NAME).c_str());
-#endif
+  base::FilePath resources_pack_path;
+  PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path);
+  {
+    TRACE_EVENT0("startup",
+        "ChromeBrowserMainParts::PreCreateThreadsImpl:AddDataPack");
+    ResourceBundle::GetSharedInstance().AddDataPackFromPath(
+        resources_pack_path, ui::SCALE_FACTOR_NONE);
+  }
+#endif  // defined(OS_MACOSX)
 
   // Android does first run in Java instead of native.
   // Chrome OS has its own out-of-box-experience code.
@@ -942,7 +916,7 @@ int ChromeBrowserMainParts::PreCreateThreadsImpl() {
 
     // TODO(macourteau): refactor preferences that are copied from
     // master_preferences into local_state, as a "local_state" section in
-    // master preferences. If possible, a generic solution would be prefered
+    // master preferences. If possible, a generic solution would be preferred
     // over a copy one-by-one of specific preferences. Also see related TODO
     // in first_run.h.
 
@@ -982,13 +956,6 @@ int ChromeBrowserMainParts::PreCreateThreadsImpl() {
   // Initialize tracking synchronizer system.
   tracking_synchronizer_ = new chrome_browser_metrics::TrackingSynchronizer();
 
-  // Now that all preferences have been registered, set the install date
-  // for the uninstall metrics if this is our first run. This only actually
-  // gets used if the user has metrics reporting enabled at uninstall time.
-  int64 install_date = local_state_->GetInt64(prefs::kInstallDate);
-  if (install_date == 0)
-    local_state_->SetInt64(prefs::kInstallDate, base::Time::Now().ToTimeT());
-
 #if defined(OS_MACOSX)
   // Get the Keychain API to register for distributed notifications on the main
   // thread, which has a proper CFRunloop, instead of later on the I/O thread,
@@ -1042,6 +1009,10 @@ void ChromeBrowserMainParts::PreProfileInit() {
     chrome_extra_parts_[i]->PreProfileInit();
 
 #if !defined(OS_ANDROID)
+  // Initialize the feedback uploader so it can setup notifications for profile
+  // creation.
+  feedback::FeedbackProfileObserver::Initialize();
+
   ProfileManager* profile_manager = g_browser_process->profile_manager();
 
   // First check if any ephemeral profiles are left behind because of browser
@@ -1050,13 +1021,13 @@ void ChromeBrowserMainParts::PreProfileInit() {
   ProfileInfoCache& profile_cache = profile_manager->GetProfileInfoCache();
   size_t profiles_count = profile_cache.GetNumberOfProfiles();
   std::vector<base::FilePath> profiles_to_delete;
-  for (size_t i = 0;i < profiles_count; ++i) {
+  for (size_t i = 0; i < profiles_count; ++i) {
     if (profile_cache.ProfileIsEphemeralAtIndex(i))
       profiles_to_delete.push_back(profile_cache.GetPathOfProfileAtIndex(i));
   }
 
   if (profiles_to_delete.size()) {
-    for (size_t i = 0;i < profiles_to_delete.size(); ++i) {
+    for (size_t i = 0; i < profiles_to_delete.size(); ++i) {
       profile_manager->ScheduleProfileForDeletion(
           profiles_to_delete[i], ProfileManager::CreateCallback());
     }
@@ -1091,6 +1062,15 @@ void ChromeBrowserMainParts::PostBrowserStart() {
   // Allow ProcessSingleton to process messages.
   process_singleton_->Unlock();
 #endif
+#if defined(ENABLE_WEBRTC)
+  // Set up a task to delete old WebRTC log files for all profiles. Use a delay
+  // to reduce the impact on startup time.
+  BrowserThread::PostDelayedTask(
+      BrowserThread::UI,
+      FROM_HERE,
+      base::Bind(&WebRtcLogUtil::DeleteOldWebRtcLogFilesForAllProfiles),
+      base::TimeDelta::FromMinutes(1));
+#endif
 }
 
 int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
@@ -1130,6 +1110,9 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
     return ChromeBrowserMainPartsWin::HandleIconsCommands(
         parsed_command_line_);
   }
+
+  ui::SelectFileDialog::SetFactory(new ChromeSelectFileDialogFactory(
+      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
 #endif
 
   if (parsed_command_line().HasSwitch(switches::kMakeDefaultBrowser)) {
@@ -1139,9 +1122,8 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
   }
 
 #if defined(USE_AURA)
-  // Env creates the compositor. Aura widgets need the compositor to be created
-  // before they can be initialized by the browser.
-  aura::Env::CreateInstance();
+  // Make sure aura::Env has been initialized.
+  CHECK(aura::Env::GetInstance());
 #endif
 
   // Android doesn't support extensions and doesn't implement ProcessSingleton.
@@ -1166,9 +1148,6 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
     // 20 seconds to respond. Note that this needs to be done before we attempt
     // to read the profile.
     notify_result_ = process_singleton_->NotifyOtherProcessOrCreate();
-    UMA_HISTOGRAM_ENUMERATION("NotifyOtherProcessOrCreate.Result",
-                               notify_result_,
-                               ProcessSingleton::NUM_NOTIFY_RESULTS);
     switch (notify_result_) {
       case ProcessSingleton::PROCESS_NONE:
         // No process already running, fall through to starting a new one.
@@ -1202,17 +1181,10 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
         NOTREACHED();
     }
   }
-
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
-  if (sxs_linux::ShouldMigrateUserDataDir())
-    return sxs_linux::MigrateUserDataDir();
-#endif  // defined(OS_LINUX) && !defined(OS_CHROMEOS)
-
-  first_run::CreateSentinelIfNeeded();
 #endif  // !defined(OS_ANDROID)
 
-  // Desktop construction occurs here, (required before profile creation).
-  PreProfileInit();
+  // Handle special early return paths (which couldn't be processed even earlier
+  // as they require the process singleton to be held) first.
 
   std::string try_chrome =
       parsed_command_line().GetSwitchValueASCII(switches::kTryChromeAgain);
@@ -1245,15 +1217,45 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
 #endif  // defined(OS_WIN)
   }
 
+#if defined(OS_WIN)
+  // Do the tasks if chrome has been upgraded while it was last running.
+  if (!already_running && upgrade_util::DoUpgradeTasks(parsed_command_line()))
+    return content::RESULT_CODE_NORMAL_EXIT;
+
+  // Check if there is any machine level Chrome installed on the current
+  // machine. If yes and the current Chrome process is user level, we do not
+  // allow the user level Chrome to run. So we notify the user and uninstall
+  // user level Chrome.
+  // Note this check needs to happen here (after the process singleton was
+  // obtained but before potentially creating the first run sentinel).
+  if (ChromeBrowserMainPartsWin::CheckMachineLevelInstall())
+    return chrome::RESULT_CODE_MACHINE_LEVEL_INSTALL_EXISTS;
+#endif  // defined(OS_WIN)
+
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+  if (sxs_linux::ShouldMigrateUserDataDir())
+    return sxs_linux::MigrateUserDataDir();
+#endif  // defined(OS_LINUX) && !defined(OS_CHROMEOS)
+
+  // Desktop construction occurs here, (required before profile creation).
+  PreProfileInit();
+
   // Profile creation ----------------------------------------------------------
 
-  MetricsService::SetExecutionPhase(MetricsService::CREATE_PROFILE);
+  MetricsService::SetExecutionPhase(MetricsService::CREATE_PROFILE,
+                                    g_browser_process->local_state());
   profile_ = CreatePrimaryProfile(parameters(),
                                   user_data_dir_,
                                   parsed_command_line());
   if (!profile_)
     return content::RESULT_CODE_NORMAL_EXIT;
 
+#if !defined(OS_ANDROID)
+  // The first run sentinel must be created after the process singleton was
+  // grabbed and no early return paths were otherwise hit above.
+  first_run::CreateSentinelIfNeeded();
+#endif  // !defined(OS_ANDROID)
+
 #if defined(ENABLE_BACKGROUND)
   // Autoload any profiles which are running background apps.
   // TODO(rlp): Do this on a separate thread. See http://crbug.com/99075.
@@ -1261,25 +1263,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
 #endif
   // Post-profile init ---------------------------------------------------------
 
-#if defined(OS_WIN)
-  // Do the tasks if chrome has been upgraded while it was last running.
-  if (!already_running && upgrade_util::DoUpgradeTasks(parsed_command_line()))
-    return content::RESULT_CODE_NORMAL_EXIT;
-
-  // Check if there is any machine level Chrome installed on the current
-  // machine. If yes and the current Chrome process is user level, we do not
-  // allow the user level Chrome to run. So we notify the user and uninstall
-  // user level Chrome.
-  // Note this check should only happen here, after all the checks above
-  // (uninstall, resource bundle initialization, other chrome browser
-  // processes etc).
-  if (ChromeBrowserMainPartsWin::CheckMachineLevelInstall())
-    return chrome::RESULT_CODE_MACHINE_LEVEL_INSTALL_EXISTS;
-#endif
-
-  // Create the TranslateManager singleton.
-  translate_manager_ = TranslateManager::GetInstance();
-  DCHECK(translate_manager_ != NULL);
+  TranslateService::Initialize();
 
   // Needs to be done before PostProfileInit, since login manager on CrOS is
   // called inside PostProfileInit.
@@ -1289,8 +1273,8 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
   // NaClBrowserDelegateImpl is accessed inside PostProfileInit().
   // So make sure to create it before that.
 #if !defined(DISABLE_NACL)
-  NaClBrowserDelegateImpl* delegate = new NaClBrowserDelegateImpl(
-    extensions::ExtensionSystem::Get(profile_)->info_map());
+  NaClBrowserDelegateImpl* delegate =
+      new NaClBrowserDelegateImpl(browser_process_->profile_manager());
   nacl::NaClBrowser::SetDelegate(delegate);
 #endif
 
@@ -1352,7 +1336,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
   // Verify that the profile is not on a network share and if so prepare to show
   // notification to the user.
   if (NetworkProfileBubble::ShouldCheckNetworkProfile(profile_)) {
-    content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
+    BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
         base::Bind(&NetworkProfileBubble::CheckNetworkProfile,
                    profile_->GetPath()));
   }
@@ -1389,26 +1373,31 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
   browser_process_->intranet_redirect_detector();
   GoogleSearchCounter::RegisterForNotifications();
 
-  if (parsed_command_line().HasSwitch(switches::kEnableSdch)) {
-    // SDCH options via switches::kEnableSdch include:
-    const int kSdchDisabled = 0;
-    const int kSdchOverHttpEnabled = 1;
-    const int kSdchOverBothHttpAndHttpsEnabled = 2;
-    int sdch_enabled = kSdchOverHttpEnabled;
-    if (base::StringToInt(parsed_command_line().GetSwitchValueASCII(
-            switches::kEnableSdch), &sdch_enabled)) {
-      if (sdch_enabled == kSdchDisabled) {
-        net::SdchManager::EnableSdchSupport(false);
-      } else if (sdch_enabled == kSdchOverBothHttpAndHttpsEnabled) {
-        net::SdchManager::EnableSecureSchemeSupport(true);
-      }
+  if (parsed_command_line().HasSwitch(switches::kEnableSdchOverHttps)) {
+    net::SdchManager::EnableSecureSchemeSupport(true);
+  } else {
+    // Check SDCH field trial.
+    const char kSdchFieldTrialName[] = "SDCH";
+    const char kEnabledAllGroupName[] = "EnabledAll";
+    const char kEnabledHttpOnlyGroupName[] = "EnabledHttpOnly";
+    const char kDisabledAllGroupName[] = "DisabledAll";
+
+    // Store in a string on return to keep underlying storage for
+    // StringPiece stable.
+    std::string sdch_trial_group_string =
+        base::FieldTrialList::FindFullName(kSdchFieldTrialName);
+    base::StringPiece sdch_trial_group(sdch_trial_group_string);
+    if (sdch_trial_group.starts_with(kEnabledAllGroupName)) {
+      net::SdchManager::EnableSecureSchemeSupport(true);
+      net::SdchManager::EnableSdchSupport(true);
+    } else if (sdch_trial_group.starts_with(kEnabledHttpOnlyGroupName)) {
+      net::SdchManager::EnableSdchSupport(true);
+    } else if (sdch_trial_group.starts_with(kDisabledAllGroupName)) {
+      net::SdchManager::EnableSdchSupport(false);
     }
   }
 
-  if (parsed_command_line().HasSwitch(switches::kEnableWatchdog))
-    InstallJankometer(parsed_command_line());
-
-#if defined(OS_WIN) && !defined(GOOGLE_CHROME_BUILD)
+#if defined(ENABLE_FULL_PRINTING) && !defined(OFFICIAL_BUILD)
   if (parsed_command_line().HasSwitch(switches::kDebugPrint)) {
     base::FilePath path =
         parsed_command_line().GetSwitchValuePath(switches::kDebugPrint);
@@ -1425,21 +1414,11 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
   language_usage_metrics::LanguageUsageMetrics::RecordApplicationLanguage(
       browser_process_->GetApplicationLocale());
 
-  // The extension service may be available at this point. If the command line
-  // specifies --uninstall-extension, attempt the uninstall extension startup
-  // action.
-  if (parsed_command_line().HasSwitch(switches::kUninstallExtension)) {
-    extensions::StartupHelper extension_startup_helper;
-    if (extension_startup_helper.UninstallExtension(
-            parsed_command_line(), profile_))
-      return content::RESULT_CODE_NORMAL_EXIT;
-    return chrome::RESULT_CODE_UNINSTALL_EXTENSION_ERROR;
-  }
-
   // Start watching for hangs during startup. We disarm this hang detector when
   // ThreadWatcher takes over or when browser is shutdown or when
   // startup_watcher_ is deleted.
-  MetricsService::SetExecutionPhase(MetricsService::STARTUP_TIMEBOMB_ARM);
+  MetricsService::SetExecutionPhase(MetricsService::STARTUP_TIMEBOMB_ARM,
+                                    g_browser_process->local_state());
   startup_watcher_->Arm(base::TimeDelta::FromSeconds(300));
 
   // On mobile, need for clean shutdown arises only when the application comes
@@ -1447,7 +1426,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
   // http://crbug.com/179143
 #if !defined(OS_ANDROID)
   // Start watching for a hang.
-  MetricsService::LogNeedForCleanShutdown();
+  MetricsService::LogNeedForCleanShutdown(g_browser_process->local_state());
 #endif
 
 #if defined(ENABLE_FULL_PRINTING)
@@ -1461,18 +1440,17 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
 #endif
 
   // Start watching all browser threads for responsiveness.
-  MetricsService::SetExecutionPhase(MetricsService::THREAD_WATCHER_START);
+  MetricsService::SetExecutionPhase(MetricsService::THREAD_WATCHER_START,
+                                    g_browser_process->local_state());
   ThreadWatcherList::StartWatchingAll(parsed_command_line());
 
-#if !defined(DISABLE_NACL)
-  if (parsed_command_line().HasSwitch(switches::kPnaclDir)) {
-    PathService::Override(chrome::DIR_PNACL_BASE,
-                          parsed_command_line().GetSwitchValuePath(
-                              switches::kPnaclDir));
-  }
+#if defined(OS_ANDROID)
+  ThreadWatcherAndroid::RegisterApplicationStatusListener();
+#endif
 
-  content::BrowserThread::PostTask(
-      content::BrowserThread::IO,
+#if !defined(DISABLE_NACL)
+  BrowserThread::PostTask(
+      BrowserThread::IO,
       FROM_HERE,
       base::Bind(nacl::NaClProcessHost::EarlyStartup));
 #endif
@@ -1489,13 +1467,18 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
   browser_process_->notification_ui_manager();
 
   if (!parsed_command_line().HasSwitch(switches::kDisableComponentUpdate))
-    RegisterComponentsForUpdate(parsed_command_line());
+    RegisterComponentsForUpdate();
 
 #if defined(OS_ANDROID)
   chrome_variations::VariationsService* variations_service =
       browser_process_->variations_service();
-  if (variations_service)
+  if (variations_service) {
+    variations_service->set_policy_pref_service(profile_->GetPrefs());
     variations_service->StartRepeatedVariationsSeedFetch();
+  }
+  translate::TranslateDownloadManager::RequestLanguageList(
+      profile_->GetPrefs());
+
 #else
   // Most general initialization is behind us, but opening a
   // tab and/or session restore and such is still to be done.
@@ -1546,8 +1529,8 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
     UMA_HISTOGRAM_LONG_TIMES_100("Startup.BrowserOpenTabs", delay);
 
     // If we're running tests (ui_task is non-null), then we don't want to
-    // call FetchLanguageListFromTranslateServer or
-    // StartRepeatedVariationsSeedFetch.
+    // call RequestLanguageList or StartRepeatedVariationsSeedFetch or
+    // RequestLanguageList
     if (parameters().ui_task == NULL) {
       // Request new variations seed information from server.
       chrome_variations::VariationsService* variations_service =
@@ -1560,10 +1543,8 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
 #endif
       }
 
-      if (translate_manager_ != NULL) {
-        translate_manager_->FetchLanguageListFromTranslateServer(
-            profile_->GetPrefs());
-      }
+      translate::TranslateDownloadManager::RequestLanguageList(
+          profile_->GetPrefs());
     }
 
     run_message_loop_ = true;
@@ -1577,10 +1558,6 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
 
   PostBrowserStart();
 
-  // Initialize preference hash stores for profiles that haven't been loaded
-  // recently.
-  InitializeAllPrefHashStores();
-
   if (parameters().ui_task) {
     // We end the startup timer here if we have parameters to run, because we
     // never start to run the main loop (where we normally stop the timer).
@@ -1622,16 +1599,12 @@ bool ChromeBrowserMainParts::MainMessageLoopRun(int* result_code) {
       performance_monitor::StartupTimer::STARTUP_NORMAL);
 
   DCHECK(base::MessageLoopForUI::IsCurrent());
-#if !defined(USE_AURA) && defined(TOOLKIT_VIEWS)
-  views::AcceleratorHandler accelerator_handler;
-  base::RunLoop run_loop(&accelerator_handler);
-#else
   base::RunLoop run_loop;
-#endif
 
   performance_monitor::PerformanceMonitor::GetInstance()->StartGatherCycle();
 
-  MetricsService::SetExecutionPhase(MetricsService::MAIN_MESSAGE_LOOP_RUN);
+  MetricsService::SetExecutionPhase(MetricsService::MAIN_MESSAGE_LOOP_RUN,
+                                    g_browser_process->local_state());
   run_loop.Run();
 
   return true;
@@ -1648,7 +1621,8 @@ void ChromeBrowserMainParts::PostMainMessageLoopRun() {
 
   // Start watching for jank during shutdown. It gets disarmed when
   // |shutdown_watcher_| object is destructed.
-  MetricsService::SetExecutionPhase(MetricsService::SHUTDOWN_TIMEBOMB_ARM);
+  MetricsService::SetExecutionPhase(MetricsService::SHUTDOWN_TIMEBOMB_ARM,
+                                    g_browser_process->local_state());
   shutdown_watcher_->Arm(base::TimeDelta::FromSeconds(300));
 
   // Disarm the startup hang detector time bomb if it is still Arm'ed.
@@ -1660,8 +1634,7 @@ void ChromeBrowserMainParts::PostMainMessageLoopRun() {
   // Some tests don't set parameters.ui_task, so they started translate
   // language fetch that was never completed so we need to cleanup here
   // otherwise it will be done by the destructor in a wrong thread.
-  if (parameters().ui_task == NULL && translate_manager_ != NULL)
-    translate_manager_->CleanupPendingUlrFetcher();
+  TranslateService::Shutdown(parameters().ui_task == NULL);
 
   if (notify_result_ == ProcessSingleton::PROCESS_NONE)
     process_singleton_->Cleanup();