AssetManager2: Add other support methods
- Add GetResourceConfigurations()
- Add GetResourceLocales()
- Add ResolveReference()
- Add stub for GetResourceId()
- Change LoadedArsc and ApkAssets factory method to return const
Test: make libandroidfw_tests
Change-Id: Ia797dc9381a523b1a3e7029048a413e544730379
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index d2eff65..542a125 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -18,6 +18,8 @@
#include "androidfw/AssetManager2.h"
+#include <set>
+
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
#include "utils/ByteOrder.h"
@@ -143,6 +145,36 @@
}
}
+std::set<ResTable_config> AssetManager2::GetResourceConfigurations(bool exclude_system,
+ bool exclude_mipmap) {
+ ATRACE_CALL();
+ std::set<ResTable_config> configurations;
+ for (const PackageGroup& package_group : package_groups_) {
+ for (const LoadedPackage* package : package_group.packages_) {
+ if (exclude_system && package->IsSystem()) {
+ continue;
+ }
+ package->CollectConfigurations(exclude_mipmap, &configurations);
+ }
+ }
+ return configurations;
+}
+
+std::set<std::string> AssetManager2::GetResourceLocales(bool exclude_system,
+ bool merge_equivalent_languages) {
+ ATRACE_CALL();
+ std::set<std::string> locales;
+ for (const PackageGroup& package_group : package_groups_) {
+ for (const LoadedPackage* package : package_group.packages_) {
+ if (exclude_system && package->IsSystem()) {
+ continue;
+ }
+ package->CollectLocales(merge_equivalent_languages, &locales);
+ }
+ }
+ return locales;
+}
+
std::unique_ptr<Asset> AssetManager2::Open(const std::string& filename, Asset::AccessMode mode) {
const std::string new_path = "assets/" + filename;
return OpenNonAsset(new_path, mode);
@@ -325,8 +357,15 @@
if (dtohl(entry.entry->flags) & ResTable_entry::FLAG_COMPLEX) {
if (!may_be_bag) {
LOG(ERROR) << base::StringPrintf("Resource %08x is a complex map type.", resid);
+ return kInvalidCookie;
}
- return kInvalidCookie;
+
+ // Create a reference since we can't represent this complex type as a Res_value.
+ out_value->dataType = Res_value::TYPE_REFERENCE;
+ out_value->data = resid;
+ *out_selected_config = config;
+ *out_flags = flags;
+ return cookie;
}
const Res_value* device_value = reinterpret_cast<const Res_value*>(
@@ -341,6 +380,37 @@
return cookie;
}
+ApkAssetsCookie AssetManager2::ResolveReference(ApkAssetsCookie cookie, Res_value* in_out_value,
+ ResTable_config* in_out_selected_config,
+ uint32_t* in_out_flags,
+ ResTable_ref* out_last_reference) {
+ ATRACE_CALL();
+ constexpr const int kMaxIterations = 20;
+
+ out_last_reference->ident = 0u;
+ for (size_t iteration = 0u; in_out_value->dataType == Res_value::TYPE_REFERENCE &&
+ in_out_value->data != 0u && iteration < kMaxIterations;
+ iteration++) {
+ if (out_last_reference != nullptr) {
+ out_last_reference->ident = in_out_value->data;
+ }
+ uint32_t new_flags = 0u;
+ cookie = GetResource(in_out_value->data, true /*may_be_bag*/, 0u /*density_override*/,
+ in_out_value, in_out_selected_config, &new_flags);
+ if (cookie == kInvalidCookie) {
+ return kInvalidCookie;
+ }
+ if (in_out_flags != nullptr) {
+ *in_out_flags |= new_flags;
+ }
+ if (out_last_reference->ident == in_out_value->data) {
+ // This reference can't be resolved, so exit now and let the caller deal with it.
+ return cookie;
+ }
+ }
+ return cookie;
+}
+
const ResolvedBag* AssetManager2::GetBag(uint32_t resid) {
ATRACE_CALL();
@@ -501,6 +571,15 @@
return result;
}
+uint32_t AssetManager2::GetResourceId(const std::string& resource_name,
+ const std::string& fallback_type,
+ const std::string& fallback_package) {
+ (void)resource_name;
+ (void)fallback_type;
+ (void)fallback_package;
+ return 0u;
+}
+
void AssetManager2::InvalidateCaches(uint32_t diff) {
if (diff == 0xffffffffu) {
// Everything must go.