AssetManager2: Add GetResourceId
Add ability to lookup a resource by name.
Test: make libandroidfw_tests
Change-Id: I262ba5ce4c9892458226fbdb44cf21f9877fb92d
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index cb589ec..db72f48 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -34,6 +34,7 @@
#include "androidfw/ByteBucketArray.h"
#include "androidfw/Chunk.h"
+#include "androidfw/ResourceUtils.h"
#include "androidfw/Util.h"
using android::base::StringPrintf;
@@ -181,9 +182,9 @@
LoadedArscEntry* out_entry, ResTable_config* out_selected_config,
uint32_t* out_flags) const {
ATRACE_CALL();
- const uint8_t package_id = util::get_package_id(resid);
- const uint8_t type_id = util::get_type_id(resid);
- const uint16_t entry_id = util::get_entry_id(resid);
+ const uint8_t package_id = get_package_id(resid);
+ const uint8_t type_id = get_type_id(resid);
+ const uint16_t entry_id = get_entry_id(resid);
if (type_id == 0) {
LOG(ERROR) << "Invalid ID 0x" << std::hex << resid << std::dec << ".";
@@ -200,7 +201,7 @@
}
const LoadedPackage* LoadedArsc::GetPackageForId(uint32_t resid) const {
- const uint8_t package_id = util::get_package_id(resid);
+ const uint8_t package_id = get_package_id(resid);
for (const auto& loaded_package : packages_) {
if (loaded_package->package_id_ == package_id) {
return loaded_package.get();
@@ -372,6 +373,45 @@
}
}
+uint32_t LoadedPackage::FindEntryByName(const std::u16string& type_name,
+ const std::u16string& entry_name) const {
+ ssize_t type_idx = type_string_pool_.indexOfString(type_name.data(), type_name.size());
+ if (type_idx < 0) {
+ return 0u;
+ }
+
+ ssize_t key_idx = key_string_pool_.indexOfString(entry_name.data(), entry_name.size());
+ if (key_idx < 0) {
+ return 0u;
+ }
+
+ const TypeSpec* type_spec = type_specs_[type_idx].get();
+ if (type_spec == nullptr) {
+ return 0u;
+ }
+
+ for (size_t ti = 0; ti < type_spec->type_count; ti++) {
+ const Type* type = &type_spec->types[ti];
+ size_t entry_count = dtohl(type->type->entryCount);
+ for (size_t entry_idx = 0; entry_idx < entry_count; entry_idx++) {
+ const uint32_t* entry_offsets = reinterpret_cast<const uint32_t*>(
+ reinterpret_cast<const uint8_t*>(type->type) + dtohs(type->type->header.headerSize));
+ const uint32_t offset = dtohl(entry_offsets[entry_idx]);
+ if (offset != ResTable_type::NO_ENTRY) {
+ const ResTable_entry* entry =
+ reinterpret_cast<const ResTable_entry*>(reinterpret_cast<const uint8_t*>(type->type) +
+ dtohl(type->type->entriesStart) + offset);
+ if (dtohl(entry->key.index) == static_cast<uint32_t>(key_idx)) {
+ // The package ID will be overridden by the caller (due to runtime assignment of package
+ // IDs for shared libraries).
+ return make_resid(0x00, type_idx + type_id_offset_ + 1, entry_idx);
+ }
+ }
+ }
+ }
+ return 0u;
+}
+
std::unique_ptr<LoadedPackage> LoadedPackage::Load(const Chunk& chunk) {
ATRACE_CALL();
std::unique_ptr<LoadedPackage> loaded_package{new LoadedPackage()};