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 "jni/ResourceBundle_jni.h" | 12 #include "jni/ResourceBundle_jni.h" |
| 13 #include "ui/base/l10n/l10n_util.h" |
| 14 #include "ui/base/resource/data_pack.h" |
12 #include "ui/base/resource/resource_bundle.h" | 15 #include "ui/base/resource/resource_bundle.h" |
13 | 16 |
14 namespace { | 17 namespace { |
15 // It is okay to cache and share these file descriptors since the | 18 // It is okay to cache and share these file descriptors since the |
16 // ResourceBundle singleton never closes the handles. | 19 // ResourceBundle singleton never closes the handles. |
17 int g_chrome_100_percent_fd = -1; | 20 int g_chrome_100_percent_fd = -1; |
18 int g_resources_pack_fd = -1; | 21 int g_resources_pack_fd = -1; |
| 22 int g_locale_pack_fd = -1; |
19 base::MemoryMappedFile::Region g_chrome_100_percent_region; | 23 base::MemoryMappedFile::Region g_chrome_100_percent_region; |
20 base::MemoryMappedFile::Region g_resources_pack_region; | 24 base::MemoryMappedFile::Region g_resources_pack_region; |
| 25 base::MemoryMappedFile::Region g_locale_pack_region; |
21 bool g_locale_paks_in_apk = false; | 26 bool g_locale_paks_in_apk = false; |
22 } | 27 } |
23 | 28 |
24 namespace ui { | 29 namespace ui { |
25 | 30 |
26 void ResourceBundle::LoadCommonResources() { | 31 void ResourceBundle::LoadCommonResources() { |
27 DCHECK_EQ(g_chrome_100_percent_fd, -1); | 32 DCHECK_EQ(g_chrome_100_percent_fd, -1); |
28 g_chrome_100_percent_fd = base::android::OpenApkAsset( | 33 g_chrome_100_percent_fd = base::android::OpenApkAsset( |
29 "assets/chrome_100_percent.pak", &g_chrome_100_percent_region); | 34 "assets/chrome_100_percent.pak", &g_chrome_100_percent_region); |
30 DCHECK_GE(g_chrome_100_percent_fd, 0); | 35 DCHECK_GE(g_chrome_100_percent_fd, 0); |
31 AddDataPackFromFileRegion(base::File(g_chrome_100_percent_fd), | 36 AddDataPackFromFileRegion(base::File(g_chrome_100_percent_fd), |
32 g_chrome_100_percent_region, SCALE_FACTOR_100P); | 37 g_chrome_100_percent_region, SCALE_FACTOR_100P); |
33 } | 38 } |
34 | 39 |
35 bool ResourceBundle::LocaleDataPakExists(const std::string& locale) { | 40 bool ResourceBundle::LocaleDataPakExists(const std::string& locale) { |
36 if (g_locale_paks_in_apk) { | 41 if (g_locale_paks_in_apk) { |
37 return !GetPathForAndroidLocalePakWithinApk(locale).empty(); | 42 return !GetPathForAndroidLocalePakWithinApk(locale).empty(); |
38 } | 43 } |
39 return !GetLocaleFilePath(locale, true).empty(); | 44 return !GetLocaleFilePath(locale, true).empty(); |
40 } | 45 } |
41 | 46 |
| 47 std::string ResourceBundle::LoadLocaleResources( |
| 48 const std::string& pref_locale) { |
| 49 DCHECK(!locale_resources_data_.get()) << "locale.pak already loaded"; |
| 50 DCHECK_EQ(g_locale_pack_fd, -1); |
| 51 std::string app_locale = l10n_util::GetApplicationLocale(pref_locale); |
| 52 if (g_locale_paks_in_apk) { |
| 53 std::string locale_path_within_apk = |
| 54 GetPathForAndroidLocalePakWithinApk(app_locale); |
| 55 if (locale_path_within_apk.empty()) { |
| 56 LOG(WARNING) << "locale_path_within_apk.empty() for locale " |
| 57 << app_locale; |
| 58 return std::string(); |
| 59 } |
| 60 g_locale_pack_fd = base::android::OpenApkAsset(locale_path_within_apk, |
| 61 &g_locale_pack_region); |
| 62 } else { |
| 63 base::FilePath locale_file_path = GetOverriddenPakPath(); |
| 64 if (locale_file_path.empty()) |
| 65 locale_file_path = GetLocaleFilePath(app_locale, true); |
| 66 |
| 67 if (locale_file_path.empty()) { |
| 68 // It's possible that there is no locale.pak. |
| 69 LOG(WARNING) << "locale_file_path.empty() for locale " << app_locale; |
| 70 return std::string(); |
| 71 } |
| 72 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; |
| 73 g_locale_pack_fd = base::File(locale_file_path, flags).TakePlatformFile(); |
| 74 g_locale_pack_region = base::MemoryMappedFile::Region::kWholeFile; |
| 75 } |
| 76 |
| 77 scoped_ptr<DataPack> data_pack(new DataPack(SCALE_FACTOR_100P)); |
| 78 if (!data_pack->LoadFromFileRegion(base::File(g_locale_pack_fd), |
| 79 g_locale_pack_region)) { |
| 80 UMA_HISTOGRAM_ENUMERATION("ResourceBundle.LoadLocaleResourcesError", |
| 81 logging::GetLastSystemErrorCode(), 16000); |
| 82 LOG(ERROR) << "failed to load locale.pak"; |
| 83 NOTREACHED(); |
| 84 return std::string(); |
| 85 } |
| 86 |
| 87 locale_resources_data_.reset(data_pack.release()); |
| 88 return app_locale; |
| 89 } |
| 90 |
42 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id, ImageRTL rtl) { | 91 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id, ImageRTL rtl) { |
43 // Flipped image is not used on Android. | 92 // Flipped image is not used on Android. |
44 DCHECK_EQ(rtl, RTL_DISABLED); | 93 DCHECK_EQ(rtl, RTL_DISABLED); |
45 return GetImageNamed(resource_id); | 94 return GetImageNamed(resource_id); |
46 } | 95 } |
47 | 96 |
48 void SetLocalePaksStoredInApk(bool value) { | 97 void SetLocalePaksStoredInApk(bool value) { |
49 g_locale_paks_in_apk = value; | 98 g_locale_paks_in_apk = value; |
50 } | 99 } |
51 | 100 |
| 101 bool GetLocalePaksStoredInApk() { |
| 102 return g_locale_paks_in_apk; |
| 103 } |
| 104 |
52 void LoadMainAndroidPackFile() { | 105 void LoadMainAndroidPackFile() { |
53 DCHECK_EQ(g_resources_pack_fd, -1); | 106 DCHECK_EQ(g_resources_pack_fd, -1); |
54 g_resources_pack_fd = base::android::OpenApkAsset("assets/resources.pak", | 107 g_resources_pack_fd = base::android::OpenApkAsset("assets/resources.pak", |
55 &g_resources_pack_region); | 108 &g_resources_pack_region); |
56 DCHECK_GE(g_resources_pack_fd, 0); | 109 DCHECK_GE(g_resources_pack_fd, 0); |
57 ResourceBundle::GetSharedInstance().AddDataPackFromFileRegion( | 110 ResourceBundle::GetSharedInstance().AddDataPackFromFileRegion( |
58 base::File(g_resources_pack_fd), g_resources_pack_region, | 111 base::File(g_resources_pack_fd), g_resources_pack_region, |
59 SCALE_FACTOR_NONE); | 112 SCALE_FACTOR_NONE); |
60 } | 113 } |
61 | 114 |
62 int GetMainAndroidPackFd(base::MemoryMappedFile::Region* out_region) { | 115 int GetMainAndroidPackFd(base::MemoryMappedFile::Region* out_region) { |
63 DCHECK_GE(g_resources_pack_fd, 0); | 116 DCHECK_GE(g_resources_pack_fd, 0); |
64 *out_region = g_resources_pack_region; | 117 *out_region = g_resources_pack_region; |
65 return g_resources_pack_fd; | 118 return g_resources_pack_fd; |
66 } | 119 } |
67 | 120 |
68 int GetCommonResourcesPackFd(base::MemoryMappedFile::Region* out_region) { | 121 int GetCommonResourcesPackFd(base::MemoryMappedFile::Region* out_region) { |
69 DCHECK_GE(g_chrome_100_percent_fd, 0); | 122 DCHECK_GE(g_chrome_100_percent_fd, 0); |
70 *out_region = g_chrome_100_percent_region; | 123 *out_region = g_chrome_100_percent_region; |
71 return g_chrome_100_percent_fd; | 124 return g_chrome_100_percent_fd; |
72 } | 125 } |
73 | 126 |
| 127 int GetLocalePackFd(base::MemoryMappedFile::Region* out_region) { |
| 128 DCHECK_GE(g_locale_pack_fd, 0); |
| 129 *out_region = g_locale_pack_region; |
| 130 return g_locale_pack_fd; |
| 131 } |
| 132 |
74 std::string GetPathForAndroidLocalePakWithinApk(const std::string& locale) { | 133 std::string GetPathForAndroidLocalePakWithinApk(const std::string& locale) { |
75 JNIEnv* env = base::android::AttachCurrentThread(); | 134 JNIEnv* env = base::android::AttachCurrentThread(); |
76 base::android::ScopedJavaLocalRef<jstring> ret = | 135 base::android::ScopedJavaLocalRef<jstring> ret = |
77 Java_ResourceBundle_getLocalePakResourcePath( | 136 Java_ResourceBundle_getLocalePakResourcePath( |
78 env, base::android::ConvertUTF8ToJavaString(env, locale).obj()); | 137 env, base::android::ConvertUTF8ToJavaString(env, locale).obj()); |
79 if (ret.obj() == nullptr) { | 138 if (ret.obj() == nullptr) { |
80 return std::string(); | 139 return std::string(); |
81 } | 140 } |
82 return base::android::ConvertJavaStringToUTF8(env, ret.obj()); | 141 return base::android::ConvertJavaStringToUTF8(env, ret.obj()); |
83 } | 142 } |
84 | 143 |
85 bool RegisterResourceBundleAndroid(JNIEnv* env) { | 144 bool RegisterResourceBundleAndroid(JNIEnv* env) { |
86 return RegisterNativesImpl(env); | 145 return RegisterNativesImpl(env); |
87 } | 146 } |
88 | 147 |
89 } | 148 } |
OLD | NEW |