OLD | NEW |
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/metrics/histogram.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" |
| 14 #include "ui/base/l10n/l10n_util.h" |
| 15 #include "ui/base/resource/data_pack.h" |
13 #include "ui/base/resource/resource_bundle.h" | 16 #include "ui/base/resource/resource_bundle.h" |
14 #include "ui/base/ui_base_paths.h" | 17 #include "ui/base/ui_base_paths.h" |
15 | 18 |
16 namespace ui { | 19 namespace ui { |
17 | 20 |
18 namespace { | 21 namespace { |
19 | 22 |
20 bool g_locale_paks_in_apk = false; | 23 bool g_locale_paks_in_apk = false; |
21 // It is okay to cache and share these file descriptors since the | 24 // It is okay to cache and share these file descriptors since the |
22 // ResourceBundle singleton never closes the handles. | 25 // ResourceBundle singleton never closes the handles. |
23 int g_chrome_100_percent_fd = -1; | 26 int g_chrome_100_percent_fd = -1; |
24 int g_resources_pack_fd = -1; | 27 int g_resources_pack_fd = -1; |
| 28 int g_locale_pack_fd = -1; |
25 base::MemoryMappedFile::Region g_chrome_100_percent_region; | 29 base::MemoryMappedFile::Region g_chrome_100_percent_region; |
26 base::MemoryMappedFile::Region g_resources_pack_region; | 30 base::MemoryMappedFile::Region g_resources_pack_region; |
| 31 base::MemoryMappedFile::Region g_locale_pack_region; |
27 | 32 |
28 bool LoadFromApkOrFile(const char* apk_path, | 33 bool LoadFromApkOrFile(const char* apk_path, |
29 const base::FilePath* disk_path, | 34 const base::FilePath* disk_path, |
30 int* fd_out, | 35 int* fd_out, |
31 base::MemoryMappedFile::Region* region_out) { | 36 base::MemoryMappedFile::Region* region_out) { |
32 DCHECK_EQ(*fd_out, -1) << "Attempt to load " << apk_path << " twice."; | 37 DCHECK_EQ(*fd_out, -1) << "Attempt to load " << apk_path << " twice."; |
33 if (apk_path != nullptr) { | 38 if (apk_path != nullptr) { |
34 *fd_out = base::android::OpenApkAsset(apk_path, region_out); | 39 *fd_out = base::android::OpenApkAsset(apk_path, region_out); |
35 } | 40 } |
36 // For unit tests, the file exists on disk. | 41 // For unit tests, the file exists on disk. |
(...skipping 24 matching lines...) Expand all Loading... |
61 } | 66 } |
62 } | 67 } |
63 | 68 |
64 bool ResourceBundle::LocaleDataPakExists(const std::string& locale) { | 69 bool ResourceBundle::LocaleDataPakExists(const std::string& locale) { |
65 if (g_locale_paks_in_apk) { | 70 if (g_locale_paks_in_apk) { |
66 return !GetPathForAndroidLocalePakWithinApk(locale).empty(); | 71 return !GetPathForAndroidLocalePakWithinApk(locale).empty(); |
67 } | 72 } |
68 return !GetLocaleFilePath(locale, true).empty(); | 73 return !GetLocaleFilePath(locale, true).empty(); |
69 } | 74 } |
70 | 75 |
| 76 std::string ResourceBundle::LoadLocaleResources( |
| 77 const std::string& pref_locale) { |
| 78 DCHECK(!locale_resources_data_.get()) << "locale.pak already loaded"; |
| 79 if (g_locale_pack_fd != -1) { |
| 80 LOG(WARNING) |
| 81 << "Unexpected (outside of tests): Loading a second locale pak file."; |
| 82 } |
| 83 std::string app_locale = l10n_util::GetApplicationLocale(pref_locale); |
| 84 if (g_locale_paks_in_apk) { |
| 85 std::string locale_path_within_apk = |
| 86 GetPathForAndroidLocalePakWithinApk(app_locale); |
| 87 if (locale_path_within_apk.empty()) { |
| 88 LOG(WARNING) << "locale_path_within_apk.empty() for locale " |
| 89 << app_locale; |
| 90 return std::string(); |
| 91 } |
| 92 g_locale_pack_fd = base::android::OpenApkAsset(locale_path_within_apk, |
| 93 &g_locale_pack_region); |
| 94 } else { |
| 95 base::FilePath locale_file_path = GetOverriddenPakPath(); |
| 96 if (locale_file_path.empty()) |
| 97 locale_file_path = GetLocaleFilePath(app_locale, true); |
| 98 |
| 99 if (locale_file_path.empty()) { |
| 100 // It's possible that there is no locale.pak. |
| 101 LOG(WARNING) << "locale_file_path.empty() for locale " << app_locale; |
| 102 return std::string(); |
| 103 } |
| 104 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; |
| 105 g_locale_pack_fd = base::File(locale_file_path, flags).TakePlatformFile(); |
| 106 g_locale_pack_region = base::MemoryMappedFile::Region::kWholeFile; |
| 107 } |
| 108 |
| 109 scoped_ptr<DataPack> data_pack(new DataPack(SCALE_FACTOR_100P)); |
| 110 if (!data_pack->LoadFromFileRegion(base::File(g_locale_pack_fd), |
| 111 g_locale_pack_region)) { |
| 112 UMA_HISTOGRAM_ENUMERATION("ResourceBundle.LoadLocaleResourcesError", |
| 113 logging::GetLastSystemErrorCode(), 16000); |
| 114 LOG(ERROR) << "failed to load locale.pak"; |
| 115 NOTREACHED(); |
| 116 return std::string(); |
| 117 } |
| 118 |
| 119 locale_resources_data_.reset(data_pack.release()); |
| 120 return app_locale; |
| 121 } |
| 122 |
71 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id, ImageRTL rtl) { | 123 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id, ImageRTL rtl) { |
72 // Flipped image is not used on Android. | 124 // Flipped image is not used on Android. |
73 DCHECK_EQ(rtl, RTL_DISABLED); | 125 DCHECK_EQ(rtl, RTL_DISABLED); |
74 return GetImageNamed(resource_id); | 126 return GetImageNamed(resource_id); |
75 } | 127 } |
76 | 128 |
77 void SetLocalePaksStoredInApk(bool value) { | 129 void SetLocalePaksStoredInApk(bool value) { |
78 g_locale_paks_in_apk = value; | 130 g_locale_paks_in_apk = value; |
79 } | 131 } |
80 | 132 |
(...skipping 14 matching lines...) Expand all Loading... |
95 *out_region = g_resources_pack_region; | 147 *out_region = g_resources_pack_region; |
96 return g_resources_pack_fd; | 148 return g_resources_pack_fd; |
97 } | 149 } |
98 | 150 |
99 int GetCommonResourcesPackFd(base::MemoryMappedFile::Region* out_region) { | 151 int GetCommonResourcesPackFd(base::MemoryMappedFile::Region* out_region) { |
100 DCHECK_GE(g_chrome_100_percent_fd, 0); | 152 DCHECK_GE(g_chrome_100_percent_fd, 0); |
101 *out_region = g_chrome_100_percent_region; | 153 *out_region = g_chrome_100_percent_region; |
102 return g_chrome_100_percent_fd; | 154 return g_chrome_100_percent_fd; |
103 } | 155 } |
104 | 156 |
| 157 int GetLocalePackFd(base::MemoryMappedFile::Region* out_region) { |
| 158 DCHECK_GE(g_locale_pack_fd, 0); |
| 159 *out_region = g_locale_pack_region; |
| 160 return g_locale_pack_fd; |
| 161 } |
| 162 |
105 std::string GetPathForAndroidLocalePakWithinApk(const std::string& locale) { | 163 std::string GetPathForAndroidLocalePakWithinApk(const std::string& locale) { |
106 JNIEnv* env = base::android::AttachCurrentThread(); | 164 JNIEnv* env = base::android::AttachCurrentThread(); |
107 base::android::ScopedJavaLocalRef<jstring> ret = | 165 base::android::ScopedJavaLocalRef<jstring> ret = |
108 Java_ResourceBundle_getLocalePakResourcePath( | 166 Java_ResourceBundle_getLocalePakResourcePath( |
109 env, base::android::ConvertUTF8ToJavaString(env, locale).obj()); | 167 env, base::android::ConvertUTF8ToJavaString(env, locale).obj()); |
110 if (ret.obj() == nullptr) { | 168 if (ret.obj() == nullptr) { |
111 return std::string(); | 169 return std::string(); |
112 } | 170 } |
113 return base::android::ConvertJavaStringToUTF8(env, ret.obj()); | 171 return base::android::ConvertJavaStringToUTF8(env, ret.obj()); |
114 } | 172 } |
115 | 173 |
116 bool RegisterResourceBundleAndroid(JNIEnv* env) { | 174 bool RegisterResourceBundleAndroid(JNIEnv* env) { |
117 return RegisterNativesImpl(env); | 175 return RegisterNativesImpl(env); |
118 } | 176 } |
119 | 177 |
120 } // namespace ui | 178 } // namespace ui |
OLD | NEW |