Commit 349162b2 authored by Xi Han's avatar Xi Han Committed by Commit Bot

Initialize ResouceBundle in ChromeFeatureListCreator.

In this CL, the entire ResouceBundle is initialized in the
ChromeFeatureListCreator. This prevents loading parts of the data pack
earlier and then add it to the ResouceBundle when the full browser
starts.

Bug: 846846,729596
Change-Id: Ia254252288ead936bde8cb65b12cf2fecbfc106f
Reviewed-on: https://chromium-review.googlesource.com/c/1292516
Commit-Queue: Xi Han <hanxi@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#603067}
parent 871761b6
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include "android_webview/common/crash_reporter/aw_crash_reporter_client.h" #include "android_webview/common/crash_reporter/aw_crash_reporter_client.h"
#include "base/android/apk_assets.h" #include "base/android/apk_assets.h"
#include "base/android/build_info.h" #include "base/android/build_info.h"
#include "base/android/locale_utils.h"
#include "base/android/memory_pressure_listener_android.h" #include "base/android/memory_pressure_listener_android.h"
#include "base/base_paths_android.h" #include "base/base_paths_android.h"
#include "base/command_line.h" #include "base/command_line.h"
...@@ -62,9 +61,6 @@ ...@@ -62,9 +61,6 @@
#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/connector.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/base/layout.h" #include "ui/base/layout.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/resource/resource_bundle_android.h"
#include "ui/base/ui_base_paths.h"
#include "ui/gl/gl_surface.h" #include "ui/gl/gl_surface.h"
namespace { namespace {
...@@ -169,23 +165,6 @@ int AwBrowserMainParts::PreEarlyInitialization() { ...@@ -169,23 +165,6 @@ int AwBrowserMainParts::PreEarlyInitialization() {
} }
int AwBrowserMainParts::PreCreateThreads() { int AwBrowserMainParts::PreCreateThreads() {
ui::SetLocalePaksStoredInApk(true);
std::string locale = ui::ResourceBundle::InitSharedInstanceWithLocale(
base::android::GetDefaultLocaleString(), NULL,
ui::ResourceBundle::LOAD_COMMON_RESOURCES);
if (locale.empty()) {
LOG(WARNING) << "Failed to load locale .pak from the apk. "
"Bringing up WebView without any locale";
}
base::i18n::SetICUDefaultLocale(locale);
// Try to directly mmap the resources.pak from the apk. Fall back to load
// from file, using PATH_SERVICE, otherwise.
base::FilePath pak_file_path;
base::PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &pak_file_path);
pak_file_path = pak_file_path.AppendASCII("resources.pak");
ui::LoadMainAndroidPackFile("assets/resources.pak", pak_file_path);
base::android::MemoryPressureListenerAndroid::Initialize( base::android::MemoryPressureListenerAndroid::Initialize(
base::android::AttachCurrentThread()); base::android::AttachCurrentThread());
::crash_reporter::ChildExitObserver::Create(); ::crash_reporter::ChildExitObserver::Create();
......
...@@ -22,12 +22,14 @@ ...@@ -22,12 +22,14 @@
#include "android_webview/utility/aw_content_utility_client.h" #include "android_webview/utility/aw_content_utility_client.h"
#include "base/android/apk_assets.h" #include "base/android/apk_assets.h"
#include "base/android/build_info.h" #include "base/android/build_info.h"
#include "base/android/locale_utils.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/cpu.h" #include "base/cpu.h"
#include "base/i18n/icu_util.h" #include "base/i18n/icu_util.h"
#include "base/i18n/rtl.h" #include "base/i18n/rtl.h"
#include "base/lazy_instance.h" #include "base/lazy_instance.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "cc/base/switches.h" #include "cc/base/switches.h"
...@@ -52,6 +54,8 @@ ...@@ -52,6 +54,8 @@
#include "media/base/media_switches.h" #include "media/base/media_switches.h"
#include "media/media_buildflags.h" #include "media/media_buildflags.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/base/resource/resource_bundle_android.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_switches.h"
#include "ui/events/gesture_detection/gesture_configuration.h" #include "ui/events/gesture_detection/gesture_configuration.h"
...@@ -317,6 +321,25 @@ bool AwMainDelegate::ShouldCreateFeatureList() { ...@@ -317,6 +321,25 @@ bool AwMainDelegate::ShouldCreateFeatureList() {
return false; return false;
} }
void AwMainDelegate::PostEarlyInitialization(bool is_running_tests) {
ui::SetLocalePaksStoredInApk(true);
std::string locale = ui::ResourceBundle::InitSharedInstanceWithLocale(
base::android::GetDefaultLocaleString(), NULL,
ui::ResourceBundle::LOAD_COMMON_RESOURCES);
if (locale.empty()) {
LOG(WARNING) << "Failed to load locale .pak from the apk. "
"Bringing up WebView without any locale";
}
base::i18n::SetICUDefaultLocale(locale);
// Try to directly mmap the resources.pak from the apk. Fall back to load
// from file, using PATH_SERVICE, otherwise.
base::FilePath pak_file_path;
base::PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &pak_file_path);
pak_file_path = pak_file_path.AppendASCII("resources.pak");
ui::LoadMainAndroidPackFile("assets/resources.pak", pak_file_path);
}
content::ContentBrowserClient* AwMainDelegate::CreateContentBrowserClient() { content::ContentBrowserClient* AwMainDelegate::CreateContentBrowserClient() {
content_browser_client_.reset(new AwContentBrowserClient()); content_browser_client_.reset(new AwContentBrowserClient());
return content_browser_client_.get(); return content_browser_client_.get();
......
...@@ -45,6 +45,7 @@ class AwMainDelegate : public content::ContentMainDelegate { ...@@ -45,6 +45,7 @@ class AwMainDelegate : public content::ContentMainDelegate {
const content::MainFunctionParams& main_function_params) override; const content::MainFunctionParams& main_function_params) override;
void ProcessExiting(const std::string& process_type) override; void ProcessExiting(const std::string& process_type) override;
bool ShouldCreateFeatureList() override; bool ShouldCreateFeatureList() override;
void PostEarlyInitialization(bool is_running_tests) override;
content::ContentBrowserClient* CreateContentBrowserClient() override; content::ContentBrowserClient* CreateContentBrowserClient() override;
content::ContentGpuClient* CreateContentGpuClient() override; content::ContentGpuClient* CreateContentGpuClient() override;
content::ContentRendererClient* CreateContentRendererClient() override; content::ContentRendererClient* CreateContentRendererClient() override;
......
...@@ -16,14 +16,15 @@ ...@@ -16,14 +16,15 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/process/memory.h" #include "base/process/memory.h"
#include "base/process/process_handle.h"
#include "base/process/process.h" #include "base/process/process.h"
#include "base/process/process_handle.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/trace_event/trace_event_impl.h" #include "base/trace_event/trace_event_impl.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/browser/chrome_resource_bundle_helper.h"
#include "chrome/browser/defaults.h" #include "chrome/browser/defaults.h"
#include "chrome/common/buildflags.h" #include "chrome/common/buildflags.h"
#include "chrome/common/channel_info.h" #include "chrome/common/channel_info.h"
...@@ -505,9 +506,15 @@ ChromeMainDelegate::~ChromeMainDelegate() { ...@@ -505,9 +506,15 @@ ChromeMainDelegate::~ChromeMainDelegate() {
} }
#if !defined(CHROME_MULTIPLE_DLL_CHILD) #if !defined(CHROME_MULTIPLE_DLL_CHILD)
void ChromeMainDelegate::PostEarlyInitialization() { void ChromeMainDelegate::PostEarlyInitialization(bool is_running_tests) {
DCHECK(chrome_feature_list_creator_); DCHECK(chrome_feature_list_creator_);
chrome_feature_list_creator_->CreateFeatureList(); chrome_feature_list_creator_->CreateFeatureList();
// Initializes the resouce bundle and determines the locale.
std::string actual_locale =
LoadLocalState(chrome_feature_list_creator_.get(), is_running_tests);
chrome_feature_list_creator_->SetApplicationLocale(actual_locale);
tracing_sampler_profiler_->OnMessageLoopStarted(); tracing_sampler_profiler_->OnMessageLoopStarted();
} }
......
...@@ -65,7 +65,7 @@ class ChromeMainDelegate : public content::ContentMainDelegate { ...@@ -65,7 +65,7 @@ class ChromeMainDelegate : public content::ContentMainDelegate {
service_manager::ProcessType OverrideProcessType() override; service_manager::ProcessType OverrideProcessType() override;
void PreCreateMainMessageLoop() override; void PreCreateMainMessageLoop() override;
#if !defined(CHROME_MULTIPLE_DLL_CHILD) #if !defined(CHROME_MULTIPLE_DLL_CHILD)
void PostEarlyInitialization() override; void PostEarlyInitialization(bool is_running_tests) override;
bool ShouldCreateFeatureList() override; bool ShouldCreateFeatureList() override;
#endif #endif
......
...@@ -273,6 +273,8 @@ jumbo_split_static_library("browser") { ...@@ -273,6 +273,8 @@ jumbo_split_static_library("browser") {
"chrome_notification_types.h", "chrome_notification_types.h",
"chrome_quota_permission_context.cc", "chrome_quota_permission_context.cc",
"chrome_quota_permission_context.h", "chrome_quota_permission_context.h",
"chrome_resource_bundle_helper.cc",
"chrome_resource_bundle_helper.h",
"chrome_service.cc", "chrome_service.cc",
"chrome_service.h", "chrome_service.h",
"client_hints/client_hints.cc", "client_hints/client_hints.cc",
......
...@@ -222,11 +222,8 @@ class BrowserProcess { ...@@ -222,11 +222,8 @@ class BrowserProcess {
// defined in BCP 47. The region subtag is not included when it adds no // defined in BCP 47. The region subtag is not included when it adds no
// distinguishing information to the language tag (e.g. both "en-US" and "fr" // distinguishing information to the language tag (e.g. both "en-US" and "fr"
// are correct here). // are correct here).
// When setting the locale, |preferred_locale| is the original desired locale.
// The actual application locale may differ.
virtual const std::string& GetApplicationLocale() = 0; virtual const std::string& GetApplicationLocale() = 0;
virtual void SetApplicationLocale(const std::string& actual_locale, virtual void SetApplicationLocale(const std::string& actual_locale) = 0;
const std::string& preferred_locale) = 0;
virtual DownloadStatusUpdater* download_status_updater() = 0; virtual DownloadStatusUpdater* download_status_updater() = 0;
virtual DownloadRequestLimiter* download_request_limiter() = 0; virtual DownloadRequestLimiter* download_request_limiter() = 0;
......
...@@ -850,15 +850,10 @@ const std::string& BrowserProcessImpl::GetApplicationLocale() { ...@@ -850,15 +850,10 @@ const std::string& BrowserProcessImpl::GetApplicationLocale() {
} }
void BrowserProcessImpl::SetApplicationLocale( void BrowserProcessImpl::SetApplicationLocale(
const std::string& actual_locale, const std::string& actual_locale) {
const std::string& preferred_locale) {
// NOTE: this is called before any threads have been created in non-test // NOTE: this is called before any threads have been created in non-test
// environments. // environments.
locale_ = actual_locale; locale_ = actual_locale;
#if BUILDFLAG(ENABLE_EXTENSIONS)
extension_l10n_util::SetProcessLocale(actual_locale);
extension_l10n_util::SetPreferredLocale(preferred_locale);
#endif
ChromeContentBrowserClient::SetApplicationLocale(actual_locale); ChromeContentBrowserClient::SetApplicationLocale(actual_locale);
translate::TranslateDownloadManager::GetInstance()->set_application_locale( translate::TranslateDownloadManager::GetInstance()->set_application_locale(
actual_locale); actual_locale);
...@@ -1109,6 +1104,12 @@ void BrowserProcessImpl::ResourceDispatcherHostCreated() { ...@@ -1109,6 +1104,12 @@ void BrowserProcessImpl::ResourceDispatcherHostCreated() {
ApplyAllowCrossOriginAuthPromptPolicy(); ApplyAllowCrossOriginAuthPromptPolicy();
} }
std::string BrowserProcessImpl::actual_locale() {
return chrome_feature_list_creator_
? chrome_feature_list_creator_->actual_locale()
: std::string();
}
void BrowserProcessImpl::OnKeepAliveStateChanged(bool is_keeping_alive) { void BrowserProcessImpl::OnKeepAliveStateChanged(bool is_keeping_alive) {
if (is_keeping_alive) if (is_keeping_alive)
Pin(); Pin();
......
...@@ -168,8 +168,7 @@ class BrowserProcessImpl : public BrowserProcess, ...@@ -168,8 +168,7 @@ class BrowserProcessImpl : public BrowserProcess,
printing::BackgroundPrintingManager* background_printing_manager() override; printing::BackgroundPrintingManager* background_printing_manager() override;
IntranetRedirectDetector* intranet_redirect_detector() override; IntranetRedirectDetector* intranet_redirect_detector() override;
const std::string& GetApplicationLocale() override; const std::string& GetApplicationLocale() override;
void SetApplicationLocale(const std::string& actual_locale, void SetApplicationLocale(const std::string& actual_locale) override;
const std::string& preferred_locale) override;
DownloadStatusUpdater* download_status_updater() override; DownloadStatusUpdater* download_status_updater() override;
DownloadRequestLimiter* download_request_limiter() override; DownloadRequestLimiter* download_request_limiter() override;
BackgroundModeManager* background_mode_manager() override; BackgroundModeManager* background_mode_manager() override;
...@@ -205,6 +204,9 @@ class BrowserProcessImpl : public BrowserProcess, ...@@ -205,6 +204,9 @@ class BrowserProcessImpl : public BrowserProcess,
static void RegisterPrefs(PrefRegistrySimple* registry); static void RegisterPrefs(PrefRegistrySimple* registry);
// The locale used by the application.
std::string actual_locale();
private: private:
using WebRtcEventLogManager = webrtc_event_logging::WebRtcEventLogManager; using WebRtcEventLogManager = webrtc_event_logging::WebRtcEventLogManager;
......
...@@ -356,88 +356,6 @@ void AddFirstRunNewTabs(StartupBrowserCreator* browser_creator, ...@@ -356,88 +356,6 @@ void AddFirstRunNewTabs(StartupBrowserCreator* browser_creator,
} }
#endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) #endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
void InitializeLocalState() {
TRACE_EVENT0("startup", "ChromeBrowserMainParts::InitializeLocalState")
// Load local state. This includes the application locale so we know which
// locale dll to load. This also causes local state prefs to be registered.
PrefService* local_state = g_browser_process->local_state();
DCHECK(local_state);
#if defined(OS_WIN)
if (first_run::IsChromeFirstRun()) {
// During first run we read the google_update registry key to find what
// language the user selected when downloading the installer. This
// becomes our default language in the prefs.
// Other platforms obey the system locale.
base::string16 install_lang;
if (GoogleUpdateSettings::GetLanguage(&install_lang)) {
local_state->SetString(language::prefs::kApplicationLocale,
base::UTF16ToASCII(install_lang));
}
bool stats_default;
if (GoogleUpdateSettings::GetCollectStatsConsentDefault(&stats_default)) {
// |stats_default| == true means that the default state of consent for the
// product at the time of install was to report usage statistics, meaning
// "opt-out".
metrics::RecordMetricsReportingDefaultState(
local_state, stats_default ? metrics::EnableMetricsDefault::OPT_OUT
: metrics::EnableMetricsDefault::OPT_IN);
}
}
#endif // defined(OS_WIN)
// If the local state file for the current profile doesn't exist and the
// parent profile command line flag is present, then we should inherit some
// local state from the parent profile.
// Checking that the local state file for the current profile doesn't exist
// is the most robust way to determine whether we need to inherit or not
// since the parent profile command line flag can be present even when the
// current profile is not a new one, and in that case we do not want to
// inherit and reset the user's setting.
//
// TODO(mnissler): We should probably just instantiate a
// JSONPrefStore here instead of an entire PrefService. Once this is
// addressed, the call to browser_prefs::RegisterLocalState can move
// to chrome_prefs::CreateLocalState.
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kParentProfile)) {
base::FilePath local_state_path;
base::PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path);
bool local_state_file_exists = base::PathExists(local_state_path);
if (!local_state_file_exists) {
base::FilePath parent_profile =
command_line->GetSwitchValuePath(switches::kParentProfile);
scoped_refptr<PrefRegistrySimple> registry =
base::MakeRefCounted<PrefRegistrySimple>();
registry->RegisterStringPref(language::prefs::kApplicationLocale,
std::string());
const std::unique_ptr<PrefService> parent_local_state =
chrome_prefs::CreateLocalState(
parent_profile, g_browser_process->policy_service(),
std::move(registry), false, nullptr,
g_browser_process->browser_policy_connector());
// Right now, we only inherit the locale setting from the parent profile.
local_state->SetString(
language::prefs::kApplicationLocale,
parent_local_state->GetString(language::prefs::kApplicationLocale));
}
}
#if defined(OS_CHROMEOS)
if (command_line->HasSwitch(chromeos::switches::kLoginManager)) {
std::string owner_locale = local_state->GetString(prefs::kOwnerLocale);
// Ensure that we start with owner's locale.
if (!owner_locale.empty() &&
local_state->GetString(language::prefs::kApplicationLocale) !=
owner_locale &&
!local_state->IsManagedPreference(
language::prefs::kApplicationLocale)) {
local_state->SetString(language::prefs::kApplicationLocale, owner_locale);
}
}
#endif // defined(OS_CHROMEOS)
}
// Initializes the primary profile, possibly doing some user prompting to pick // Initializes the primary profile, possibly doing some user prompting to pick
// a fallback profile. Returns the newly created profile, or NULL if startup // a fallback profile. Returns the newly created profile, or NULL if startup
// should not continue. // should not continue.
...@@ -679,48 +597,6 @@ bool IsWebDriverOverridingPolicy(PrefService* local_state) { ...@@ -679,48 +597,6 @@ bool IsWebDriverOverridingPolicy(PrefService* local_state) {
prefs::kWebDriverOverridesIncompatiblePolicies))); prefs::kWebDriverOverridesIncompatiblePolicies)));
} }
// Initializes the shared instance of ResourceBundle and returns the locale. An
// empty |actual_locale| value indicates failure.
ApplicationLocaleResult InitResourceBundleAndDetermineLocale(
const content::MainFunctionParams& params) {
#if defined(OS_MACOSX)
// TODO(markusheintz): Read preference pref::kApplicationLocale in order
// to enforce the application locale.
// Tests always get en-US.
std::string preferred_locale = params.ui_task ? "en-US" : std::string();
#else
std::string preferred_locale = g_browser_process->local_state()->GetString(
language::prefs::kApplicationLocale);
#endif
TRACE_EVENT0("startup",
"ChromeBrowserMainParts::InitResourceBundleAndDetermineLocale");
// On a POSIX OS other than ChromeOS, the parameter that is passed to the
// method InitSharedInstance is ignored.
std::string actual_locale = ui::ResourceBundle::InitSharedInstanceWithLocale(
preferred_locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
if (actual_locale.empty())
return {actual_locale, preferred_locale};
// First run prefs needs data from the ResourceBundle, so load it now.
{
TRACE_EVENT0("startup",
"ChromeBrowserMainParts::InitResourceBundleAndDetermineLocale:"
":AddDataPack");
base::FilePath resources_pack_path;
base::PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path);
#if defined(OS_ANDROID)
ui::LoadMainAndroidPackFile("assets/resources.pak", resources_pack_path);
#else
ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath(
resources_pack_path, ui::SCALE_FACTOR_NONE);
#endif // defined(OS_ANDROID)
}
return {actual_locale, preferred_locale};
}
bool IsSiteIsolationEnterprisePolicyApplicable() { bool IsSiteIsolationEnterprisePolicyApplicable() {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// https://crbug.com/844118: Limiting policy to devices with > 1GB RAM. // https://crbug.com/844118: Limiting policy to devices with > 1GB RAM.
...@@ -964,7 +840,7 @@ int ChromeBrowserMainParts::PreEarlyInitialization() { ...@@ -964,7 +840,7 @@ int ChromeBrowserMainParts::PreEarlyInitialization() {
bool failed_to_load_resource_bundle = false; bool failed_to_load_resource_bundle = false;
const int load_local_state_result = const int load_local_state_result =
LoadLocalState(&failed_to_load_resource_bundle); OnLocalStateLoaded(&failed_to_load_resource_bundle);
// Reuses the MetricsServicesManager and GetMetricsServicesManagerClient // Reuses the MetricsServicesManager and GetMetricsServicesManagerClient
// instances created in the FeatureListCreator so they won't be created again. // instances created in the FeatureListCreator so they won't be created again.
...@@ -1047,27 +923,32 @@ int ChromeBrowserMainParts::PreCreateThreads() { ...@@ -1047,27 +923,32 @@ int ChromeBrowserMainParts::PreCreateThreads() {
return result_code_; return result_code_;
} }
int ChromeBrowserMainParts::LoadLocalState( int ChromeBrowserMainParts::OnLocalStateLoaded(
bool* failed_to_load_resource_bundle) { bool* failed_to_load_resource_bundle) {
*failed_to_load_resource_bundle = false; *failed_to_load_resource_bundle = false;
if (!base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir_)) if (!base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir_))
return chrome::RESULT_CODE_MISSING_DATA; return chrome::RESULT_CODE_MISSING_DATA;
InitializeLocalState(); #if defined(OS_WIN)
if (first_run::IsChromeFirstRun()) {
browser_process_->local_state()->UpdateCommandLinePrefStore( bool stats_default;
new ChromeCommandLinePrefStore(base::CommandLine::ForCurrentProcess())); if (GoogleUpdateSettings::GetCollectStatsConsentDefault(&stats_default)) {
// |stats_default| == true means that the default state of consent for the
// product at the time of install was to report usage statistics, meaning
// "opt-out".
metrics::RecordMetricsReportingDefaultState(
browser_process_->local_state(),
stats_default ? metrics::EnableMetricsDefault::OPT_OUT
: metrics::EnableMetricsDefault::OPT_IN);
}
}
#endif // defined(OS_WIN)
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
master_prefs_ = std::make_unique<first_run::MasterPrefs>(); master_prefs_ = std::make_unique<first_run::MasterPrefs>();
#endif #endif
// First run prefs may use the ResourceBundle (and get data from it), so this if (browser_process_->actual_locale().empty()) {
// needs to be before ApplyFirstRunPrefs().
ApplicationLocaleResult locale_result =
InitResourceBundleAndDetermineLocale(parameters());
if (locale_result.actual_locale.empty()) {
*failed_to_load_resource_bundle = true; *failed_to_load_resource_bundle = true;
return chrome::RESULT_CODE_MISSING_DATA; return chrome::RESULT_CODE_MISSING_DATA;
} }
...@@ -1076,8 +957,7 @@ int ChromeBrowserMainParts::LoadLocalState( ...@@ -1076,8 +957,7 @@ int ChromeBrowserMainParts::LoadLocalState(
if (apply_first_run_result != service_manager::RESULT_CODE_NORMAL_EXIT) if (apply_first_run_result != service_manager::RESULT_CODE_NORMAL_EXIT)
return apply_first_run_result; return apply_first_run_result;
browser_process_->SetApplicationLocale(locale_result.actual_locale, browser_process_->SetApplicationLocale(browser_process_->actual_locale());
locale_result.preferred_locale);
SetupOriginTrialsCommandLine(browser_process_->local_state()); SetupOriginTrialsCommandLine(browser_process_->local_state());
......
...@@ -116,12 +116,12 @@ class ChromeBrowserMainParts : public content::BrowserMainParts { ...@@ -116,12 +116,12 @@ class ChromeBrowserMainParts : public content::BrowserMainParts {
// for child processes. // for child processes.
void SetupOriginTrialsCommandLine(PrefService* local_state); void SetupOriginTrialsCommandLine(PrefService* local_state);
// Calling during PreEarlyInitialization() to load local state. Return value // Calling during PreEarlyInitialization() to complete the remaining tasks
// is an exit status, RESULT_CODE_NORMAL_EXIT indicates success. // after the local state is loaded. Return value is an exit status,
// If the return value is RESULT_CODE_MISSING_DATA, then // RESULT_CODE_NORMAL_EXIT indicates success. If the return value is
// |failed_to_load_resource_bundle| indicates if the ResourceBundle couldn't // RESULT_CODE_MISSING_DATA, then |failed_to_load_resource_bundle| indicates
// be loaded. // if the ResourceBundle couldn't be loaded.
int LoadLocalState(bool* failed_to_load_resource_bundle); int OnLocalStateLoaded(bool* failed_to_load_resource_bundle);
// Applies any preferences (to local state) needed for first run. This is // Applies any preferences (to local state) needed for first run. This is
// always called and early outs if not first-run. Return value is an exit // always called and early outs if not first-run. Return value is an exit
......
...@@ -114,13 +114,6 @@ int ChromeBrowserMainPartsAndroid::PreEarlyInitialization() { ...@@ -114,13 +114,6 @@ int ChromeBrowserMainPartsAndroid::PreEarlyInitialization() {
main_message_loop_ = std::make_unique<base::MessageLoopForUI>(); main_message_loop_ = std::make_unique<base::MessageLoopForUI>();
} }
// In order for SetLoadSecondaryLocalePaks() to work ResourceBundle must
// not have been created yet.
DCHECK(!ui::ResourceBundle::HasSharedInstance());
// Auto-detect based on en-US whether secondary locale .pak files exist.
ui::SetLoadSecondaryLocalePaks(
!ui::GetPathForAndroidLocalePakWithinApk("en-US").empty());
return ChromeBrowserMainParts::PreEarlyInitialization(); return ChromeBrowserMainParts::PreEarlyInitialization();
} }
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chrome_resource_bundle_helper.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/metrics/chrome_feature_list_creator.h"
#include "chrome/browser/prefs/chrome_command_line_pref_store.h"
#include "chrome/browser/prefs/chrome_pref_service_factory.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/installer/util/google_update_settings.h"
#include "components/language/core/browser/pref_names.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/extension_l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#if defined(OS_ANDROID)
#include "ui/base/resource/resource_bundle_android.h"
#endif
#if defined(OS_CHROMEOS)
#include "chrome/common/pref_names.h"
#include "chromeos/chromeos_switches.h"
#endif
namespace {
extern void InitializeLocalState(
ChromeFeatureListCreator* chrome_feature_list_creator) {
TRACE_EVENT0("startup", "ChromeBrowserMainParts::InitializeLocalState");
// Load local state. This includes the application locale so we know which
// locale dll to load. This also causes local state prefs to be registered.
PrefService* local_state = chrome_feature_list_creator->local_state();
DCHECK(local_state);
#if defined(OS_WIN)
if (first_run::IsChromeFirstRun()) {
// During first run we read the google_update registry key to find what
// language the user selected when downloading the installer. This
// becomes our default language in the prefs.
// Other platforms obey the system locale.
base::string16 install_lang;
if (GoogleUpdateSettings::GetLanguage(&install_lang)) {
local_state->SetString(language::prefs::kApplicationLocale,
base::UTF16ToASCII(install_lang));
}
}
#endif // defined(OS_WIN)
// If the local state file for the current profile doesn't exist and the
// parent profile command line flag is present, then we should inherit some
// local state from the parent profile.
// Checking that the local state file for the current profile doesn't exist
// is the most robust way to determine whether we need to inherit or not
// since the parent profile command line flag can be present even when the
// current profile is not a new one, and in that case we do not want to
// inherit and reset the user's setting.
//
// TODO(mnissler): We should probably just instantiate a
// JSONPrefStore here instead of an entire PrefService. Once this is
// addressed, the call to browser_prefs::RegisterLocalState can move
// to chrome_prefs::CreateLocalState.
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kParentProfile)) {
base::FilePath local_state_path;
base::PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path);
bool local_state_file_exists = base::PathExists(local_state_path);
if (!local_state_file_exists) {
base::FilePath parent_profile =
command_line->GetSwitchValuePath(switches::kParentProfile);
scoped_refptr<PrefRegistrySimple> registry =
base::MakeRefCounted<PrefRegistrySimple>();
registry->RegisterStringPref(language::prefs::kApplicationLocale,
std::string());
const std::unique_ptr<PrefService> parent_local_state =
chrome_prefs::CreateLocalState(
parent_profile,
chrome_feature_list_creator->browser_policy_connector()
->GetPolicyService(),
std::move(registry), false, nullptr,
chrome_feature_list_creator->browser_policy_connector());
// Right now, we only inherit the locale setting from the parent profile.
local_state->SetString(
language::prefs::kApplicationLocale,
parent_local_state->GetString(language::prefs::kApplicationLocale));
}
}
#if defined(OS_CHROMEOS)
if (command_line->HasSwitch(chromeos::switches::kLoginManager)) {
std::string owner_locale = local_state->GetString(prefs::kOwnerLocale);
// Ensure that we start with owner's locale.
if (!owner_locale.empty() &&
local_state->GetString(language::prefs::kApplicationLocale) !=
owner_locale &&
!local_state->IsManagedPreference(
language::prefs::kApplicationLocale)) {
local_state->SetString(language::prefs::kApplicationLocale, owner_locale);
}
}
#endif // defined(OS_CHROMEOS)
}
// Initializes the shared instance of ResourceBundle and returns the application
// locale. An empty |actual_locale| value indicates failure.
std::string InitResourceBundleAndDetermineLocale(PrefService* local_state,
bool is_running_tests) {
#if defined(OS_ANDROID)
// In order for SetLoadSecondaryLocalePaks() to work ResourceBundle must
// not have been created yet.
DCHECK(!ui::ResourceBundle::HasSharedInstance());
// Auto-detect based on en-US whether secondary locale .pak files exist.
ui::SetLoadSecondaryLocalePaks(
!ui::GetPathForAndroidLocalePakWithinApk("en-US").empty());
#endif
std::string preferred_locale;
#if defined(OS_MACOSX)
// TODO(markusheintz): Read preference pref::kApplicationLocale in order
// to enforce the application locale.
// Tests always get en-US.
preferred_locale = is_running_tests ? "en-US" : std::string();
#else
preferred_locale =
local_state->GetString(language::prefs::kApplicationLocale);
#endif
TRACE_EVENT0("startup",
"ChromeBrowserMainParts::InitResourceBundleAndDetermineLocale");
// On a POSIX OS other than ChromeOS, the parameter that is passed to the
// method InitSharedInstance is ignored.
std::string actual_locale = ui::ResourceBundle::InitSharedInstanceWithLocale(
preferred_locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
if (actual_locale.empty())
return actual_locale;
// First run prefs needs data from the ResourceBundle, so load it now.
{
TRACE_EVENT0("startup",
"ChromeBrowserMainParts::InitResourceBundleAndDetermineLocale:"
":AddDataPack");
base::FilePath resources_pack_path;
base::PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path);
#if defined(OS_ANDROID)
ui::LoadMainAndroidPackFile("assets/resources.pak", resources_pack_path);
#else
ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath(
resources_pack_path, ui::SCALE_FACTOR_NONE);
#endif // defined(OS_ANDROID)
}
#if BUILDFLAG(ENABLE_EXTENSIONS)
extension_l10n_util::SetProcessLocale(actual_locale);
extension_l10n_util::SetPreferredLocale(preferred_locale);
#endif
return actual_locale;
}
} // namespace
std::string LoadLocalState(
ChromeFeatureListCreator* chrome_feature_list_creator,
bool is_running_tests) {
base::FilePath user_data_dir;
if (!base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
return std::string();
InitializeLocalState(chrome_feature_list_creator);
chrome_feature_list_creator->local_state()->UpdateCommandLinePrefStore(
new ChromeCommandLinePrefStore(base::CommandLine::ForCurrentProcess()));
return InitResourceBundleAndDetermineLocale(
chrome_feature_list_creator->local_state(), is_running_tests);
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROME_RESOURCE_BUNDLE_HELPER_H_
#define CHROME_BROWSER_CHROME_RESOURCE_BUNDLE_HELPER_H_
#include <string>
class ChromeFeatureListCreator;
// Loads the local state, and returns the application locale. An empty return
// value indicates the ResouceBundle couldn't be loaded.
std::string LoadLocalState(
ChromeFeatureListCreator* chrome_feature_list_creator,
bool is_running_tests);
#endif // CHROME_BROWSER_CHROME_RESOURCE_BUNDLE_HELPER_H_
...@@ -62,8 +62,7 @@ void SwitchLanguageDoReloadLocale(SwitchLanguageData* data) { ...@@ -62,8 +62,7 @@ void SwitchLanguageDoReloadLocale(SwitchLanguageData* data) {
void FinishSwitchLanguage(std::unique_ptr<SwitchLanguageData> data) { void FinishSwitchLanguage(std::unique_ptr<SwitchLanguageData> data) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (data->result.success) { if (data->result.success) {
g_browser_process->SetApplicationLocale(data->result.loaded_locale, g_browser_process->SetApplicationLocale(data->result.loaded_locale);
data->result.requested_locale);
if (data->enable_locale_keyboard_layouts) { if (data->enable_locale_keyboard_layouts) {
input_method::InputMethodManager* manager = input_method::InputMethodManager* manager =
......
...@@ -48,6 +48,14 @@ class ChromeFeatureListCreator { ...@@ -48,6 +48,14 @@ class ChromeFeatureListCreator {
std::unique_ptr<prefs::InProcessPrefServiceFactory> TakePrefServiceFactory(); std::unique_ptr<prefs::InProcessPrefServiceFactory> TakePrefServiceFactory();
PrefService* local_state() { return local_state_.get(); } PrefService* local_state() { return local_state_.get(); }
policy::ChromeBrowserPolicyConnector* browser_policy_connector() {
return browser_policy_connector_.get();
}
const std::string& actual_locale() { return actual_locale_; }
void SetApplicationLocale(const std::string& locale) {
actual_locale_ = locale;
}
private: private:
void CreatePrefService(); void CreatePrefService();
...@@ -59,6 +67,10 @@ class ChromeFeatureListCreator { ...@@ -59,6 +67,10 @@ class ChromeFeatureListCreator {
// of this variable. Stop using this variable afterwards. // of this variable. Stop using this variable afterwards.
std::unique_ptr<PrefService> local_state_; std::unique_ptr<PrefService> local_state_;
// The locale used by the application. It is set when initializing the
// ResouceBundle.
std::string actual_locale_;
// This is owned by |metrics_services_manager_| but we need to expose it. // This is owned by |metrics_services_manager_| but we need to expose it.
ChromeMetricsServicesManagerClient* metrics_services_manager_client_; ChromeMetricsServicesManagerClient* metrics_services_manager_client_;
......
...@@ -222,12 +222,12 @@ TEST_F(TtsControllerTest, TestGetMatchingVoice) { ...@@ -222,12 +222,12 @@ TEST_F(TtsControllerTest, TestGetMatchingVoice) {
Utterance utterance(nullptr); Utterance utterance(nullptr);
// voice1 is matched against the exact default system language. // voice1 is matched against the exact default system language.
g_browser_process->SetApplicationLocale("en-US", "en-US"); g_browser_process->SetApplicationLocale("en-US");
utterance.set_lang(""); utterance.set_lang("");
EXPECT_EQ(1, tts_controller->GetMatchingVoice(&utterance, voices)); EXPECT_EQ(1, tts_controller->GetMatchingVoice(&utterance, voices));
// voice0 is matched against the system language which has no region piece. // voice0 is matched against the system language which has no region piece.
g_browser_process->SetApplicationLocale("en", "en"); g_browser_process->SetApplicationLocale("en");
utterance.set_lang(""); utterance.set_lang("");
EXPECT_EQ(0, tts_controller->GetMatchingVoice(&utterance, voices)); EXPECT_EQ(0, tts_controller->GetMatchingVoice(&utterance, voices));
...@@ -242,7 +242,7 @@ TEST_F(TtsControllerTest, TestGetMatchingVoice) { ...@@ -242,7 +242,7 @@ TEST_F(TtsControllerTest, TestGetMatchingVoice) {
std::move(lang_to_voices)); std::move(lang_to_voices));
// voice0 is matched against the pref over the system language. // voice0 is matched against the pref over the system language.
g_browser_process->SetApplicationLocale("en-US", "en-US"); g_browser_process->SetApplicationLocale("en-US");
EXPECT_EQ(0, tts_controller->GetMatchingVoice(&utterance, voices)); EXPECT_EQ(0, tts_controller->GetMatchingVoice(&utterance, voices));
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
} }
......
...@@ -585,7 +585,7 @@ class TranslateManagerRenderViewHostInvalidLocaleTest ...@@ -585,7 +585,7 @@ class TranslateManagerRenderViewHostInvalidLocaleTest
const std::string original_locale_; const std::string original_locale_;
void SetApplicationLocale(const std::string& locale) { void SetApplicationLocale(const std::string& locale) {
g_browser_process->SetApplicationLocale(locale, locale); g_browser_process->SetApplicationLocale(locale);
translate::TranslateDownloadManager::GetInstance()->set_application_locale( translate::TranslateDownloadManager::GetInstance()->set_application_locale(
g_browser_process->GetApplicationLocale()); g_browser_process->GetApplicationLocale());
} }
......
...@@ -101,7 +101,7 @@ bool SwitchBrowserLanguageToFrench() { ...@@ -101,7 +101,7 @@ bool SwitchBrowserLanguageToFrench() {
EXPECT_NE("fr", default_locale); EXPECT_NE("fr", default_locale);
// Switch browser language to French. // Switch browser language to French.
g_browser_process->SetApplicationLocale("fr", "fr"); g_browser_process->SetApplicationLocale("fr");
PrefService* prefs = g_browser_process->local_state(); PrefService* prefs = g_browser_process->local_state();
prefs->SetString(language::prefs::kApplicationLocale, "fr"); prefs->SetString(language::prefs::kApplicationLocale, "fr");
......
...@@ -8,9 +8,9 @@ ...@@ -8,9 +8,9 @@
ScopedBrowserLocale::ScopedBrowserLocale(const std::string& new_locale) ScopedBrowserLocale::ScopedBrowserLocale(const std::string& new_locale)
: old_locale_(g_browser_process->GetApplicationLocale()) { : old_locale_(g_browser_process->GetApplicationLocale()) {
g_browser_process->SetApplicationLocale(new_locale, new_locale); g_browser_process->SetApplicationLocale(new_locale);
} }
ScopedBrowserLocale::~ScopedBrowserLocale() { ScopedBrowserLocale::~ScopedBrowserLocale() {
g_browser_process->SetApplicationLocale(old_locale_, old_locale_); g_browser_process->SetApplicationLocale(old_locale_);
} }
...@@ -367,8 +367,7 @@ const std::string& TestingBrowserProcess::GetApplicationLocale() { ...@@ -367,8 +367,7 @@ const std::string& TestingBrowserProcess::GetApplicationLocale() {
} }
void TestingBrowserProcess::SetApplicationLocale( void TestingBrowserProcess::SetApplicationLocale(
const std::string& actual_locale, const std::string& actual_locale) {
const std::string& preferred_locale) {
app_locale_ = actual_locale; app_locale_ = actual_locale;
} }
......
...@@ -114,8 +114,7 @@ class TestingBrowserProcess : public BrowserProcess { ...@@ -114,8 +114,7 @@ class TestingBrowserProcess : public BrowserProcess {
override; override;
printing::BackgroundPrintingManager* background_printing_manager() override; printing::BackgroundPrintingManager* background_printing_manager() override;
const std::string& GetApplicationLocale() override; const std::string& GetApplicationLocale() override;
void SetApplicationLocale(const std::string& actual_locale, void SetApplicationLocale(const std::string& actual_locale) override;
const std::string& preferred_locale) override;
DownloadStatusUpdater* download_status_updater() override; DownloadStatusUpdater* download_status_updater() override;
DownloadRequestLimiter* download_request_limiter() override; DownloadRequestLimiter* download_request_limiter() override;
......
...@@ -888,7 +888,7 @@ int ContentMainRunnerImpl::Run(bool start_service_manager_only) { ...@@ -888,7 +888,7 @@ int ContentMainRunnerImpl::Run(bool start_service_manager_only) {
field_trial_list_ = SetUpFieldTrialsAndFeatureList(); field_trial_list_ = SetUpFieldTrialsAndFeatureList();
} }
delegate_->PostEarlyInitialization(); delegate_->PostEarlyInitialization(main_params.ui_task != nullptr);
if (GetContentClient()->browser()->ShouldCreateTaskScheduler()) { if (GetContentClient()->browser()->ShouldCreateTaskScheduler()) {
// The FeatureList needs to create before starting the TaskScheduler. // The FeatureList needs to create before starting the TaskScheduler.
......
...@@ -130,7 +130,8 @@ class CONTENT_EXPORT ContentMainDelegate { ...@@ -130,7 +130,8 @@ class CONTENT_EXPORT ContentMainDelegate {
// Allows the embedder to perform its own initialization after content // Allows the embedder to perform its own initialization after content
// performed its own and already brought up MessageLoop, TaskScheduler, field // performed its own and already brought up MessageLoop, TaskScheduler, field
// tials and FeatureList (by default). // tials and FeatureList (by default).
virtual void PostEarlyInitialization() {} // |is_running_tests| indicates whether it is running in tests.
virtual void PostEarlyInitialization(bool is_running_tests) {}
protected: protected:
friend class ContentClientInitializer; friend class ContentClientInitializer;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment