| Index: ui/base/resource/resource_bundle_android.cc
|
| diff --git a/ui/base/resource/resource_bundle_android.cc b/ui/base/resource/resource_bundle_android.cc
|
| index 9b0ae24bfce1146d80cddf462e25d9ff7e84bcce..809fbcbd3fc8ceade13273ef330207a347071a20 100644
|
| --- a/ui/base/resource/resource_bundle_android.cc
|
| +++ b/ui/base/resource/resource_bundle_android.cc
|
| @@ -8,6 +8,7 @@
|
| #include "base/android/jni_android.h"
|
| #include "base/android/jni_string.h"
|
| #include "base/logging.h"
|
| +#include "base/memory/ptr_util.h"
|
| #include "base/path_service.h"
|
| #include "jni/ResourceBundle_jni.h"
|
| #include "ui/base/l10n/l10n_util.h"
|
| @@ -20,36 +21,63 @@ namespace ui {
|
| namespace {
|
|
|
| bool g_locale_paks_in_apk = false;
|
| +bool g_load_secondary_locale_paks = false;
|
| // It is okay to cache and share these file descriptors since the
|
| // ResourceBundle singleton never closes the handles.
|
| int g_chrome_100_percent_fd = -1;
|
| int g_resources_pack_fd = -1;
|
| int g_locale_pack_fd = -1;
|
| +int g_secondary_locale_pack_fd = -1;
|
| base::MemoryMappedFile::Region g_chrome_100_percent_region;
|
| base::MemoryMappedFile::Region g_resources_pack_region;
|
| base::MemoryMappedFile::Region g_locale_pack_region;
|
| +base::MemoryMappedFile::Region g_secondary_locale_pack_region;
|
|
|
| bool LoadFromApkOrFile(const char* apk_path,
|
| const base::FilePath* disk_path,
|
| - int* fd_out,
|
| - base::MemoryMappedFile::Region* region_out) {
|
| - DCHECK_EQ(*fd_out, -1) << "Attempt to load " << apk_path << " twice.";
|
| + int* out_fd,
|
| + base::MemoryMappedFile::Region* out_region) {
|
| + DCHECK_EQ(*out_fd, -1) << "Attempt to load " << apk_path << " twice.";
|
| if (apk_path != nullptr) {
|
| - *fd_out = base::android::OpenApkAsset(apk_path, region_out);
|
| + *out_fd = base::android::OpenApkAsset(apk_path, out_region);
|
| }
|
| // For unit tests, the file exists on disk.
|
| - if (*fd_out < 0 && disk_path != nullptr) {
|
| + if (*out_fd < 0 && disk_path != nullptr) {
|
| int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
|
| - *fd_out = base::File(*disk_path, flags).TakePlatformFile();
|
| - *region_out = base::MemoryMappedFile::Region::kWholeFile;
|
| + *out_fd = base::File(*disk_path, flags).TakePlatformFile();
|
| + *out_region = base::MemoryMappedFile::Region::kWholeFile;
|
| }
|
| - bool success = *fd_out >= 0;
|
| + bool success = *out_fd >= 0;
|
| if (!success) {
|
| LOG(ERROR) << "Failed to open pak file: " << apk_path;
|
| }
|
| return success;
|
| }
|
|
|
| +int LoadLocalePakFromApk(const std::string& app_locale,
|
| + base::MemoryMappedFile::Region* out_region) {
|
| + std::string locale_path_within_apk =
|
| + GetPathForAndroidLocalePakWithinApk(app_locale);
|
| + if (locale_path_within_apk.empty()) {
|
| + LOG(ERROR) << "locale_path_within_apk.empty() for locale "
|
| + << app_locale;
|
| + return -1;
|
| + }
|
| + return base::android::OpenApkAsset(locale_path_within_apk, out_region);
|
| +}
|
| +
|
| +std::unique_ptr<DataPack> LoadDataPackFromLocalePak(
|
| + int locale_pack_fd,
|
| + const base::MemoryMappedFile::Region& region) {
|
| + std::unique_ptr<DataPack> data_pack(new DataPack(SCALE_FACTOR_100P));
|
| + if (!data_pack->LoadFromFileRegion(base::File(locale_pack_fd), region)) {
|
| + LOG(ERROR) << "failed to load locale.pak";
|
| + NOTREACHED();
|
| + return nullptr;
|
| + }
|
| + return data_pack;
|
| +}
|
| +
|
| } // namespace
|
|
|
| void ResourceBundle::LoadCommonResources() {
|
| @@ -74,22 +102,18 @@ bool ResourceBundle::LocaleDataPakExists(const std::string& locale) {
|
|
|
| std::string ResourceBundle::LoadLocaleResources(
|
| const std::string& pref_locale) {
|
| - DCHECK(!locale_resources_data_.get()) << "locale.pak already loaded";
|
| + DCHECK(!locale_resources_data_.get() &&
|
| + !secondary_locale_resources_data_.get())
|
| + << "locale.pak already loaded";
|
| if (g_locale_pack_fd != -1) {
|
| LOG(WARNING)
|
| << "Unexpected (outside of tests): Loading a second locale pak file.";
|
| }
|
| std::string app_locale = l10n_util::GetApplicationLocale(pref_locale);
|
| +
|
| + // Load primary locale .pak file.
|
| if (g_locale_paks_in_apk) {
|
| - std::string locale_path_within_apk =
|
| - GetPathForAndroidLocalePakWithinApk(app_locale);
|
| - if (locale_path_within_apk.empty()) {
|
| - LOG(WARNING) << "locale_path_within_apk.empty() for locale "
|
| - << app_locale;
|
| - return std::string();
|
| - }
|
| - g_locale_pack_fd = base::android::OpenApkAsset(locale_path_within_apk,
|
| - &g_locale_pack_region);
|
| + g_locale_pack_fd = LoadLocalePakFromApk(app_locale, &g_locale_pack_region);
|
| } else {
|
| base::FilePath locale_file_path = GetOverriddenPakPath();
|
| if (locale_file_path.empty())
|
| @@ -105,15 +129,27 @@ std::string ResourceBundle::LoadLocaleResources(
|
| g_locale_pack_region = base::MemoryMappedFile::Region::kWholeFile;
|
| }
|
|
|
| - std::unique_ptr<DataPack> data_pack(new DataPack(SCALE_FACTOR_100P));
|
| - if (!data_pack->LoadFromFileRegion(base::File(g_locale_pack_fd),
|
| - g_locale_pack_region)) {
|
| - LOG(ERROR) << "failed to load locale.pak";
|
| - NOTREACHED();
|
| + locale_resources_data_ = LoadDataPackFromLocalePak(
|
| + g_locale_pack_fd, g_locale_pack_region);
|
| +
|
| + if (!locale_resources_data_.get())
|
| return std::string();
|
| +
|
| + // Load secondary locale .pak file if it exists. For debug build monochrome,
|
| + // a secondary locale pak will always be loaded; however, it should be
|
| + // unnecessary for loading locale resources because the primary locale pak
|
| + // would have a copy of all the resources in the secondary locale pak.
|
| + if (g_load_secondary_locale_paks) {
|
| + g_secondary_locale_pack_fd = LoadLocalePakFromApk(
|
| + app_locale, &g_secondary_locale_pack_region);
|
| +
|
| + secondary_locale_resources_data_ = LoadDataPackFromLocalePak(
|
| + g_secondary_locale_pack_fd, g_secondary_locale_pack_region);
|
| +
|
| + if (!secondary_locale_resources_data_.get())
|
| + return std::string();
|
| }
|
|
|
| - locale_resources_data_ = std::move(data_pack);
|
| return app_locale;
|
| }
|
|
|
| @@ -125,6 +161,10 @@ void SetLocalePaksStoredInApk(bool value) {
|
| g_locale_paks_in_apk = value;
|
| }
|
|
|
| +void SetLoadSecondaryLocalePaks(bool value) {
|
| + g_load_secondary_locale_paks = value;
|
| +}
|
| +
|
| void LoadMainAndroidPackFile(const char* path_within_apk,
|
| const base::FilePath& disk_file_path) {
|
| if (LoadFromApkOrFile(path_within_apk,
|
| @@ -155,6 +195,11 @@ int GetLocalePackFd(base::MemoryMappedFile::Region* out_region) {
|
| return g_locale_pack_fd;
|
| }
|
|
|
| +int GetSecondaryLocalePackFd(base::MemoryMappedFile::Region* out_region) {
|
| + *out_region = g_secondary_locale_pack_region;
|
| + return g_secondary_locale_pack_fd;
|
| +}
|
| +
|
| std::string GetPathForAndroidLocalePakWithinApk(const std::string& locale) {
|
| JNIEnv* env = base::android::AttachCurrentThread();
|
| base::android::ScopedJavaLocalRef<jstring> ret =
|
|
|