Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Side by Side Diff: ui/base/resource/resource_bundle_android.cc

Issue 2977993002: Reland of Deduplicate Monochrome locale .paks (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/base/resource/resource_bundle_android.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/base/resource/resource_bundle_android.h" 5 #include "ui/base/resource/resource_bundle_android.h"
6 6
7 #include "base/android/apk_assets.h" 7 #include "base/android/apk_assets.h"
8 #include "base/android/jni_android.h" 8 #include "base/android/jni_android.h"
9 #include "base/android/jni_string.h" 9 #include "base/android/jni_string.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/ptr_util.h"
11 #include "base/path_service.h" 12 #include "base/path_service.h"
12 #include "jni/ResourceBundle_jni.h" 13 #include "jni/ResourceBundle_jni.h"
13 #include "ui/base/l10n/l10n_util.h" 14 #include "ui/base/l10n/l10n_util.h"
14 #include "ui/base/resource/data_pack.h" 15 #include "ui/base/resource/data_pack.h"
15 #include "ui/base/resource/resource_bundle.h" 16 #include "ui/base/resource/resource_bundle.h"
16 #include "ui/base/ui_base_paths.h" 17 #include "ui/base/ui_base_paths.h"
17 18
18 namespace ui { 19 namespace ui {
19 20
20 namespace { 21 namespace {
21 22
22 bool g_locale_paks_in_apk = false; 23 bool g_locale_paks_in_apk = false;
24 bool g_load_secondary_locale_paks = false;
23 // It is okay to cache and share these file descriptors since the 25 // It is okay to cache and share these file descriptors since the
24 // ResourceBundle singleton never closes the handles. 26 // ResourceBundle singleton never closes the handles.
25 int g_chrome_100_percent_fd = -1; 27 int g_chrome_100_percent_fd = -1;
26 int g_resources_pack_fd = -1; 28 int g_resources_pack_fd = -1;
27 int g_locale_pack_fd = -1; 29 int g_locale_pack_fd = -1;
30 int g_secondary_locale_pack_fd = -1;
28 base::MemoryMappedFile::Region g_chrome_100_percent_region; 31 base::MemoryMappedFile::Region g_chrome_100_percent_region;
29 base::MemoryMappedFile::Region g_resources_pack_region; 32 base::MemoryMappedFile::Region g_resources_pack_region;
30 base::MemoryMappedFile::Region g_locale_pack_region; 33 base::MemoryMappedFile::Region g_locale_pack_region;
34 base::MemoryMappedFile::Region g_secondary_locale_pack_region;
31 35
32 bool LoadFromApkOrFile(const char* apk_path, 36 bool LoadFromApkOrFile(const char* apk_path,
33 const base::FilePath* disk_path, 37 const base::FilePath* disk_path,
34 int* fd_out, 38 int* out_fd,
35 base::MemoryMappedFile::Region* region_out) { 39 base::MemoryMappedFile::Region* out_region) {
36 DCHECK_EQ(*fd_out, -1) << "Attempt to load " << apk_path << " twice."; 40 DCHECK_EQ(*out_fd, -1) << "Attempt to load " << apk_path << " twice.";
37 if (apk_path != nullptr) { 41 if (apk_path != nullptr) {
38 *fd_out = base::android::OpenApkAsset(apk_path, region_out); 42 *out_fd = base::android::OpenApkAsset(apk_path, out_region);
39 } 43 }
40 // For unit tests, the file exists on disk. 44 // For unit tests, the file exists on disk.
41 if (*fd_out < 0 && disk_path != nullptr) { 45 if (*out_fd < 0 && disk_path != nullptr) {
42 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; 46 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
43 *fd_out = base::File(*disk_path, flags).TakePlatformFile(); 47 *out_fd = base::File(*disk_path, flags).TakePlatformFile();
44 *region_out = base::MemoryMappedFile::Region::kWholeFile; 48 *out_region = base::MemoryMappedFile::Region::kWholeFile;
45 } 49 }
46 bool success = *fd_out >= 0; 50 bool success = *out_fd >= 0;
47 if (!success) { 51 if (!success) {
48 LOG(ERROR) << "Failed to open pak file: " << apk_path; 52 LOG(ERROR) << "Failed to open pak file: " << apk_path;
49 } 53 }
50 return success; 54 return success;
51 } 55 }
52 56
57 int LoadLocalePakFromApk(const std::string& app_locale,
58 base::MemoryMappedFile::Region* out_region) {
59 std::string locale_path_within_apk =
60 GetPathForAndroidLocalePakWithinApk(app_locale);
61 if (locale_path_within_apk.empty()) {
62 LOG(WARNING) << "locale_path_within_apk.empty() for locale "
63 << app_locale;
64 return -1;
65 }
66 return base::android::OpenApkAsset(locale_path_within_apk, out_region);
67 }
68
69 std::unique_ptr<DataPack> LoadDataPackFromLocalePak(
70 int locale_pack_fd,
71 const base::MemoryMappedFile::Region& region) {
72 auto data_pack = base::MakeUnique<DataPack>(SCALE_FACTOR_100P);
73 if (!data_pack->LoadFromFileRegion(base::File(locale_pack_fd), region)) {
74 LOG(WARNING) << "failed to load locale.pak";
75 NOTREACHED();
76 return nullptr;
77 }
78 return data_pack;
79 }
80
53 } // namespace 81 } // namespace
54 82
55 void ResourceBundle::LoadCommonResources() { 83 void ResourceBundle::LoadCommonResources() {
56 base::FilePath disk_path; 84 base::FilePath disk_path;
57 PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &disk_path); 85 PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &disk_path);
58 disk_path = disk_path.AppendASCII("chrome_100_percent.pak"); 86 disk_path = disk_path.AppendASCII("chrome_100_percent.pak");
59 if (LoadFromApkOrFile("assets/chrome_100_percent.pak", 87 if (LoadFromApkOrFile("assets/chrome_100_percent.pak",
60 &disk_path, 88 &disk_path,
61 &g_chrome_100_percent_fd, 89 &g_chrome_100_percent_fd,
62 &g_chrome_100_percent_region)) { 90 &g_chrome_100_percent_region)) {
63 AddDataPackFromFileRegion(base::File(g_chrome_100_percent_fd), 91 AddDataPackFromFileRegion(base::File(g_chrome_100_percent_fd),
64 g_chrome_100_percent_region, SCALE_FACTOR_100P); 92 g_chrome_100_percent_region, SCALE_FACTOR_100P);
65 } 93 }
66 } 94 }
67 95
68 bool ResourceBundle::LocaleDataPakExists(const std::string& locale) { 96 bool ResourceBundle::LocaleDataPakExists(const std::string& locale) {
69 if (g_locale_paks_in_apk) { 97 if (g_locale_paks_in_apk) {
70 return !GetPathForAndroidLocalePakWithinApk(locale).empty(); 98 return !GetPathForAndroidLocalePakWithinApk(locale).empty();
71 } 99 }
72 return !GetLocaleFilePath(locale, true).empty(); 100 return !GetLocaleFilePath(locale, true).empty();
73 } 101 }
74 102
75 std::string ResourceBundle::LoadLocaleResources( 103 std::string ResourceBundle::LoadLocaleResources(
76 const std::string& pref_locale) { 104 const std::string& pref_locale) {
77 DCHECK(!locale_resources_data_.get()) << "locale.pak already loaded"; 105 DCHECK(!locale_resources_data_.get() &&
106 !secondary_locale_resources_data_.get())
107 << "locale.pak already loaded";
78 if (g_locale_pack_fd != -1) { 108 if (g_locale_pack_fd != -1) {
79 LOG(WARNING) 109 LOG(WARNING)
80 << "Unexpected (outside of tests): Loading a second locale pak file."; 110 << "Unexpected (outside of tests): Loading a second locale pak file.";
81 } 111 }
82 std::string app_locale = l10n_util::GetApplicationLocale(pref_locale); 112 std::string app_locale = l10n_util::GetApplicationLocale(pref_locale);
113
114 // Load primary locale .pak file.
83 if (g_locale_paks_in_apk) { 115 if (g_locale_paks_in_apk) {
84 std::string locale_path_within_apk = 116 g_locale_pack_fd = LoadLocalePakFromApk(app_locale, &g_locale_pack_region);
85 GetPathForAndroidLocalePakWithinApk(app_locale);
86 if (locale_path_within_apk.empty()) {
87 LOG(WARNING) << "locale_path_within_apk.empty() for locale "
88 << app_locale;
89 return std::string();
90 }
91 g_locale_pack_fd = base::android::OpenApkAsset(locale_path_within_apk,
92 &g_locale_pack_region);
93 } else { 117 } else {
94 base::FilePath locale_file_path = GetOverriddenPakPath(); 118 base::FilePath locale_file_path = GetOverriddenPakPath();
95 if (locale_file_path.empty()) 119 if (locale_file_path.empty())
96 locale_file_path = GetLocaleFilePath(app_locale, true); 120 locale_file_path = GetLocaleFilePath(app_locale, true);
97 121
98 if (locale_file_path.empty()) { 122 if (locale_file_path.empty()) {
99 // It's possible that there is no locale.pak. 123 // It's possible that there is no locale.pak.
100 LOG(WARNING) << "locale_file_path.empty() for locale " << app_locale; 124 LOG(WARNING) << "locale_file_path.empty() for locale " << app_locale;
101 return std::string(); 125 return std::string();
102 } 126 }
103 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; 127 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
104 g_locale_pack_fd = base::File(locale_file_path, flags).TakePlatformFile(); 128 g_locale_pack_fd = base::File(locale_file_path, flags).TakePlatformFile();
105 g_locale_pack_region = base::MemoryMappedFile::Region::kWholeFile; 129 g_locale_pack_region = base::MemoryMappedFile::Region::kWholeFile;
106 } 130 }
107 131
108 std::unique_ptr<DataPack> data_pack(new DataPack(SCALE_FACTOR_100P)); 132 locale_resources_data_ = LoadDataPackFromLocalePak(
109 if (!data_pack->LoadFromFileRegion(base::File(g_locale_pack_fd), 133 g_locale_pack_fd, g_locale_pack_region);
110 g_locale_pack_region)) { 134
111 LOG(ERROR) << "failed to load locale.pak"; 135 if (!locale_resources_data_.get())
112 NOTREACHED();
113 return std::string(); 136 return std::string();
137
138 // Load secondary locale .pak file if it exists. For debug build monochrome,
139 // a secondary locale pak will always be loaded; however, it should be
140 // unnecessary for loading locale resources because the primary locale pak
141 // would have a copy of all the resources in the secondary locale pak.
142 if (g_load_secondary_locale_paks) {
143 g_secondary_locale_pack_fd = LoadLocalePakFromApk(
144 app_locale, &g_secondary_locale_pack_region);
145
146 secondary_locale_resources_data_ = LoadDataPackFromLocalePak(
147 g_secondary_locale_pack_fd, g_secondary_locale_pack_region);
148
149 if (!secondary_locale_resources_data_.get())
150 return std::string();
114 } 151 }
115 152
116 locale_resources_data_ = std::move(data_pack);
117 return app_locale; 153 return app_locale;
118 } 154 }
119 155
120 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) { 156 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) {
121 return GetImageNamed(resource_id); 157 return GetImageNamed(resource_id);
122 } 158 }
123 159
124 void SetLocalePaksStoredInApk(bool value) { 160 void SetLocalePaksStoredInApk(bool value) {
125 g_locale_paks_in_apk = value; 161 g_locale_paks_in_apk = value;
126 } 162 }
127 163
164 void SetLoadSecondaryLocalePaks(bool value) {
165 g_load_secondary_locale_paks = value;
166 }
167
128 void LoadMainAndroidPackFile(const char* path_within_apk, 168 void LoadMainAndroidPackFile(const char* path_within_apk,
129 const base::FilePath& disk_file_path) { 169 const base::FilePath& disk_file_path) {
130 if (LoadFromApkOrFile(path_within_apk, 170 if (LoadFromApkOrFile(path_within_apk,
131 &disk_file_path, 171 &disk_file_path,
132 &g_resources_pack_fd, 172 &g_resources_pack_fd,
133 &g_resources_pack_region)) { 173 &g_resources_pack_region)) {
134 ResourceBundle::GetSharedInstance().AddDataPackFromFileRegion( 174 ResourceBundle::GetSharedInstance().AddDataPackFromFileRegion(
135 base::File(g_resources_pack_fd), g_resources_pack_region, 175 base::File(g_resources_pack_fd), g_resources_pack_region,
136 SCALE_FACTOR_NONE); 176 SCALE_FACTOR_NONE);
137 } 177 }
(...skipping 10 matching lines...) Expand all
148 *out_region = g_chrome_100_percent_region; 188 *out_region = g_chrome_100_percent_region;
149 return g_chrome_100_percent_fd; 189 return g_chrome_100_percent_fd;
150 } 190 }
151 191
152 int GetLocalePackFd(base::MemoryMappedFile::Region* out_region) { 192 int GetLocalePackFd(base::MemoryMappedFile::Region* out_region) {
153 DCHECK_GE(g_locale_pack_fd, 0); 193 DCHECK_GE(g_locale_pack_fd, 0);
154 *out_region = g_locale_pack_region; 194 *out_region = g_locale_pack_region;
155 return g_locale_pack_fd; 195 return g_locale_pack_fd;
156 } 196 }
157 197
198 int GetSecondaryLocalePackFd(base::MemoryMappedFile::Region* out_region) {
199 *out_region = g_secondary_locale_pack_region;
200 return g_secondary_locale_pack_fd;
201 }
202
158 std::string GetPathForAndroidLocalePakWithinApk(const std::string& locale) { 203 std::string GetPathForAndroidLocalePakWithinApk(const std::string& locale) {
159 JNIEnv* env = base::android::AttachCurrentThread(); 204 JNIEnv* env = base::android::AttachCurrentThread();
160 base::android::ScopedJavaLocalRef<jstring> ret = 205 base::android::ScopedJavaLocalRef<jstring> ret =
161 Java_ResourceBundle_getLocalePakResourcePath( 206 Java_ResourceBundle_getLocalePakResourcePath(
162 env, base::android::ConvertUTF8ToJavaString(env, locale)); 207 env, base::android::ConvertUTF8ToJavaString(env, locale));
163 if (ret.obj() == nullptr) { 208 if (ret.obj() == nullptr) {
164 return std::string(); 209 return std::string();
165 } 210 }
166 return base::android::ConvertJavaStringToUTF8(env, ret.obj()); 211 return base::android::ConvertJavaStringToUTF8(env, ret.obj());
167 } 212 }
168 213
169 float GetPrimaryDisplayScale() { 214 float GetPrimaryDisplayScale() {
170 return Java_ResourceBundle_getPrimaryDisplayScale( 215 return Java_ResourceBundle_getPrimaryDisplayScale(
171 base::android::AttachCurrentThread()); 216 base::android::AttachCurrentThread());
172 } 217 }
173 218
174 } // namespace ui 219 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/resource/resource_bundle_android.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698