summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yurii Zubrytskyi <zyy@google.com> 2025-03-24 10:48:09 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2025-03-24 10:48:09 -0700
commitf882c532b142f9a5b88676e2efebcc021b61a211 (patch)
tree807372016dc0155ba2f281f7343decfa69bdff3a
parent8c33f1cb2845e31409bc78cd9f81e976a4f43517 (diff)
parent984a84eed846b5c04265057075d574b440564168 (diff)
Merge "[res] A bit more efficient locale collection" into main
-rw-r--r--core/jni/android_util_AssetManager.cpp4
-rw-r--r--libs/androidfw/AssetManager2.cpp9
-rw-r--r--libs/androidfw/LoadedArsc.cpp12
-rw-r--r--libs/androidfw/include/androidfw/AssetManager2.h4
-rw-r--r--libs/androidfw/include/androidfw/LoadedArsc.h3
-rw-r--r--libs/androidfw/tests/AssetManager2_bench.cpp2
-rw-r--r--libs/androidfw/tests/AssetManager2_test.cpp2
7 files changed, 20 insertions, 16 deletions
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index d3d838a1675b..e1c72c34d63f 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -1077,8 +1077,8 @@ static jstring NativeGetLastResourceResolution(JNIEnv* env,
static jobjectArray NativeGetLocales(JNIEnv* env, jclass /*class*/, jlong ptr,
jboolean exclude_system) {
auto assetmanager = LockAndStartAssetManager(ptr);
- std::set<std::string> locales =
- assetmanager->GetResourceLocales(exclude_system, true /*merge_equivalent_languages*/);
+ auto locales =
+ assetmanager->GetResourceLocales(exclude_system, true /*merge_equivalent_languages*/);
jobjectArray array = env->NewObjectArray(locales.size(), g_stringClass, nullptr);
if (array == nullptr) {
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 6caae4c7623e..508750720690 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -603,12 +603,12 @@ base::expected<std::set<ResTable_config>, IOError> AssetManager2::GetResourceCon
return configurations;
}
-std::set<std::string> AssetManager2::GetResourceLocales(bool exclude_system,
- bool merge_equivalent_languages) const {
+LoadedPackage::Locales AssetManager2::GetResourceLocales(
+ bool exclude_system, bool merge_equivalent_languages) const {
ATRACE_NAME("AssetManager::GetResourceLocales");
auto op = StartOperation();
- std::set<std::string> locales;
+ LoadedPackage::Locales locales;
const auto non_system_overlays =
exclude_system ? GetNonSystemOverlays() : std::set<ApkAssetsPtr>();
@@ -622,8 +622,7 @@ std::set<std::string> AssetManager2::GetResourceLocales(bool exclude_system,
if (!non_system_overlays.empty()) {
// Exclude overlays that target only system resources.
const auto& apk_assets = GetApkAssets(package_group.cookies_[i]);
- if (apk_assets && apk_assets->IsOverlay() &&
- non_system_overlays.find(apk_assets) == non_system_overlays.end()) {
+ if (apk_assets && apk_assets->IsOverlay() && !non_system_overlays.contains(apk_assets)) {
continue;
}
}
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index d9166a16cdea..7cebb6d79502 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -361,14 +361,18 @@ base::expected<std::monostate, IOError> LoadedPackage::CollectConfigurations(
return {};
}
-void LoadedPackage::CollectLocales(bool canonicalize, std::set<std::string>* out_locales) const {
- char temp_locale[RESTABLE_MAX_LOCALE_LEN];
+void LoadedPackage::CollectLocales(bool canonicalize,
+ Locales* out_locales) const {
for (const auto& type_spec : type_specs_) {
for (const auto& type_entry : type_spec.second.type_entries) {
if (type_entry.config.locale != 0) {
+ char temp_locale[RESTABLE_MAX_LOCALE_LEN];
type_entry.config.getBcp47Locale(temp_locale, canonicalize);
- std::string locale(temp_locale);
- out_locales->insert(std::move(locale));
+ auto locale_sv = std::string_view(temp_locale);
+ if (auto it = out_locales->lower_bound(locale_sv);
+ it == out_locales->end() || *it != locale_sv) {
+ out_locales->emplace_hint(it, locale_sv);
+ }
}
}
}
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index ffcef944a6ba..e312042cf7da 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -189,8 +189,8 @@ class AssetManager2 {
// ('android' package, other libraries) will be excluded from the list.
// If `merge_equivalent_languages` is set to true, resource locales will be canonicalized
// and de-duped in the resulting list.
- std::set<std::string> GetResourceLocales(bool exclude_system = false,
- bool merge_equivalent_languages = false) const;
+ LoadedPackage::Locales GetResourceLocales(
+ bool exclude_system = false, bool merge_equivalent_languages = false) const;
// Searches the set of APKs loaded by this AssetManager and opens the first one found located
// in the assets/ directory.
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index 413b27829474..eb99dc7b8eff 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -238,7 +238,8 @@ class LoadedPackage {
// Populates a set of strings representing locales.
// If `canonicalize` is set to true, each locale is transformed into its canonical format
// before being inserted into the set. This may cause some equivalent locales to de-dupe.
- void CollectLocales(bool canonicalize, std::set<std::string>* out_locales) const;
+ using Locales = std::set<std::string, std::less<>>;
+ void CollectLocales(bool canonicalize, Locales* out_locales) const;
// type_idx is TT - 1 from 0xPPTTEEEE.
inline const TypeSpec* GetTypeSpecByTypeIndex(uint8_t type_index) const {
diff --git a/libs/androidfw/tests/AssetManager2_bench.cpp b/libs/androidfw/tests/AssetManager2_bench.cpp
index 136f5ea639a1..c469817d3595 100644
--- a/libs/androidfw/tests/AssetManager2_bench.cpp
+++ b/libs/androidfw/tests/AssetManager2_bench.cpp
@@ -191,7 +191,7 @@ static void BM_AssetManagerGetResourceLocales(benchmark::State& state) {
assets.SetApkAssets({apk});
for (auto&& _ : state) {
- std::set<std::string> locales =
+ auto locales =
assets.GetResourceLocales(false /*exclude_system*/, true /*merge_equivalent_languages*/);
benchmark::DoNotOptimize(locales);
}
diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp
index 948437230ecc..a691c5dabfcb 100644
--- a/libs/androidfw/tests/AssetManager2_test.cpp
+++ b/libs/androidfw/tests/AssetManager2_test.cpp
@@ -628,7 +628,7 @@ TEST_F(AssetManager2Test, GetResourceLocales) {
AssetManager2 assetmanager;
assetmanager.SetApkAssets({system_assets_, basic_de_fr_assets_});
- std::set<std::string> locales = assetmanager.GetResourceLocales();
+ auto locales = assetmanager.GetResourceLocales();
// We expect the locale sv from the system assets, and de and fr from basic_de_fr assets.
EXPECT_EQ(3u, locales.size());