| 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 |