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

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

Issue 2933343002: 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
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* fd_out,
35 base::MemoryMappedFile::Region* region_out) { 39 base::MemoryMappedFile::Region* out_region) {
agrieve 2017/06/29 01:09:53 nit: this now doesn't match the other out param (f
F 2017/06/29 18:31:20 Done. I put "out" in front of "fd/region" because
36 DCHECK_EQ(*fd_out, -1) << "Attempt to load " << apk_path << " twice."; 40 DCHECK_EQ(*fd_out, -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 *fd_out = 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 (*fd_out < 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 *fd_out = 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 = *fd_out >= 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,
agrieve 2017/06/29 01:09:53 nit: might be nice to match the signature of the a
F 2017/06/29 18:31:21 Resolved offline.
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 "
agrieve 2017/06/29 01:09:53 nit: Probably worth using ERROR here
F 2017/06/29 18:31:20 Done.
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 std::unique_ptr<DataPack> data_pack(new DataPack(SCALE_FACTOR_100P));
73 if (!data_pack->LoadFromFileRegion(base::File(locale_pack_fd), region)) {
74 LOG(ERROR) << "failed to load locale.pak";
agrieve 2017/06/29 01:09:53 nit: just << to the NOTREACHED().
F 2017/06/29 18:31:21 Resolved offline.
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.
agrieve 2017/06/29 01:09:53 nit: say why it's unnecessary.
F 2017/06/29 18:31:21 Done.
141 if (g_load_secondary_locale_paks) {
142 g_secondary_locale_pack_fd = LoadLocalePakFromApk(
143 app_locale, &g_secondary_locale_pack_region);
144
145 secondary_locale_resources_data_ = LoadDataPackFromLocalePak(
146 g_secondary_locale_pack_fd, g_secondary_locale_pack_region);
147
148 if (!secondary_locale_resources_data_.get())
agrieve 2017/06/29 01:09:53 nit: probably fine to omit this early return since
F 2017/06/29 18:31:21 Resolved offline.
149 return std::string();
114 } 150 }
115 151
116 locale_resources_data_ = std::move(data_pack);
117 return app_locale; 152 return app_locale;
118 } 153 }
119 154
120 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) { 155 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) {
121 return GetImageNamed(resource_id); 156 return GetImageNamed(resource_id);
122 } 157 }
123 158
124 void SetLocalePaksStoredInApk(bool value) { 159 void SetLocalePaksStoredInApk(bool value) {
125 g_locale_paks_in_apk = value; 160 g_locale_paks_in_apk = value;
126 } 161 }
127 162
163 void SetLoadSecondaryLocalePaks(bool value) {
164 g_load_secondary_locale_paks = value;
165 }
166
128 void LoadMainAndroidPackFile(const char* path_within_apk, 167 void LoadMainAndroidPackFile(const char* path_within_apk,
129 const base::FilePath& disk_file_path) { 168 const base::FilePath& disk_file_path) {
130 if (LoadFromApkOrFile(path_within_apk, 169 if (LoadFromApkOrFile(path_within_apk,
131 &disk_file_path, 170 &disk_file_path,
132 &g_resources_pack_fd, 171 &g_resources_pack_fd,
133 &g_resources_pack_region)) { 172 &g_resources_pack_region)) {
134 ResourceBundle::GetSharedInstance().AddDataPackFromFileRegion( 173 ResourceBundle::GetSharedInstance().AddDataPackFromFileRegion(
135 base::File(g_resources_pack_fd), g_resources_pack_region, 174 base::File(g_resources_pack_fd), g_resources_pack_region,
136 SCALE_FACTOR_NONE); 175 SCALE_FACTOR_NONE);
137 } 176 }
(...skipping 10 matching lines...) Expand all
148 *out_region = g_chrome_100_percent_region; 187 *out_region = g_chrome_100_percent_region;
149 return g_chrome_100_percent_fd; 188 return g_chrome_100_percent_fd;
150 } 189 }
151 190
152 int GetLocalePackFd(base::MemoryMappedFile::Region* out_region) { 191 int GetLocalePackFd(base::MemoryMappedFile::Region* out_region) {
153 DCHECK_GE(g_locale_pack_fd, 0); 192 DCHECK_GE(g_locale_pack_fd, 0);
154 *out_region = g_locale_pack_region; 193 *out_region = g_locale_pack_region;
155 return g_locale_pack_fd; 194 return g_locale_pack_fd;
156 } 195 }
157 196
197 int GetSecondaryLocalePackFd(base::MemoryMappedFile::Region* out_region) {
198 *out_region = g_secondary_locale_pack_region;
199 return g_secondary_locale_pack_fd;
200 }
201
158 std::string GetPathForAndroidLocalePakWithinApk(const std::string& locale) { 202 std::string GetPathForAndroidLocalePakWithinApk(const std::string& locale) {
159 JNIEnv* env = base::android::AttachCurrentThread(); 203 JNIEnv* env = base::android::AttachCurrentThread();
160 base::android::ScopedJavaLocalRef<jstring> ret = 204 base::android::ScopedJavaLocalRef<jstring> ret =
161 Java_ResourceBundle_getLocalePakResourcePath( 205 Java_ResourceBundle_getLocalePakResourcePath(
162 env, base::android::ConvertUTF8ToJavaString(env, locale)); 206 env, base::android::ConvertUTF8ToJavaString(env, locale));
163 if (ret.obj() == nullptr) { 207 if (ret.obj() == nullptr) {
164 return std::string(); 208 return std::string();
165 } 209 }
166 return base::android::ConvertJavaStringToUTF8(env, ret.obj()); 210 return base::android::ConvertJavaStringToUTF8(env, ret.obj());
167 } 211 }
168 212
169 float GetPrimaryDisplayScale() { 213 float GetPrimaryDisplayScale() {
170 return Java_ResourceBundle_getPrimaryDisplayScale( 214 return Java_ResourceBundle_getPrimaryDisplayScale(
171 base::android::AttachCurrentThread()); 215 base::android::AttachCurrentThread());
172 } 216 }
173 217
174 } // namespace ui 218 } // namespace ui
OLDNEW
« tools/resources/filter_resource_whitelist.py ('K') | « 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