1 // Copyright 2018 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.
5 #include "chrome/browser/chrome_resource_bundle_helper.h"
7 #include "base/files/file_util.h"
8 #include "base/path_service.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/trace_event/trace_event.h"
11 #include "build/build_config.h"
12 #include "chrome/browser/first_run/first_run.h"
13 #include "chrome/browser/metrics/chrome_feature_list_creator.h"
14 #include "chrome/browser/prefs/chrome_command_line_pref_store.h"
15 #include "chrome/browser/prefs/chrome_pref_service_factory.h"
16 #include "chrome/common/chrome_paths.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/installer/util/google_update_settings.h"
19 #include "components/language/core/browser/pref_names.h"
20 #include "components/prefs/pref_registry_simple.h"
21 #include "components/prefs/pref_service.h"
22 #include "extensions/buildflags/buildflags.h"
23 #include "extensions/common/extension_l10n_util.h"
24 #include "ui/base/resource/resource_bundle.h"
26 #if defined(OS_ANDROID)
27 #include "ui/base/resource/resource_bundle_android.h"
30 #if defined(OS_CHROMEOS)
31 #include "chrome/common/pref_names.h"
32 #include "chromeos/constants/chromeos_switches.h"
37 extern void InitializeLocalState(
38 ChromeFeatureListCreator* chrome_feature_list_creator) {
39 TRACE_EVENT0("startup", "ChromeBrowserMainParts::InitializeLocalState");
41 #if defined(OS_CHROMEOS)
42 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
43 if (command_line->HasSwitch(chromeos::switches::kLoginManager)) {
44 PrefService* local_state = chrome_feature_list_creator->local_state();
47 std::string owner_locale = local_state->GetString(prefs::kOwnerLocale);
48 // Ensure that we start with owner's locale.
49 if (!owner_locale.empty() &&
50 local_state->GetString(language::prefs::kApplicationLocale) !=
52 !local_state->IsManagedPreference(
53 language::prefs::kApplicationLocale)) {
54 local_state->SetString(language::prefs::kApplicationLocale, owner_locale);
57 #endif // defined(OS_CHROMEOS)
60 // Initializes the shared instance of ResourceBundle and returns the application
61 // locale. An empty |actual_locale| value indicates failure.
62 std::string InitResourceBundleAndDetermineLocale(PrefService* local_state,
63 bool is_running_tests) {
64 #if defined(OS_ANDROID)
65 // In order for SetLoadSecondaryLocalePaks() to work ResourceBundle must
66 // not have been created yet.
67 DCHECK(!ui::ResourceBundle::HasSharedInstance());
68 // Auto-detect based on en-US whether secondary locale .pak files exist.
69 bool in_split = false;
70 bool log_error = false;
71 ui::SetLoadSecondaryLocalePaks(
72 !ui::GetPathForAndroidLocalePakWithinApk("en-US", in_split, log_error)
76 std::string preferred_locale;
77 #if defined(OS_MACOSX)
78 // TODO(markusheintz): Read preference pref::kApplicationLocale in order
79 // to enforce the application locale.
80 // Tests always get en-US.
81 preferred_locale = is_running_tests ? "en-US" : std::string();
84 local_state->GetString(language::prefs::kApplicationLocale);
87 TRACE_EVENT0("startup",
88 "ChromeBrowserMainParts::InitResourceBundleAndDetermineLocale");
89 // On a POSIX OS other than ChromeOS, the parameter that is passed to the
90 // method InitSharedInstance is ignored.
91 std::string actual_locale = ui::ResourceBundle::InitSharedInstanceWithLocale(
92 preferred_locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
93 CHECK(!actual_locale.empty())
94 << "Locale could not be found for " << preferred_locale;
96 // First run prefs needs data from the ResourceBundle, so load it now.
98 TRACE_EVENT0("startup",
99 "ChromeBrowserMainParts::InitResourceBundleAndDetermineLocale:"
101 base::FilePath resources_pack_path;
102 base::PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path);
103 #if defined(OS_ANDROID)
104 ui::LoadMainAndroidPackFile("assets/resources.pak", resources_pack_path);
106 // Avoid loading DFM native resources here, to keep startup lean. These
107 // resources are loaded on-use, when an already-installed DFM loads.
109 ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath(
110 resources_pack_path, ui::SCALE_FACTOR_NONE);
111 #endif // defined(OS_ANDROID)
114 #if BUILDFLAG(ENABLE_EXTENSIONS)
115 extension_l10n_util::SetProcessLocale(actual_locale);
116 extension_l10n_util::SetPreferredLocale(preferred_locale);
118 return actual_locale;
123 std::string LoadLocalState(
124 ChromeFeatureListCreator* chrome_feature_list_creator,
125 bool is_running_tests) {
126 base::FilePath user_data_dir;
127 if (!base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
128 return std::string();
130 InitializeLocalState(chrome_feature_list_creator);
132 chrome_feature_list_creator->local_state()->UpdateCommandLinePrefStore(
133 new ChromeCommandLinePrefStore(base::CommandLine::ForCurrentProcess()));
135 return InitResourceBundleAndDetermineLocale(
136 chrome_feature_list_creator->local_state(), is_running_tests);