summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/idmap2/idmap2d/Idmap2Service.h2
-rw-r--r--cmds/idmap2/include/idmap2/BinaryStreamVisitor.h3
-rw-r--r--cmds/idmap2/include/idmap2/Idmap.h118
-rw-r--r--cmds/idmap2/include/idmap2/PrettyPrintVisitor.h3
-rw-r--r--cmds/idmap2/include/idmap2/RawPrintVisitor.h4
-rw-r--r--cmds/idmap2/include/idmap2/ResourceMapping.h21
-rw-r--r--cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp34
-rw-r--r--cmds/idmap2/libidmap2/Idmap.cpp86
-rw-r--r--cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp65
-rw-r--r--cmds/idmap2/libidmap2/RawPrintVisitor.cpp85
-rw-r--r--cmds/idmap2/libidmap2/ResourceMapping.cpp56
-rw-r--r--cmds/idmap2/tests/BinaryStreamVisitorTests.cpp13
-rw-r--r--cmds/idmap2/tests/Idmap2BinaryTests.cpp8
-rw-r--r--cmds/idmap2/tests/IdmapTests.cpp114
-rw-r--r--cmds/idmap2/tests/PrettyPrintVisitorTests.cpp5
-rw-r--r--cmds/idmap2/tests/RawPrintVisitorTests.cpp24
-rw-r--r--cmds/idmap2/tests/ResourceMappingTests.cpp180
-rw-r--r--cmds/idmap2/tests/TestConstants.h2
-rw-r--r--cmds/idmap2/tests/TestHelpers.h90
-rw-r--r--libs/androidfw/AssetManager2.cpp51
-rw-r--r--libs/androidfw/Idmap.cpp121
-rw-r--r--libs/androidfw/include/androidfw/Idmap.h36
-rw-r--r--libs/androidfw/include/androidfw/ResourceTypes.h67
-rw-r--r--libs/androidfw/tests/data/overlay/overlay.apkbin2992 -> 2988 bytes
-rw-r--r--libs/androidfw/tests/data/overlay/overlay.idmapbin1090 -> 1092 bytes
25 files changed, 665 insertions, 523 deletions
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.h b/cmds/idmap2/idmap2d/Idmap2Service.h
index abee999dd2b2..0127e874b444 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.h
+++ b/cmds/idmap2/idmap2d/Idmap2Service.h
@@ -20,6 +20,8 @@
#include <android-base/unique_fd.h>
#include <binder/BinderService.h>
+#include <string>
+
#include "android/os/BnIdmap2.h"
namespace android::os {
diff --git a/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h b/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h
index ff45b1407dea..bf31cbf8d4f7 100644
--- a/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h
+++ b/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h
@@ -36,12 +36,11 @@ class BinaryStreamVisitor : public Visitor {
void visit(const IdmapData::Header& header) override;
private:
- void Write(const void* value, size_t length);
void Write8(uint8_t value);
void Write16(uint16_t value);
void Write32(uint32_t value);
void WriteString256(const StringPiece& value);
- void WriteString(const std::string& value);
+ void WriteString(const StringPiece& value);
std::ostream& stream_;
};
diff --git a/cmds/idmap2/include/idmap2/Idmap.h b/cmds/idmap2/include/idmap2/Idmap.h
index 0f05592b70f3..a35fad9d686c 100644
--- a/cmds/idmap2/include/idmap2/Idmap.h
+++ b/cmds/idmap2/include/idmap2/Idmap.h
@@ -17,48 +17,45 @@
/*
* # idmap file format (current version)
*
- * idmap := header data*
- * header := magic version target_crc overlay_crc target_path overlay_path debug_info
- * data := data_header data_block*
- * data_header := target_package_id types_count
- * data_block := target_type overlay_type entry_count entry_offset entry*
- * overlay_path := string256
- * target_path := string256
- * debug_info := string
- * string := <uint32_t> <uint8_t>+ '\0'+
- * entry := <uint32_t>
- * entry_count := <uint16_t>
- * entry_offset := <uint16_t>
- * magic := <uint32_t>
- * overlay_crc := <uint32_t>
- * overlay_type := <uint16_t>
- * string256 := <uint8_t>[256]
- * target_crc := <uint32_t>
- * target_package_id := <uint16_t>
- * target_type := <uint16_t>
- * types_count := <uint16_t>
- * version := <uint32_t>
+ * idmap := header data*
+ * header := magic version target_crc overlay_crc fulfilled_policies
+ * enforce_overlayable target_path overlay_path debug_info
+ * data := data_header target_entry* target_inline_entry* overlay_entry*
+ * string_pool
+ * data_header := target_package_id overlay_package_id padding(2) target_entry_count
+ * target_inline_entry_count overlay_entry_count string_pool_index
+ * target_entry := target_id overlay_id
+ * target_inline_entry := target_id Res_value::size padding(1) Res_value::type
+ * Res_value::value
+ * overlay_entry := overlay_id target_id
*
- *
- * # idmap file format changelog
- * ## v1
- * - Identical to idmap v1.
- *
- * ## v2
- * - Entries are no longer separated by type into type specific data blocks.
- * - Added overlay-indexed target resource id lookup capabilities.
- * - Target and overlay entries are stored as a sparse array in the data block. The target entries
- * array maps from target resource id to overlay data type and value and the array is sorted by
- * target resource id. The overlay entries array maps from overlay resource id to target resource
- * id and the array is sorted by overlay resource id. It is important for both arrays to be sorted
- * to allow for O(log(number_of_overlaid_resources)) performance when looking up resource
- * mappings at runtime.
- * - Idmap can now encode a type and value to override a resource without needing a table entry.
- * - A string pool block is included to retrieve the value of strings that do not have a resource
- * table entry.
- *
- * ## v3
- * - Add 'debug' block to IdmapHeader.
+ * debug_info := string
+ * enforce_overlayable := <uint32_t>
+ * fulfilled_policies := <uint32_t>
+ * magic := <uint32_t>
+ * overlay_crc := <uint32_t>
+ * overlay_entry_count := <uint32_t>
+ * overlay_id := <uint32_t>
+ * overlay_package_id := <uint8_t>
+ * overlay_path := string256
+ * padding(n) := <uint8_t>[n]
+ * Res_value::size := <uint16_t>
+ * Res_value::type := <uint8_t>
+ * Res_value::value := <uint32_t>
+ * string := <uint32_t> <uint8_t>+ padding(n)
+ * string256 := <uint8_t>[256]
+ * string_pool := string
+ * string_pool_index := <uint32_t>
+ * string_pool_length := <uint32_t>
+ * target_crc := <uint32_t>
+ * target_entry_count := <uint32_t>
+ * target_inline_entry_count := <uint32_t>
+ * target_id := <uint32_t>
+ * target_package_id := <uint8_t>
+ * target_path := string256
+ * value_type := <uint8_t>
+ * value_data := <uint32_t>
+ * version := <uint32_t>
*/
#ifndef IDMAP2_INCLUDE_IDMAP2_IDMAP_H_
@@ -183,6 +180,10 @@ class IdmapData {
return target_entry_count;
}
+ inline uint32_t GetTargetInlineEntryCount() const {
+ return target_entry_inline_count;
+ }
+
inline uint32_t GetOverlayEntryCount() const {
return overlay_entry_count;
}
@@ -191,19 +192,15 @@ class IdmapData {
return string_pool_index_offset;
}
- inline uint32_t GetStringPoolLength() const {
- return string_pool_len;
- }
-
void accept(Visitor* v) const;
private:
PackageId target_package_id_;
PackageId overlay_package_id_;
uint32_t target_entry_count;
+ uint32_t target_entry_inline_count;
uint32_t overlay_entry_count;
uint32_t string_pool_index_offset;
- uint32_t string_pool_len;
Header() = default;
friend Idmap;
@@ -213,8 +210,12 @@ class IdmapData {
struct TargetEntry {
ResourceId target_id;
- TargetValue::DataType data_type;
- TargetValue::DataValue data_value;
+ ResourceId overlay_id;
+ };
+
+ struct TargetInlineEntry {
+ ResourceId target_id;
+ TargetValue value;
};
struct OverlayEntry {
@@ -227,20 +228,24 @@ class IdmapData {
static Result<std::unique_ptr<const IdmapData>> FromResourceMapping(
const ResourceMapping& resource_mapping);
- inline const std::unique_ptr<const Header>& GetHeader() const {
+ const std::unique_ptr<const Header>& GetHeader() const {
return header_;
}
- inline const std::vector<TargetEntry>& GetTargetEntries() const {
+ const std::vector<TargetEntry>& GetTargetEntries() const {
return target_entries_;
}
- inline const std::vector<OverlayEntry>& GetOverlayEntries() const {
+ const std::vector<TargetInlineEntry>& GetTargetInlineEntries() const {
+ return target_inline_entries_;
+ }
+
+ const std::vector<OverlayEntry>& GetOverlayEntries() const {
return overlay_entries_;
}
- inline const void* GetStringPoolData() const {
- return string_pool_.get();
+ const std::string& GetStringPoolData() const {
+ return string_pool_data_;
}
void accept(Visitor* v) const;
@@ -251,8 +256,9 @@ class IdmapData {
std::unique_ptr<const Header> header_;
std::vector<TargetEntry> target_entries_;
+ std::vector<TargetInlineEntry> target_inline_entries_;
std::vector<OverlayEntry> overlay_entries_;
- std::unique_ptr<uint8_t[]> string_pool_;
+ std::string string_pool_data_;
friend Idmap;
DISALLOW_COPY_AND_ASSIGN(IdmapData);
@@ -304,6 +310,10 @@ class Visitor {
virtual void visit(const IdmapData::Header& header) = 0;
};
+inline size_t CalculatePadding(size_t data_length) {
+ return (4 - (data_length % 4)) % 4;
+}
+
} // namespace android::idmap2
#endif // IDMAP2_INCLUDE_IDMAP2_IDMAP_H_
diff --git a/cmds/idmap2/include/idmap2/PrettyPrintVisitor.h b/cmds/idmap2/include/idmap2/PrettyPrintVisitor.h
index 5dcf217e2aa3..2b4c76124175 100644
--- a/cmds/idmap2/include/idmap2/PrettyPrintVisitor.h
+++ b/cmds/idmap2/include/idmap2/PrettyPrintVisitor.h
@@ -41,8 +41,9 @@ class PrettyPrintVisitor : public Visitor {
private:
std::ostream& stream_;
- std::unique_ptr<const ApkAssets> target_apk_;
AssetManager2 target_am_;
+ AssetManager2 overlay_am_;
+ std::vector<std::unique_ptr<const ApkAssets>> apk_assets_;
};
} // namespace idmap2
diff --git a/cmds/idmap2/include/idmap2/RawPrintVisitor.h b/cmds/idmap2/include/idmap2/RawPrintVisitor.h
index 92c186453611..58edc99715fd 100644
--- a/cmds/idmap2/include/idmap2/RawPrintVisitor.h
+++ b/cmds/idmap2/include/idmap2/RawPrintVisitor.h
@@ -45,11 +45,9 @@ class RawPrintVisitor : public Visitor {
void print(uint16_t value, const char* fmt, ...);
void print(uint32_t value, const char* fmt, ...);
void print(const std::string& value, size_t encoded_size, const char* fmt, ...);
- void print_raw(uint32_t length, const char* fmt, ...);
std::ostream& stream_;
- std::unique_ptr<const ApkAssets> target_apk_;
- std::unique_ptr<const ApkAssets> overlay_apk_;
+ std::vector<std::unique_ptr<const ApkAssets>> apk_assets_;
AssetManager2 target_am_;
AssetManager2 overlay_am_;
size_t offset_;
diff --git a/cmds/idmap2/include/idmap2/ResourceMapping.h b/cmds/idmap2/include/idmap2/ResourceMapping.h
index 5869409e7db9..0a58ec43d8ff 100644
--- a/cmds/idmap2/include/idmap2/ResourceMapping.h
+++ b/cmds/idmap2/include/idmap2/ResourceMapping.h
@@ -41,7 +41,7 @@ struct TargetValue {
DataValue data_value;
};
-using TargetResourceMap = std::map<ResourceId, TargetValue>;
+using TargetResourceMap = std::map<ResourceId, std::variant<ResourceId, TargetValue>>;
using OverlayResourceMap = std::map<ResourceId, ResourceId>;
class ResourceMapping {
@@ -56,7 +56,7 @@ class ResourceMapping {
bool enforce_overlayable, LogInfo& log_info);
// Retrieves the mapping of target resource id to overlay value.
- inline TargetResourceMap GetTargetToOverlayMap() const {
+ inline const TargetResourceMap& GetTargetToOverlayMap() const {
return target_map_;
}
@@ -81,19 +81,24 @@ class ResourceMapping {
}
// Retrieves the raw string pool data from the xml referenced in android:resourcesMap.
- inline const std::pair<const uint8_t*, uint32_t> GetStringPoolData() const {
- return std::make_pair(string_pool_data_.get(), string_pool_data_length_);
+ inline const StringPiece GetStringPoolData() const {
+ return StringPiece(reinterpret_cast<const char*>(string_pool_data_.get()),
+ string_pool_data_length_);
}
private:
ResourceMapping() = default;
- // Apps a mapping of target resource id to the type and value of the data that overlays the
- // target resource. The data_type is the runtime format of the data value (see
- // Res_value::dataType). If rewrite_overlay_reference is `true` then references to an overlay
+ // Maps a target resource id to an overlay resource id.
+ // If rewrite_overlay_reference is `true` then references to the overlay
// resource should appear as a reference to its corresponding target resource at runtime.
+ Result<Unit> AddMapping(ResourceId target_resource, ResourceId overlay_resource,
+ bool rewrite_overlay_reference);
+
+ // Maps a target resource id to a data type and value combination.
+ // The `data_type` is the runtime format of the data value (see Res_value::dataType).
Result<Unit> AddMapping(ResourceId target_resource, TargetValue::DataType data_type,
- TargetValue::DataValue data_value, bool rewrite_overlay_reference);
+ TargetValue::DataValue data_value);
// Removes the overlay value mapping for the target resource.
void RemoveMapping(ResourceId target_resource);
diff --git a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp
index 255212ad4c66..726f6c5c2c99 100644
--- a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp
+++ b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp
@@ -24,10 +24,6 @@
namespace android::idmap2 {
-void BinaryStreamVisitor::Write(const void* value, size_t length) {
- stream_.write(reinterpret_cast<const char*>(value), length);
-}
-
void BinaryStreamVisitor::Write8(uint8_t value) {
stream_.write(reinterpret_cast<char*>(&value), sizeof(uint8_t));
}
@@ -49,11 +45,11 @@ void BinaryStreamVisitor::WriteString256(const StringPiece& value) {
stream_.write(buf, sizeof(buf));
}
-void BinaryStreamVisitor::WriteString(const std::string& value) {
- // pad with null to nearest word boundary; include at least one terminating null
- size_t padding_size = 4 - (value.size() % 4);
- Write32(value.size() + padding_size);
- stream_.write(value.c_str(), value.size());
+void BinaryStreamVisitor::WriteString(const StringPiece& value) {
+ // pad with null to nearest word boundary;
+ size_t padding_size = CalculatePadding(value.size());
+ Write32(value.size());
+ stream_.write(value.data(), value.size());
stream_.write("\0\0\0\0", padding_size);
}
@@ -67,7 +63,7 @@ void BinaryStreamVisitor::visit(const IdmapHeader& header) {
Write32(header.GetTargetCrc());
Write32(header.GetOverlayCrc());
Write32(header.GetFulfilledPolicies());
- Write8(static_cast<uint8_t>(header.GetEnforceOverlayable()));
+ Write32(static_cast<uint8_t>(header.GetEnforceOverlayable()));
WriteString256(header.GetTargetPath());
WriteString256(header.GetOverlayPath());
WriteString(header.GetDebugInfo());
@@ -76,8 +72,16 @@ void BinaryStreamVisitor::visit(const IdmapHeader& header) {
void BinaryStreamVisitor::visit(const IdmapData& data) {
for (const auto& target_entry : data.GetTargetEntries()) {
Write32(target_entry.target_id);
- Write8(target_entry.data_type);
- Write32(target_entry.data_value);
+ Write32(target_entry.overlay_id);
+ }
+
+ static constexpr uint16_t kValueSize = 8U;
+ for (const auto& target_entry : data.GetTargetInlineEntries()) {
+ Write32(target_entry.target_id);
+ Write16(kValueSize);
+ Write8(0U); // padding
+ Write8(target_entry.value.data_type);
+ Write32(target_entry.value.data_value);
}
for (const auto& overlay_entry : data.GetOverlayEntries()) {
@@ -85,16 +89,18 @@ void BinaryStreamVisitor::visit(const IdmapData& data) {
Write32(overlay_entry.target_id);
}
- Write(data.GetStringPoolData(), data.GetHeader()->GetStringPoolLength());
+ WriteString(data.GetStringPoolData());
}
void BinaryStreamVisitor::visit(const IdmapData::Header& header) {
Write8(header.GetTargetPackageId());
Write8(header.GetOverlayPackageId());
+ Write8(0U); // padding
+ Write8(0U); // padding
Write32(header.GetTargetEntryCount());
+ Write32(header.GetTargetInlineEntryCount());
Write32(header.GetOverlayEntryCount());
Write32(header.GetStringPoolIndexOffset());
- Write32(header.GetStringPoolLength());
}
} // namespace android::idmap2
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp
index 23c25a7089de..1129413584b2 100644
--- a/cmds/idmap2/libidmap2/Idmap.cpp
+++ b/cmds/idmap2/libidmap2/Idmap.cpp
@@ -51,19 +51,19 @@ bool WARN_UNUSED Read8(std::istream& stream, uint8_t* out) {
return false;
}
-bool WARN_UNUSED Read32(std::istream& stream, uint32_t* out) {
- uint32_t value;
- if (stream.read(reinterpret_cast<char*>(&value), sizeof(uint32_t))) {
- *out = dtohl(value);
+bool WARN_UNUSED Read16(std::istream& stream, uint16_t* out) {
+ uint16_t value;
+ if (stream.read(reinterpret_cast<char*>(&value), sizeof(uint16_t))) {
+ *out = dtohs(value);
return true;
}
return false;
}
-bool WARN_UNUSED ReadBuffer(std::istream& stream, std::unique_ptr<uint8_t[]>* out, size_t length) {
- auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[length]);
- if (stream.read(reinterpret_cast<char*>(buffer.get()), length)) {
- *out = std::move(buffer);
+bool WARN_UNUSED Read32(std::istream& stream, uint32_t* out) {
+ uint32_t value;
+ if (stream.read(reinterpret_cast<char*>(&value), sizeof(uint32_t))) {
+ *out = dtohl(value);
return true;
}
return false;
@@ -95,8 +95,11 @@ Result<std::string> ReadString(std::istream& stream) {
if (!stream.read(buf.data(), size)) {
return Error("failed to read string of size %u", size);
}
- // buf is guaranteed to be null terminated (with enough nulls to end on a word boundary)
- buf.resize(strlen(buf.c_str()));
+ uint32_t padding_size = CalculatePadding(size);
+ std::string padding(padding_size, '\0');
+ if (!stream.read(padding.data(), padding_size)) {
+ return Error("failed to read string padding of size %u", padding_size);
+ }
return buf;
}
@@ -112,16 +115,16 @@ Result<uint32_t> GetPackageCrc(const ZipFile& zip) {
std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& stream) {
std::unique_ptr<IdmapHeader> idmap_header(new IdmapHeader());
- uint8_t enforce_overlayable;
+ uint32_t enforce_overlayable;
if (!Read32(stream, &idmap_header->magic_) || !Read32(stream, &idmap_header->version_) ||
!Read32(stream, &idmap_header->target_crc_) || !Read32(stream, &idmap_header->overlay_crc_) ||
- !Read32(stream, &idmap_header->fulfilled_policies_) || !Read8(stream, &enforce_overlayable) ||
- !ReadString256(stream, idmap_header->target_path_) ||
+ !Read32(stream, &idmap_header->fulfilled_policies_) ||
+ !Read32(stream, &enforce_overlayable) || !ReadString256(stream, idmap_header->target_path_) ||
!ReadString256(stream, idmap_header->overlay_path_)) {
return nullptr;
}
- idmap_header->enforce_overlayable_ = static_cast<bool>(enforce_overlayable);
+ idmap_header->enforce_overlayable_ = enforce_overlayable != 0U;
auto debug_str = ReadString(stream);
if (!debug_str) {
@@ -207,12 +210,13 @@ Result<Unit> IdmapHeader::IsUpToDate(const char* target_path, const char* overla
std::unique_ptr<const IdmapData::Header> IdmapData::Header::FromBinaryStream(std::istream& stream) {
std::unique_ptr<IdmapData::Header> idmap_data_header(new IdmapData::Header());
+ uint8_t padding;
if (!Read8(stream, &idmap_data_header->target_package_id_) ||
- !Read8(stream, &idmap_data_header->overlay_package_id_) ||
- !Read32(stream, &idmap_data_header->target_entry_count) ||
+ !Read8(stream, &idmap_data_header->overlay_package_id_) || !Read8(stream, &padding) ||
+ !Read8(stream, &padding) || !Read32(stream, &idmap_data_header->target_entry_count) ||
+ !Read32(stream, &idmap_data_header->target_entry_inline_count) ||
!Read32(stream, &idmap_data_header->overlay_entry_count) ||
- !Read32(stream, &idmap_data_header->string_pool_index_offset) ||
- !Read32(stream, &idmap_data_header->string_pool_len)) {
+ !Read32(stream, &idmap_data_header->string_pool_index_offset)) {
return nullptr;
}
@@ -225,14 +229,27 @@ std::unique_ptr<const IdmapData> IdmapData::FromBinaryStream(std::istream& strea
if (!data->header_) {
return nullptr;
}
+
// Read the mapping of target resource id to overlay resource value.
for (size_t i = 0; i < data->header_->GetTargetEntryCount(); i++) {
TargetEntry target_entry{};
- if (!Read32(stream, &target_entry.target_id) || !Read8(stream, &target_entry.data_type) ||
- !Read32(stream, &target_entry.data_value)) {
+ if (!Read32(stream, &target_entry.target_id) || !Read32(stream, &target_entry.overlay_id)) {
+ return nullptr;
+ }
+ data->target_entries_.push_back(target_entry);
+ }
+
+ // Read the mapping of target resource id to inline overlay values.
+ uint8_t unused1;
+ uint16_t unused2;
+ for (size_t i = 0; i < data->header_->GetTargetInlineEntryCount(); i++) {
+ TargetInlineEntry target_entry{};
+ if (!Read32(stream, &target_entry.target_id) || !Read16(stream, &unused2) ||
+ !Read8(stream, &unused1) || !Read8(stream, &target_entry.value.data_type) ||
+ !Read32(stream, &target_entry.value.data_value)) {
return nullptr;
}
- data->target_entries_.emplace_back(target_entry);
+ data->target_inline_entries_.push_back(target_entry);
}
// Read the mapping of overlay resource id to target resource id.
@@ -245,9 +262,11 @@ std::unique_ptr<const IdmapData> IdmapData::FromBinaryStream(std::istream& strea
}
// Read raw string pool bytes.
- if (!ReadBuffer(stream, &data->string_pool_, data->header_->string_pool_len)) {
+ auto string_pool_data = ReadString(stream);
+ if (!string_pool_data) {
return nullptr;
}
+ data->string_pool_data_ = std::move(*string_pool_data);
return std::move(data);
}
@@ -290,27 +309,28 @@ Result<std::unique_ptr<const IdmapData>> IdmapData::FromResourceMapping(
}
std::unique_ptr<IdmapData> data(new IdmapData());
- for (const auto& mappings : resource_mapping.GetTargetToOverlayMap()) {
- data->target_entries_.emplace_back(IdmapData::TargetEntry{
- mappings.first, mappings.second.data_type, mappings.second.data_value});
+ data->string_pool_data_ = resource_mapping.GetStringPoolData().to_string();
+ for (const auto& mapping : resource_mapping.GetTargetToOverlayMap()) {
+ if (auto overlay_resource = std::get_if<ResourceId>(&mapping.second)) {
+ data->target_entries_.push_back({mapping.first, *overlay_resource});
+ } else {
+ data->target_inline_entries_.push_back(
+ {mapping.first, std::get<TargetValue>(mapping.second)});
+ }
}
- for (const auto& mappings : resource_mapping.GetOverlayToTargetMap()) {
- data->overlay_entries_.emplace_back(IdmapData::OverlayEntry{mappings.first, mappings.second});
+ for (const auto& mapping : resource_mapping.GetOverlayToTargetMap()) {
+ data->overlay_entries_.emplace_back(IdmapData::OverlayEntry{mapping.first, mapping.second});
}
std::unique_ptr<IdmapData::Header> data_header(new IdmapData::Header());
data_header->target_package_id_ = resource_mapping.GetTargetPackageId();
data_header->overlay_package_id_ = resource_mapping.GetOverlayPackageId();
data_header->target_entry_count = static_cast<uint32_t>(data->target_entries_.size());
+ data_header->target_entry_inline_count =
+ static_cast<uint32_t>(data->target_inline_entries_.size());
data_header->overlay_entry_count = static_cast<uint32_t>(data->overlay_entries_.size());
data_header->string_pool_index_offset = resource_mapping.GetStringPoolOffset();
-
- const auto string_pool_data = resource_mapping.GetStringPoolData();
- data_header->string_pool_len = string_pool_data.second;
- data->string_pool_ = std::unique_ptr<uint8_t[]>(new uint8_t[data_header->string_pool_len]);
- memcpy(data->string_pool_.get(), string_pool_data.first, data_header->string_pool_len);
-
data->header_ = std::move(data_header);
return {std::move(data)};
}
diff --git a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp
index 63ee8a648352..a93202a64d31 100644
--- a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp
+++ b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp
@@ -38,6 +38,7 @@ void PrettyPrintVisitor::visit(const IdmapHeader& header) {
stream_ << "Paths:" << std::endl
<< TAB "target apk path : " << header.GetTargetPath() << std::endl
<< TAB "overlay apk path : " << header.GetOverlayPath() << std::endl;
+
const std::string& debug = header.GetDebugInfo();
if (!debug.empty()) {
std::istringstream debug_stream(debug);
@@ -48,10 +49,16 @@ void PrettyPrintVisitor::visit(const IdmapHeader& header) {
}
}
- target_apk_ = ApkAssets::Load(header.GetTargetPath().to_string());
- if (target_apk_) {
+ if (auto target_apk_ = ApkAssets::Load(header.GetTargetPath().to_string())) {
target_am_.SetApkAssets({target_apk_.get()});
+ apk_assets_.push_back(std::move(target_apk_));
+ }
+
+ if (auto overlay_apk = ApkAssets::Load(header.GetOverlayPath().to_string())) {
+ overlay_am_.SetApkAssets({overlay_apk.get()});
+ apk_assets_.push_back(std::move(overlay_apk));
}
+
stream_ << "Mapping:" << std::endl;
}
@@ -59,34 +66,56 @@ void PrettyPrintVisitor::visit(const IdmapData::Header& header ATTRIBUTE_UNUSED)
}
void PrettyPrintVisitor::visit(const IdmapData& data) {
+ static constexpr const char* kUnknownResourceName = "???";
+
const bool target_package_loaded = !target_am_.GetApkAssets().empty();
- const ResStringPool string_pool(data.GetStringPoolData(),
- data.GetHeader()->GetStringPoolLength());
+ const bool overlay_package_loaded = !overlay_am_.GetApkAssets().empty();
+
+ const ResStringPool string_pool(data.GetStringPoolData().data(), data.GetStringPoolData().size());
const size_t string_pool_offset = data.GetHeader()->GetStringPoolIndexOffset();
- for (auto& target_entry : data.GetTargetEntries()) {
- stream_ << TAB << base::StringPrintf("0x%08x ->", target_entry.target_id);
+ for (const auto& target_entry : data.GetTargetEntries()) {
+ std::string target_name = kUnknownResourceName;
+ if (target_package_loaded) {
+ if (auto name = utils::ResToTypeEntryName(target_am_, target_entry.target_id)) {
+ target_name = *name;
+ }
+ }
- if (target_entry.data_type != Res_value::TYPE_REFERENCE &&
- target_entry.data_type != Res_value::TYPE_DYNAMIC_REFERENCE) {
- stream_ << " " << utils::DataTypeToString(target_entry.data_type);
+ std::string overlay_name = kUnknownResourceName;
+ if (overlay_package_loaded) {
+ if (auto name = utils::ResToTypeEntryName(overlay_am_, target_entry.overlay_id)) {
+ overlay_name = *name;
+ }
}
- if (target_entry.data_type == Res_value::TYPE_STRING) {
- stream_ << " \""
- << string_pool.string8ObjectAt(target_entry.data_value - string_pool_offset).c_str()
- << "\"";
+ stream_ << TAB
+ << base::StringPrintf("0x%08x -> 0x%08x (%s -> %s)", target_entry.target_id,
+ target_entry.overlay_id, target_name.c_str(),
+ overlay_name.c_str())
+ << std::endl;
+ }
+
+ for (auto& target_entry : data.GetTargetInlineEntries()) {
+ stream_ << TAB << base::StringPrintf("0x%08x -> ", target_entry.target_id)
+ << utils::DataTypeToString(target_entry.value.data_type);
+
+ size_t unused;
+ if (target_entry.value.data_type == Res_value::TYPE_STRING) {
+ auto str = string_pool.stringAt(target_entry.value.data_value - string_pool_offset, &unused);
+ stream_ << " \"" << StringPiece16(str) << "\"";
} else {
- stream_ << " " << base::StringPrintf("0x%08x", target_entry.data_value);
+ stream_ << " " << base::StringPrintf("0x%08x", target_entry.value.data_value);
}
+ std::string target_name = kUnknownResourceName;
if (target_package_loaded) {
- Result<std::string> name = utils::ResToTypeEntryName(target_am_, target_entry.target_id);
- if (name) {
- stream_ << " " << *name;
+ if (auto name = utils::ResToTypeEntryName(target_am_, target_entry.target_id)) {
+ target_name = *name;
}
}
- stream_ << std::endl;
+
+ stream_ << " (" << target_name << ")" << std::endl;
}
}
diff --git a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp
index 3f62a2ae2029..82f5d26cbbb3 100644
--- a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp
+++ b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp
@@ -30,15 +30,6 @@
using android::ApkAssets;
using android::idmap2::policy::PoliciesToDebugString;
-namespace {
-
-size_t StringSizeWhenEncoded(const std::string& s) {
- size_t null_bytes = 4 - (s.size() % 4);
- return sizeof(uint32_t) + s.size() + null_bytes;
-}
-
-} // namespace
-
namespace android::idmap2 {
void RawPrintVisitor::visit(const Idmap& idmap ATTRIBUTE_UNUSED) {
@@ -51,19 +42,24 @@ void RawPrintVisitor::visit(const IdmapHeader& header) {
print(header.GetOverlayCrc(), "overlay crc");
print(header.GetFulfilledPolicies(), "fulfilled policies: %s",
PoliciesToDebugString(header.GetFulfilledPolicies()).c_str());
- print(static_cast<uint8_t>(header.GetEnforceOverlayable()), "enforce overlayable");
+ print(static_cast<uint32_t>(header.GetEnforceOverlayable()), "enforce overlayable");
print(header.GetTargetPath().to_string(), kIdmapStringLength, "target path");
print(header.GetOverlayPath().to_string(), kIdmapStringLength, "overlay path");
- print("...", StringSizeWhenEncoded(header.GetDebugInfo()), "debug info");
- target_apk_ = ApkAssets::Load(header.GetTargetPath().to_string());
+ uint32_t debug_info_size = header.GetDebugInfo().size();
+ print(debug_info_size, "debug info size");
+ print("...", debug_info_size + CalculatePadding(debug_info_size), "debug info");
+
+ auto target_apk_ = ApkAssets::Load(header.GetTargetPath().to_string());
if (target_apk_) {
target_am_.SetApkAssets({target_apk_.get()});
+ apk_assets_.push_back(std::move(target_apk_));
}
- overlay_apk_ = ApkAssets::Load(header.GetOverlayPath().to_string());
+ auto overlay_apk_ = ApkAssets::Load(header.GetOverlayPath().to_string());
if (overlay_apk_) {
overlay_am_.SetApkAssets({overlay_apk_.get()});
+ apk_assets_.push_back(std::move(overlay_apk_));
}
}
@@ -82,18 +78,44 @@ void RawPrintVisitor::visit(const IdmapData& data ATTRIBUTE_UNUSED) {
print(target_entry.target_id, "target id");
}
- print(target_entry.data_type, "type: %s",
- utils::DataTypeToString(target_entry.data_type).data());
+ Result<std::string> overlay_name(Error(""));
+ if (overlay_package_loaded) {
+ overlay_name = utils::ResToTypeEntryName(overlay_am_, target_entry.overlay_id);
+ }
+ if (overlay_name) {
+ print(target_entry.overlay_id, "overlay id: %s", overlay_name->c_str());
+ } else {
+ print(target_entry.overlay_id, "overlay id");
+ }
+ }
+
+ for (auto& target_entry : data.GetTargetInlineEntries()) {
+ Result<std::string> target_name(Error(""));
+ if (target_package_loaded) {
+ target_name = utils::ResToTypeEntryName(target_am_, target_entry.target_id);
+ }
+ if (target_name) {
+ print(target_entry.target_id, "target id: %s", target_name->c_str());
+ } else {
+ print(target_entry.target_id, "target id");
+ }
+
+ print("...", sizeof(Res_value::size) + sizeof(Res_value::res0), "padding");
+
+ print(target_entry.value.data_type, "type: %s",
+ utils::DataTypeToString(target_entry.value.data_type).data());
Result<std::string> overlay_name(Error(""));
- if (overlay_package_loaded && (target_entry.data_type == Res_value::TYPE_REFERENCE ||
- target_entry.data_type == Res_value::TYPE_DYNAMIC_REFERENCE)) {
- overlay_name = utils::ResToTypeEntryName(overlay_am_, target_entry.data_value);
+ if (overlay_package_loaded &&
+ (target_entry.value.data_value == Res_value::TYPE_REFERENCE ||
+ target_entry.value.data_value == Res_value::TYPE_DYNAMIC_REFERENCE)) {
+ overlay_name = utils::ResToTypeEntryName(overlay_am_, target_entry.value.data_value);
}
+
if (overlay_name) {
- print(target_entry.data_value, "value: %s", overlay_name->c_str());
+ print(target_entry.value.data_value, "data: %s", overlay_name->c_str());
} else {
- print(target_entry.data_value, "value");
+ print(target_entry.value.data_value, "data");
}
}
@@ -121,19 +143,19 @@ void RawPrintVisitor::visit(const IdmapData& data ATTRIBUTE_UNUSED) {
}
}
- const size_t string_pool_length = data.GetHeader()->GetStringPoolLength();
- if (string_pool_length > 0) {
- print_raw(string_pool_length, "%zu raw string pool bytes", string_pool_length);
- }
+ uint32_t string_pool_size = data.GetStringPoolData().size();
+ print(string_pool_size, "string pool size");
+ print("...", string_pool_size + CalculatePadding(string_pool_size), "string pool");
}
void RawPrintVisitor::visit(const IdmapData::Header& header) {
print(header.GetTargetPackageId(), "target package id");
print(header.GetOverlayPackageId(), "overlay package id");
+ print("...", sizeof(Idmap_data_header::p0), "padding");
print(header.GetTargetEntryCount(), "target entry count");
+ print(header.GetTargetInlineEntryCount(), "target inline entry count");
print(header.GetOverlayEntryCount(), "overlay entry count");
print(header.GetStringPoolIndexOffset(), "string pool index offset");
- print(header.GetStringPoolLength(), "string pool byte length");
}
// NOLINTNEXTLINE(cert-dcl50-cpp)
@@ -190,17 +212,4 @@ void RawPrintVisitor::print(const std::string& value, size_t encoded_size, const
offset_ += encoded_size;
}
-// NOLINTNEXTLINE(cert-dcl50-cpp)
-void RawPrintVisitor::print_raw(uint32_t length, const char* fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- std::string comment;
- base::StringAppendV(&comment, fmt, ap);
- va_end(ap);
-
- stream_ << base::StringPrintf("%08zx: ", offset_) << "........ " << comment << std::endl;
-
- offset_ += length;
-}
-
} // namespace android::idmap2
diff --git a/cmds/idmap2/libidmap2/ResourceMapping.cpp b/cmds/idmap2/libidmap2/ResourceMapping.cpp
index fd8b4eb86b4a..122f0682aec6 100644
--- a/cmds/idmap2/libidmap2/ResourceMapping.cpp
+++ b/cmds/idmap2/libidmap2/ResourceMapping.cpp
@@ -205,19 +205,14 @@ Result<ResourceMapping> ResourceMapping::CreateResourceMapping(const AssetManage
overlay_resource->data += string_pool_offset;
}
- // Only rewrite resources defined within the overlay package to their corresponding target
- // resource ids at runtime.
- bool rewrite_overlay_reference =
- IsReference(overlay_resource->dataType)
- ? overlay_package_id == EXTRACT_PACKAGE(overlay_resource->data)
- : false;
-
- if (rewrite_overlay_reference) {
- overlay_resource->dataType = Res_value::TYPE_DYNAMIC_REFERENCE;
+ if (IsReference(overlay_resource->dataType)) {
+ // Only rewrite resources defined within the overlay package to their corresponding target
+ // resource ids at runtime.
+ bool rewrite_reference = overlay_package_id == EXTRACT_PACKAGE(overlay_resource->data);
+ resource_mapping.AddMapping(target_id, overlay_resource->data, rewrite_reference);
+ } else {
+ resource_mapping.AddMapping(target_id, overlay_resource->dataType, overlay_resource->data);
}
-
- resource_mapping.AddMapping(target_id, overlay_resource->dataType, overlay_resource->data,
- rewrite_overlay_reference);
}
return resource_mapping;
@@ -246,9 +241,8 @@ Result<ResourceMapping> ResourceMapping::CreateResourceMappingLegacy(
// Retrieve the compile-time resource id of the target resource.
target_resource = REWRITE_PACKAGE(target_resource, target_package_id);
-
- resource_mapping.AddMapping(target_resource, Res_value::TYPE_REFERENCE, overlay_resid,
- /* rewrite_overlay_reference */ false);
+ resource_mapping.AddMapping(target_resource, overlay_resid,
+ false /* rewrite_overlay_reference */);
}
return resource_mapping;
@@ -396,9 +390,7 @@ OverlayResourceMap ResourceMapping::GetOverlayToTargetMap() const {
return map;
}
-Result<Unit> ResourceMapping::AddMapping(ResourceId target_resource,
- TargetValue::DataType data_type,
- TargetValue::DataValue data_value,
+Result<Unit> ResourceMapping::AddMapping(ResourceId target_resource, ResourceId overlay_resource,
bool rewrite_overlay_reference) {
if (target_map_.find(target_resource) != target_map_.end()) {
return Error(R"(target resource id "0x%08x" mapped to multiple values)", target_resource);
@@ -407,13 +399,26 @@ Result<Unit> ResourceMapping::AddMapping(ResourceId target_resource,
// TODO(141485591): Ensure that the overlay type is compatible with the target type. If the
// runtime types are not compatible, it could cause runtime crashes when the resource is resolved.
- target_map_.insert(std::make_pair(target_resource, TargetValue{data_type, data_value}));
+ target_map_.insert(std::make_pair(target_resource, overlay_resource));
- if (rewrite_overlay_reference && IsReference(data_type)) {
- overlay_map_.insert(std::make_pair(data_value, target_resource));
+ if (rewrite_overlay_reference) {
+ overlay_map_.insert(std::make_pair(overlay_resource, target_resource));
}
+ return Unit{};
+}
- return Result<Unit>({});
+Result<Unit> ResourceMapping::AddMapping(ResourceId target_resource,
+ TargetValue::DataType data_type,
+ TargetValue::DataValue data_value) {
+ if (target_map_.find(target_resource) != target_map_.end()) {
+ return Error(R"(target resource id "0x%08x" mapped to multiple values)", target_resource);
+ }
+
+ // TODO(141485591): Ensure that the overlay type is compatible with the target type. If the
+ // runtime types are not compatible, it could cause runtime crashes when the resource is resolved.
+
+ target_map_.insert(std::make_pair(target_resource, TargetValue{data_type, data_value}));
+ return Unit{};
}
void ResourceMapping::RemoveMapping(ResourceId target_resource) {
@@ -422,14 +427,15 @@ void ResourceMapping::RemoveMapping(ResourceId target_resource) {
return;
}
- const TargetValue value = target_iter->second;
+ const auto value = target_iter->second;
target_map_.erase(target_iter);
- if (!IsReference(value.data_type)) {
+ const ResourceId* overlay_resource = std::get_if<ResourceId>(&value);
+ if (overlay_resource == nullptr) {
return;
}
- auto overlay_iter = overlay_map_.equal_range(value.data_value);
+ auto overlay_iter = overlay_map_.equal_range(*overlay_resource);
for (auto i = overlay_iter.first; i != overlay_iter.second; ++i) {
if (i->second == target_resource) {
overlay_map_.erase(i);
diff --git a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
index 5fea7bcdaac5..c3a3e0ba9047 100644
--- a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
+++ b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
@@ -72,13 +72,20 @@ TEST(BinaryStreamVisitorTests, CreateBinaryStreamViaBinaryStreamVisitor) {
const auto& target_entries2 = data2->GetTargetEntries();
ASSERT_EQ(target_entries1.size(), target_entries2.size());
ASSERT_EQ(target_entries1[0].target_id, target_entries2[0].target_id);
- ASSERT_EQ(target_entries1[0].data_value, target_entries2[0].data_value);
+ ASSERT_EQ(target_entries1[0].overlay_id, target_entries2[0].overlay_id);
ASSERT_EQ(target_entries1[1].target_id, target_entries2[1].target_id);
- ASSERT_EQ(target_entries1[1].data_value, target_entries2[1].data_value);
+ ASSERT_EQ(target_entries1[1].overlay_id, target_entries2[1].overlay_id);
ASSERT_EQ(target_entries1[2].target_id, target_entries2[2].target_id);
- ASSERT_EQ(target_entries1[2].data_value, target_entries2[2].data_value);
+ ASSERT_EQ(target_entries1[2].overlay_id, target_entries2[2].overlay_id);
+
+ const auto& target_inline_entries1 = data1->GetTargetInlineEntries();
+ const auto& target_inline_entries2 = data2->GetTargetInlineEntries();
+ ASSERT_EQ(target_inline_entries1.size(), target_inline_entries2.size());
+ ASSERT_EQ(target_inline_entries1[0].target_id, target_inline_entries2[0].target_id);
+ ASSERT_EQ(target_inline_entries1[0].value.data_type, target_inline_entries2[0].value.data_type);
+ ASSERT_EQ(target_inline_entries1[0].value.data_value, target_inline_entries2[0].value.data_value);
const auto& overlay_entries1 = data1->GetOverlayEntries();
const auto& overlay_entries2 = data2->GetOverlayEntries();
diff --git a/cmds/idmap2/tests/Idmap2BinaryTests.cpp b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
index d896cf9c11ba..eba102da0763 100644
--- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp
+++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
@@ -128,13 +128,13 @@ TEST_F(Idmap2BinaryTests, Dump) {
// clang-format on
ASSERT_THAT(result, NotNull());
ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
- ASSERT_NE(result->stdout.find(R::target::integer::literal::int1 + " -> 0x7f010000 integer/int1"),
+ ASSERT_NE(result->stdout.find(R::target::integer::literal::int1 + " -> 0x7f010000"),
std::string::npos);
- ASSERT_NE(result->stdout.find(R::target::string::literal::str1 + " -> 0x7f020000 string/str1"),
+ ASSERT_NE(result->stdout.find(R::target::string::literal::str1 + " -> 0x7f020000"),
std::string::npos);
- ASSERT_NE(result->stdout.find(R::target::string::literal::str3 + " -> 0x7f020001 string/str3"),
+ ASSERT_NE(result->stdout.find(R::target::string::literal::str3 + " -> 0x7f020001"),
std::string::npos);
- ASSERT_NE(result->stdout.find(R::target::string::literal::str4 + " -> 0x7f020002 string/str4"),
+ ASSERT_NE(result->stdout.find(R::target::string::literal::str4 + " -> 0x7f020002"),
std::string::npos);
// clang-format off
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index 6fab5e0f8ae1..9b42a2781b58 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -42,14 +42,18 @@ using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;
namespace android::idmap2 {
-#define ASSERT_TARGET_ENTRY(entry, target_resid, type, value) \
- ASSERT_EQ(entry.target_id, target_resid); \
- ASSERT_EQ(entry.data_type, type); \
- ASSERT_EQ(entry.data_value, value)
+#define ASSERT_TARGET_ENTRY(entry, target_resid, overlay_resid) \
+ ASSERT_EQ((entry).target_id, (target_resid)); \
+ ASSERT_EQ((entry).overlay_id, (overlay_resid))
+
+#define ASSERT_TARGET_INLINE_ENTRY(entry, target_resid, expected_type, expected_value) \
+ ASSERT_EQ((entry).target_id, target_resid); \
+ ASSERT_EQ((entry).value.data_type, (expected_type)); \
+ ASSERT_EQ((entry).value.data_value, (expected_value))
#define ASSERT_OVERLAY_ENTRY(entry, overlay_resid, target_resid) \
- ASSERT_EQ(entry.overlay_id, overlay_resid); \
- ASSERT_EQ(entry.target_id, target_resid)
+ ASSERT_EQ((entry).overlay_id, (overlay_resid)); \
+ ASSERT_EQ((entry).target_id, (target_resid))
TEST(IdmapTests, TestCanonicalIdmapPathFor) {
ASSERT_EQ(Idmap::CanonicalIdmapPathFor("/foo", "/vendor/overlay/bar.apk"),
@@ -62,7 +66,7 @@ TEST(IdmapTests, CreateIdmapHeaderFromBinaryStream) {
std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
ASSERT_THAT(header, NotNull());
ASSERT_EQ(header->GetMagic(), 0x504d4449U);
- ASSERT_EQ(header->GetVersion(), 0x04U);
+ ASSERT_EQ(header->GetVersion(), 0x05U);
ASSERT_EQ(header->GetTargetCrc(), 0x1234U);
ASSERT_EQ(header->GetOverlayCrc(), 0x5678U);
ASSERT_EQ(header->GetFulfilledPolicies(), 0x11);
@@ -75,7 +79,7 @@ TEST(IdmapTests, CreateIdmapHeaderFromBinaryStream) {
TEST(IdmapTests, FailToCreateIdmapHeaderFromBinaryStreamIfPathTooLong) {
std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len);
// overwrite the target path string, including the terminating null, with '.'
- for (size_t i = 0x15; i < 0x115; i++) {
+ for (size_t i = 0x18; i < 0x118; i++) {
raw[i] = '.';
}
std::istringstream stream(raw);
@@ -84,7 +88,7 @@ TEST(IdmapTests, FailToCreateIdmapHeaderFromBinaryStreamIfPathTooLong) {
}
TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) {
- const size_t offset = 0x221;
+ const size_t offset = 0x224;
std::string raw(reinterpret_cast<const char*>(idmap_raw_data + offset),
idmap_raw_data_len - offset);
std::istringstream stream(raw);
@@ -96,7 +100,7 @@ TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) {
}
TEST(IdmapTests, CreateIdmapDataFromBinaryStream) {
- const size_t offset = 0x221;
+ const size_t offset = 0x224;
std::string raw(reinterpret_cast<const char*>(idmap_raw_data + offset),
idmap_raw_data_len - offset);
std::istringstream stream(raw);
@@ -106,12 +110,14 @@ TEST(IdmapTests, CreateIdmapDataFromBinaryStream) {
const auto& target_entries = data->GetTargetEntries();
ASSERT_EQ(target_entries.size(), 3U);
- ASSERT_TARGET_ENTRY(target_entries[0], 0x7f020000, 0x01 /* Res_value::TYPE_REFERENCE */,
- 0x7f020000);
- ASSERT_TARGET_ENTRY(target_entries[1], 0x7f030000, 0x01 /* Res_value::TYPE_REFERENCE */,
- 0x7f030000);
- ASSERT_TARGET_ENTRY(target_entries[2], 0x7f030002, 0x01 /* Res_value::TYPE_REFERENCE */,
- 0x7f030001);
+ ASSERT_TARGET_ENTRY(target_entries[0], 0x7f020000, 0x7f020000);
+ ASSERT_TARGET_ENTRY(target_entries[1], 0x7f030000, 0x7f030000);
+ ASSERT_TARGET_ENTRY(target_entries[2], 0x7f030002, 0x7f030001);
+
+ const auto& target_inline_entries = data->GetTargetInlineEntries();
+ ASSERT_EQ(target_inline_entries.size(), 1U);
+ ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], 0x7f040000, Res_value::TYPE_INT_HEX,
+ 0x12345678);
const auto& overlay_entries = data->GetOverlayEntries();
ASSERT_EQ(target_entries.size(), 3U);
@@ -130,7 +136,7 @@ TEST(IdmapTests, CreateIdmapFromBinaryStream) {
ASSERT_THAT(idmap->GetHeader(), NotNull());
ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
- ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x04U);
+ ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x05U);
ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x1234U);
ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x5678U);
ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), 0x11);
@@ -146,9 +152,14 @@ TEST(IdmapTests, CreateIdmapFromBinaryStream) {
const auto& target_entries = data->GetTargetEntries();
ASSERT_EQ(target_entries.size(), 3U);
- ASSERT_TARGET_ENTRY(target_entries[0], 0x7f020000, Res_value::TYPE_REFERENCE, 0x7f020000);
- ASSERT_TARGET_ENTRY(target_entries[1], 0x7f030000, Res_value::TYPE_REFERENCE, 0x7f030000);
- ASSERT_TARGET_ENTRY(target_entries[2], 0x7f030002, Res_value::TYPE_REFERENCE, 0x7f030001);
+ ASSERT_TARGET_ENTRY(target_entries[0], 0x7f020000, 0x7f020000);
+ ASSERT_TARGET_ENTRY(target_entries[1], 0x7f030000, 0x7f030000);
+ ASSERT_TARGET_ENTRY(target_entries[2], 0x7f030002, 0x7f030001);
+
+ const auto& target_inline_entries = data->GetTargetInlineEntries();
+ ASSERT_EQ(target_inline_entries.size(), 1U);
+ ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], 0x7f040000, Res_value::TYPE_INT_HEX,
+ 0x12345678);
const auto& overlay_entries = data->GetOverlayEntries();
ASSERT_EQ(target_entries.size(), 3U);
@@ -184,7 +195,7 @@ TEST(IdmapTests, CreateIdmapHeaderFromApkAssets) {
ASSERT_THAT(idmap->GetHeader(), NotNull());
ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
- ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x04U);
+ ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x05U);
ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), android::idmap2::TestConstants::TARGET_CRC);
ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), android::idmap2::TestConstants::OVERLAY_CRC);
ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), PolicyFlags::PUBLIC);
@@ -244,14 +255,13 @@ TEST(IdmapTests, CreateIdmapDataFromApkAssets) {
const auto& target_entries = data->GetTargetEntries();
ASSERT_EQ(target_entries.size(), 4U);
- ASSERT_TARGET_ENTRY(target_entries[0], R::target::integer::int1,
- Res_value::TYPE_DYNAMIC_REFERENCE, R::overlay::integer::int1);
- ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str1, Res_value::TYPE_DYNAMIC_REFERENCE,
- R::overlay::string::str1);
- ASSERT_TARGET_ENTRY(target_entries[2], R::target::string::str3, Res_value::TYPE_DYNAMIC_REFERENCE,
- R::overlay::string::str3);
- ASSERT_TARGET_ENTRY(target_entries[3], R::target::string::str4, Res_value::TYPE_DYNAMIC_REFERENCE,
- R::overlay::string::str4);
+ ASSERT_TARGET_ENTRY(target_entries[0], R::target::integer::int1, R::overlay::integer::int1);
+ ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str1, R::overlay::string::str1);
+ ASSERT_TARGET_ENTRY(target_entries[2], R::target::string::str3, R::overlay::string::str3);
+ ASSERT_TARGET_ENTRY(target_entries[3], R::target::string::str4, R::overlay::string::str4);
+
+ const auto& target_inline_entries = data->GetTargetInlineEntries();
+ ASSERT_EQ(target_inline_entries.size(), 0U);
const auto& overlay_entries = data->GetOverlayEntries();
ASSERT_EQ(target_entries.size(), 4U);
@@ -286,13 +296,13 @@ TEST(IdmapTests, CreateIdmapDataFromApkAssetsSharedLibOverlay) {
const auto& target_entries = data->GetTargetEntries();
ASSERT_EQ(target_entries.size(), 4U);
ASSERT_TARGET_ENTRY(target_entries[0], R::target::integer::int1,
- Res_value::TYPE_DYNAMIC_REFERENCE, R::overlay_shared::integer::int1);
- ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str1, Res_value::TYPE_DYNAMIC_REFERENCE,
- R::overlay_shared::string::str1);
- ASSERT_TARGET_ENTRY(target_entries[2], R::target::string::str3, Res_value::TYPE_DYNAMIC_REFERENCE,
- R::overlay_shared::string::str3);
- ASSERT_TARGET_ENTRY(target_entries[3], R::target::string::str4, Res_value::TYPE_DYNAMIC_REFERENCE,
- R::overlay_shared::string::str4);
+ R::overlay_shared::integer::int1);
+ ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str1, R::overlay_shared::string::str1);
+ ASSERT_TARGET_ENTRY(target_entries[2], R::target::string::str3, R::overlay_shared::string::str3);
+ ASSERT_TARGET_ENTRY(target_entries[3], R::target::string::str4, R::overlay_shared::string::str4);
+
+ const auto& target_inline_entries = data->GetTargetInlineEntries();
+ ASSERT_EQ(target_inline_entries.size(), 0U);
const auto& overlay_entries = data->GetOverlayEntries();
ASSERT_EQ(target_entries.size(), 4U);
@@ -320,10 +330,12 @@ TEST(IdmapTests, CreateIdmapDataDoNotRewriteNonOverlayResourceId) {
const auto& target_entries = data->GetTargetEntries();
ASSERT_EQ(target_entries.size(), 2U);
- ASSERT_TARGET_ENTRY(target_entries[0], R::target::string::str1, Res_value::TYPE_REFERENCE,
+ ASSERT_TARGET_ENTRY(target_entries[0], R::target::string::str1,
0x0104000a); // -> android:string/ok
- ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str3, Res_value::TYPE_DYNAMIC_REFERENCE,
- R::overlay::string::str3);
+ ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str3, R::overlay::string::str3);
+
+ const auto& target_inline_entries = data->GetTargetInlineEntries();
+ ASSERT_EQ(target_inline_entries.size(), 0U);
const auto& overlay_entries = data->GetOverlayEntries();
ASSERT_EQ(overlay_entries.size(), 1U);
@@ -342,13 +354,17 @@ TEST(IdmapTests, CreateIdmapDataInlineResources) {
ASSERT_TRUE(idmap_data) << idmap_data.GetErrorMessage();
auto& data = *idmap_data;
- constexpr size_t overlay_string_pool_size = 8U;
const auto& target_entries = data->GetTargetEntries();
- ASSERT_EQ(target_entries.size(), 2U);
- ASSERT_TARGET_ENTRY(target_entries[0], R::target::integer::int1, Res_value::TYPE_INT_DEC,
- 73U); // -> 73
- ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str1, Res_value::TYPE_STRING,
- overlay_string_pool_size + 0U); // -> "Hello World"
+ ASSERT_EQ(target_entries.size(), 0U);
+
+ constexpr size_t overlay_string_pool_size = 8U;
+ const auto& target_inline_entries = data->GetTargetInlineEntries();
+ ASSERT_EQ(target_inline_entries.size(), 2U);
+ ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], R::target::integer::int1,
+ Res_value::TYPE_INT_DEC, 73U); // -> 73
+ ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[1], R::target::string::str1,
+ Res_value::TYPE_STRING,
+ overlay_string_pool_size + 0U); // -> "Hello World"
const auto& overlay_entries = data->GetOverlayEntries();
ASSERT_EQ(overlay_entries.size(), 0U);
@@ -479,9 +495,9 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) {
ASSERT_FALSE(bad_enforce_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(),
PolicyFlags::PUBLIC, /* enforce_overlayable */ true));
- // target path: bytes (0x15, 0x114)
+ // target path: bytes (0x18, 0x117)
std::string bad_target_path_string(stream.str());
- bad_target_path_string[0x15] = '\0';
+ bad_target_path_string[0x18] = '\0';
std::stringstream bad_target_path_stream(bad_target_path_string);
std::unique_ptr<const IdmapHeader> bad_target_path_header =
IdmapHeader::FromBinaryStream(bad_target_path_stream);
@@ -490,9 +506,9 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) {
ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(),
PolicyFlags::PUBLIC, /* enforce_overlayable */ true));
- // overlay path: bytes (0x115, 0x214)
+ // overlay path: bytes (0x118, 0x217)
std::string bad_overlay_path_string(stream.str());
- bad_overlay_path_string[0x115] = '\0';
+ bad_overlay_path_string[0x118] = '\0';
std::stringstream bad_overlay_path_stream(bad_overlay_path_string);
std::unique_ptr<const IdmapHeader> bad_overlay_path_header =
IdmapHeader::FromBinaryStream(bad_overlay_path_stream);
diff --git a/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp b/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp
index 9a10079772bf..d30fbfcb1d3c 100644
--- a/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp
+++ b/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp
@@ -56,7 +56,8 @@ TEST(PrettyPrintVisitorTests, CreatePrettyPrintVisitor) {
ASSERT_NE(stream.str().find("target apk path : "), std::string::npos);
ASSERT_NE(stream.str().find("overlay apk path : "), std::string::npos);
- ASSERT_NE(stream.str().find(R::target::integer::literal::int1 + " -> 0x7f010000 integer/int1\n"),
+ ASSERT_NE(stream.str().find(R::target::integer::literal::int1 +
+ " -> 0x7f010000 (integer/int1 -> integer/int1)\n"),
std::string::npos);
}
@@ -75,7 +76,7 @@ TEST(PrettyPrintVisitorTests, CreatePrettyPrintVisitorWithoutAccessToApks) {
ASSERT_NE(stream.str().find("target apk path : "), std::string::npos);
ASSERT_NE(stream.str().find("overlay apk path : "), std::string::npos);
- ASSERT_NE(stream.str().find("0x7f020000 -> 0x7f020000\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("0x7f020000 -> 0x7f020000 (\?\?\? -> \?\?\?)\n"), std::string::npos);
}
} // namespace android::idmap2
diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
index b268d5add141..95bd94733ab3 100644
--- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp
+++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
@@ -65,7 +65,7 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) {
(*idmap)->accept(&visitor);
ASSERT_CONTAINS_REGEX(ADDRESS "504d4449 magic\n", stream.str());
- ASSERT_CONTAINS_REGEX(ADDRESS "00000004 version\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "00000005 version\n", stream.str());
ASSERT_CONTAINS_REGEX(
StringPrintf(ADDRESS "%s target crc\n", android::idmap2::TestConstants::TARGET_CRC_STRING),
stream.str());
@@ -73,19 +73,19 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) {
StringPrintf(ADDRESS "%s overlay crc\n", android::idmap2::TestConstants::OVERLAY_CRC_STRING),
stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000001 fulfilled policies: public\n", stream.str());
- ASSERT_CONTAINS_REGEX(ADDRESS " 01 enforce overlayable\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "00000001 enforce overlayable\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS " 7f target package id\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS " 7f overlay package id\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000004 target entry count\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000004 overlay entry count\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000004 overlay entry count\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000008 string pool index offset\n", stream.str());
- ASSERT_CONTAINS_REGEX(ADDRESS "000000b4 string pool byte length\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 target id: integer/int1\n", stream.str());
- ASSERT_CONTAINS_REGEX(ADDRESS " 07 type: reference \\(dynamic\\)\n", stream.str());
- ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 value: integer/int1\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 overlay id: integer/int1\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 overlay id: integer/int1\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 target id: integer/int1\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "000000b4 string pool size\n", stream.str());
+ ASSERT_CONTAINS_REGEX("000002bc: ........ string pool: ...\n", stream.str());
}
TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) {
@@ -102,22 +102,26 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) {
(*idmap)->accept(&visitor);
ASSERT_CONTAINS_REGEX(ADDRESS "504d4449 magic\n", stream.str());
- ASSERT_CONTAINS_REGEX(ADDRESS "00000004 version\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "00000005 version\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00001234 target crc\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00005678 overlay crc\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000011 fulfilled policies: public|signature\n", stream.str());
- ASSERT_CONTAINS_REGEX(ADDRESS " 01 enforce overlayable\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "00000001 enforce overlayable\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS " 7f target package id\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS " 7f overlay package id\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000003 target entry count\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "00000001 target inline entry count\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000003 overlay entry count\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000000 string pool index offset\n", stream.str());
- ASSERT_CONTAINS_REGEX(ADDRESS "00000000 string pool byte length\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "7f020000 target id\n", stream.str());
- ASSERT_CONTAINS_REGEX(ADDRESS " 01 type: reference\n", stream.str());
- ASSERT_CONTAINS_REGEX(ADDRESS "7f020000 value\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "7f020000 overlay id\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "7f020000 target id\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS " 11 type: integer\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "12345678 data\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "7f020000 overlay id\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "7f030002 target id\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "00000004 string pool size\n", stream.str());
+ ASSERT_CONTAINS_REGEX("00000278: ........ string pool: ...\n", stream.str());
}
} // namespace android::idmap2
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index 3ec6ac24b238..185e9292346d 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -77,30 +77,61 @@ Result<ResourceMapping> TestGetResourceMapping(const android::StringPiece& local
fulfilled_policies, enforce_overlayable);
}
-Result<Unit> MappingExists(const ResourceMapping& mapping, const ResourceId& target_resource,
- const uint8_t type, const uint32_t value, bool rewrite) {
+Result<Unit> MappingExists(const ResourceMapping& mapping, ResourceId target_resource,
+ ResourceId overlay_resource, bool rewrite) {
auto target_map = mapping.GetTargetToOverlayMap();
auto entry_map = target_map.find(target_resource);
if (entry_map == target_map.end()) {
return Error("Failed to find mapping for target resource");
}
- if (entry_map->second.data_type != type) {
- return Error(R"(Expected type: "0x%02x" Actual type: "0x%02x")", type,
- entry_map->second.data_type);
+ auto actual_overlay_resource = std::get_if<ResourceId>(&entry_map->second);
+ if (actual_overlay_resource == nullptr) {
+ return Error("Target resource is not mapped to an overlay resource id");
}
- if (entry_map->second.data_value != value) {
- return Error(R"(Expected value: "0x%08x" Actual value: "0x%08x")", type,
- entry_map->second.data_value);
+ if (*actual_overlay_resource != overlay_resource) {
+ return Error(R"(Expected id: "0x%02x" Actual id: "0x%02x")", overlay_resource,
+ *actual_overlay_resource);
}
auto overlay_map = mapping.GetOverlayToTargetMap();
- auto overlay_iter = overlay_map.find(entry_map->second.data_value);
+ auto overlay_iter = overlay_map.find(overlay_resource);
if ((overlay_iter != overlay_map.end()) != rewrite) {
return Error(R"(Expected rewriting: "%s")", rewrite ? "true" : "false");
}
+ if (rewrite && overlay_iter->second != target_resource) {
+ return Error(R"(Expected rewrite id: "0x%02x" Actual id: "0x%02x")", target_resource,
+ overlay_iter->second);
+ }
+
+ return Result<Unit>({});
+}
+
+Result<Unit> MappingExists(const ResourceMapping& mapping, const ResourceId& target_resource,
+ const uint8_t type, const uint32_t value) {
+ auto target_map = mapping.GetTargetToOverlayMap();
+ auto entry_map = target_map.find(target_resource);
+ if (entry_map == target_map.end()) {
+ return Error("Failed to find mapping for target resource");
+ }
+
+ auto actual_overlay_value = std::get_if<TargetValue>(&entry_map->second);
+ if (actual_overlay_value == nullptr) {
+ return Error("Target resource is not mapped to an inline value");
+ }
+
+ if (actual_overlay_value->data_type != type) {
+ return Error(R"(Expected type: "0x%02x" Actual type: "0x%02x")", type,
+ actual_overlay_value->data_type);
+ }
+
+ if (actual_overlay_value->data_value != value) {
+ return Error(R"(Expected value: "0x%08x" Actual value: "0x%08x")", type,
+ actual_overlay_value->data_value);
+ }
+
return Result<Unit>({});
}
@@ -116,14 +147,14 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsLegacy) {
ASSERT_TRUE(resources) << resources.GetErrorMessage();
auto& res = *resources;
ASSERT_EQ(res.GetTargetToOverlayMap().size(), 4U);
- ASSERT_RESULT(MappingExists(res, R::target::integer::int1, Res_value::TYPE_REFERENCE,
- R::overlay::integer::int1, false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::str1, Res_value::TYPE_REFERENCE,
- R::overlay::string::str1, false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::str3, Res_value::TYPE_REFERENCE,
- R::overlay::string::str3, false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::str4, Res_value::TYPE_REFERENCE,
- R::overlay::string::str4, false /* rewrite */));
+ ASSERT_RESULT(
+ MappingExists(res, R::target::integer::int1, R::overlay::integer::int1, false /* rewrite */));
+ ASSERT_RESULT(
+ MappingExists(res, R::target::string::str1, R::overlay::string::str1, false /* rewrite */));
+ ASSERT_RESULT(
+ MappingExists(res, R::target::string::str3, R::overlay::string::str3, false /* rewrite */));
+ ASSERT_RESULT(
+ MappingExists(res, R::target::string::str4, R::overlay::string::str4, false /* rewrite */));
}
TEST(ResourceMappingTests, ResourcesFromApkAssetsNonMatchingNames) {
@@ -138,12 +169,12 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsNonMatchingNames) {
ASSERT_TRUE(resources) << resources.GetErrorMessage();
auto& res = *resources;
ASSERT_EQ(res.GetTargetToOverlayMap().size(), 3U);
- ASSERT_RESULT(MappingExists(res, R::target::string::str1, Res_value::TYPE_DYNAMIC_REFERENCE,
- R::overlay::string::str4, true /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::str3, Res_value::TYPE_DYNAMIC_REFERENCE,
- R::overlay::string::str1, true /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::str4, Res_value::TYPE_DYNAMIC_REFERENCE,
- R::overlay::string::str3, true /* rewrite */));
+ ASSERT_RESULT(
+ MappingExists(res, R::target::string::str1, R::overlay::string::str4, true /* rewrite */));
+ ASSERT_RESULT(
+ MappingExists(res, R::target::string::str3, R::overlay::string::str1, true /* rewrite */));
+ ASSERT_RESULT(
+ MappingExists(res, R::target::string::str4, R::overlay::string::str3, true /* rewrite */));
}
TEST(ResourceMappingTests, DoNotRewriteNonOverlayResourceId) {
@@ -159,10 +190,9 @@ TEST(ResourceMappingTests, DoNotRewriteNonOverlayResourceId) {
auto& res = *resources;
ASSERT_EQ(res.GetTargetToOverlayMap().size(), 2U);
ASSERT_EQ(res.GetOverlayToTargetMap().size(), 1U);
- ASSERT_RESULT(MappingExists(res, R::target::string::str1, Res_value::TYPE_REFERENCE, 0x0104000a,
+ ASSERT_RESULT(MappingExists(res, R::target::string::str1, 0x0104000a,
false /* rewrite */)); // -> android:string/ok
- ASSERT_RESULT(MappingExists(res, R::target::string::str3, Res_value::TYPE_DYNAMIC_REFERENCE,
- 0x7f020001, true /* rewrite */));
+ ASSERT_RESULT(MappingExists(res, R::target::string::str3, 0x7f020001, true /* rewrite */));
}
TEST(ResourceMappingTests, InlineResources) {
@@ -180,10 +210,8 @@ TEST(ResourceMappingTests, InlineResources) {
ASSERT_EQ(res.GetTargetToOverlayMap().size(), 2U);
ASSERT_EQ(res.GetOverlayToTargetMap().size(), 0U);
ASSERT_RESULT(MappingExists(res, R::target::string::str1, Res_value::TYPE_STRING,
- overlay_string_pool_size + 0U,
- false /* rewrite */)); // -> "Hello World"
- ASSERT_RESULT(MappingExists(res, R::target::integer::int1, Res_value::TYPE_INT_DEC, 73U,
- false /* rewrite */)); // -> 73
+ overlay_string_pool_size + 0U)); // -> "Hello World"
+ ASSERT_RESULT(MappingExists(res, R::target::integer::int1, Res_value::TYPE_INT_DEC, 73U));
}
TEST(ResourceMappingTests, CreateIdmapFromApkAssetsPolicySystemPublic) {
@@ -195,13 +223,13 @@ TEST(ResourceMappingTests, CreateIdmapFromApkAssetsPolicySystemPublic) {
ASSERT_TRUE(resources) << resources.GetErrorMessage();
auto& res = *resources;
ASSERT_EQ(res.GetTargetToOverlayMap().size(), 3U);
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_public,
R::system_overlay::string::policy_public, false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_system,
R::system_overlay::string::policy_system, false /* rewrite */));
- ASSERT_RESULT(
- MappingExists(res, R::target::string::policy_system_vendor, Res_value::TYPE_REFERENCE,
- R::system_overlay::string::policy_system_vendor, false /* rewrite */));
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor,
+ R::system_overlay::string::policy_system_vendor,
+ false /* rewrite */));
}
// Resources that are not declared as overlayable and resources that a protected by policies the
@@ -215,15 +243,15 @@ TEST(ResourceMappingTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) {
ASSERT_TRUE(resources) << resources.GetErrorMessage();
auto& res = *resources;
ASSERT_EQ(res.GetTargetToOverlayMap().size(), 3U);
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_public,
R::system_overlay_invalid::string::policy_public,
false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_system,
R::system_overlay_invalid::string::policy_system,
false /* rewrite */));
- ASSERT_RESULT(
- MappingExists(res, R::target::string::policy_system_vendor, Res_value::TYPE_REFERENCE,
- R::system_overlay_invalid::string::policy_system_vendor, false /* rewrite */));
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor,
+ R::system_overlay_invalid::string::policy_system_vendor,
+ false /* rewrite */));
}
// Resources that are not declared as overlayable and resources that a protected by policies the
@@ -238,37 +266,36 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsPolicySystemPublicInvalidIgnore
ASSERT_TRUE(resources) << resources.GetErrorMessage();
auto& res = *resources;
ASSERT_EQ(res.GetTargetToOverlayMap().size(), 11U);
- ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable,
R::system_overlay_invalid::string::not_overlayable,
false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::other, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::other,
R::system_overlay_invalid::string::other, false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_actor, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_actor,
R::system_overlay_invalid::string::policy_actor,
false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm,
R::system_overlay_invalid::string::policy_odm, false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem,
R::system_overlay_invalid::string::policy_oem, false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_product, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_product,
R::system_overlay_invalid::string::policy_product,
false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_public,
R::system_overlay_invalid::string::policy_public,
false /* rewrite */));
ASSERT_RESULT(MappingExists(res, R::target::string::policy_config_signature,
- Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::policy_config_signature,
false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature,
R::system_overlay_invalid::string::policy_signature,
false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_system,
R::system_overlay_invalid::string::policy_system,
false /* rewrite */));
- ASSERT_RESULT(
- MappingExists(res, R::target::string::policy_system_vendor, Res_value::TYPE_REFERENCE,
- R::system_overlay_invalid::string::policy_system_vendor, false /* rewrite */));
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor,
+ R::system_overlay_invalid::string::policy_system_vendor,
+ false /* rewrite */));
}
// Overlays that do not target an <overlayable> tag can overlay resources defined within any
@@ -281,14 +308,14 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsNoDefinedOverlayableAndNoTarget
ASSERT_TRUE(resources) << resources.GetErrorMessage();
auto& res = *resources;
ASSERT_EQ(res.GetTargetToOverlayMap().size(), 4U);
- ASSERT_RESULT(MappingExists(res, R::target::integer::int1, Res_value::TYPE_REFERENCE,
- R::overlay::integer::int1, false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::str1, Res_value::TYPE_REFERENCE,
- R::overlay::string::str1, false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::str3, Res_value::TYPE_REFERENCE,
- R::overlay::string::str3, false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::str4, Res_value::TYPE_REFERENCE,
- R::overlay::string::str4, false /* rewrite */));
+ ASSERT_RESULT(
+ MappingExists(res, R::target::integer::int1, R::overlay::integer::int1, false /* rewrite */));
+ ASSERT_RESULT(
+ MappingExists(res, R::target::string::str1, R::overlay::string::str1, false /* rewrite */));
+ ASSERT_RESULT(
+ MappingExists(res, R::target::string::str3, R::overlay::string::str3, false /* rewrite */));
+ ASSERT_RESULT(
+ MappingExists(res, R::target::string::str4, R::overlay::string::str4, false /* rewrite */));
}
// Overlays that are neither pre-installed nor signed with the same signature as the target cannot
@@ -302,9 +329,9 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPoliciesPublicFail) {
ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 0U);
}
-// Overlays that are pre-installed or are signed with the same signature as the target or are signed
-// with the same signature as the reference package can overlay packages that have not defined
-// overlayable resources.
+// Overlays that are pre-installed or are signed with the same signature as the target or are
+// signed with the same signature as the reference package can overlay packages that have not
+// defined overlayable resources.
TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
auto CheckEntries = [&](const PolicyBitmask& fulfilled_policies) -> void {
auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
@@ -315,39 +342,38 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
ASSERT_TRUE(resources) << resources.GetErrorMessage();
auto& res = *resources;
ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 11U);
- ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable,
R::system_overlay_invalid::string::not_overlayable,
false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::other, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::other,
R::system_overlay_invalid::string::other, false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_actor, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_actor,
R::system_overlay_invalid::string::policy_actor,
false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm,
R::system_overlay_invalid::string::policy_odm,
false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem,
R::system_overlay_invalid::string::policy_oem,
false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_product, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_product,
R::system_overlay_invalid::string::policy_product,
false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_public,
R::system_overlay_invalid::string::policy_public,
false /* rewrite */));
ASSERT_RESULT(MappingExists(res, R::target::string::policy_config_signature,
- Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::policy_config_signature,
false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature,
R::system_overlay_invalid::string::policy_signature,
false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, Res_value::TYPE_REFERENCE,
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_system,
R::system_overlay_invalid::string::policy_system,
false /* rewrite */));
- ASSERT_RESULT(MappingExists(
- res, R::target::string::policy_system_vendor, Res_value::TYPE_REFERENCE,
- R::system_overlay_invalid::string::policy_system_vendor, false /* rewrite */));
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor,
+ R::system_overlay_invalid::string::policy_system_vendor,
+ false /* rewrite */));
};
CheckEntries(PolicyFlags::SIGNATURE);
diff --git a/cmds/idmap2/tests/TestConstants.h b/cmds/idmap2/tests/TestConstants.h
index 641a7a8d45aa..9bbb065f46f0 100644
--- a/cmds/idmap2/tests/TestConstants.h
+++ b/cmds/idmap2/tests/TestConstants.h
@@ -19,7 +19,7 @@
namespace android::idmap2::TestConstants {
-constexpr const auto TARGET_CRC = 0x7c2d4719;
+constexpr const auto TARGET_CRC = 0x7c2d4719;
constexpr const auto TARGET_CRC_STRING = "7c2d4719";
constexpr const auto OVERLAY_CRC = 0x5afff726;
diff --git a/cmds/idmap2/tests/TestHelpers.h b/cmds/idmap2/tests/TestHelpers.h
index b599dcb0069a..d0a8e3db8eca 100644
--- a/cmds/idmap2/tests/TestHelpers.h
+++ b/cmds/idmap2/tests/TestHelpers.h
@@ -30,7 +30,7 @@ const unsigned char idmap_raw_data[] = {
0x49, 0x44, 0x4d, 0x50,
// 0x4: version
- 0x04, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00,
// 0x8: target crc
0x34, 0x12, 0x00, 0x00,
@@ -42,9 +42,9 @@ const unsigned char idmap_raw_data[] = {
0x11, 0x00, 0x00, 0x00,
// 0x14: enforce overlayable
- 0x01,
+ 0x01, 0x00, 0x00, 0x00,
- // 0x15: target path "targetX.apk"
+ // 0x18: target path "targetX.apk"
0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x58, 0x2e, 0x61, 0x70, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -62,7 +62,7 @@ const unsigned char idmap_raw_data[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- // 0x115: overlay path "overlayX.apk"
+ // 0x118: overlay path "overlayX.apk"
0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x58, 0x2e, 0x61, 0x70, 0x6b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -80,71 +80,89 @@ const unsigned char idmap_raw_data[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- // 0x215: debug string
- // string length, including terminating null
- 0x08, 0x00, 0x00, 0x00,
+ // 0x218: debug string
+ // string length,
+ 0x05, 0x00, 0x00, 0x00,
- // string contents "debug\0\0\0" (padded to word alignment)
+ // 0x21c string contents "debug\0\0\0" (padded to word alignment)
0x64, 0x65, 0x62, 0x75, 0x67, 0x00, 0x00, 0x00,
// DATA HEADER
- // 0x221: target_package_id
+ // 0x224: target_package_id
0x7f,
- // 0x222: overlay_package_id
+ // 0x225: overlay_package_id
0x7f,
- // 0x223: target_entry_count
- 0x03, 0x00, 0x00, 0x00,
+ // 0x226: padding
+ 0x00, 0x00,
- // 0x227: overlay_entry_count
+ // 0x228: target_entry_count
0x03, 0x00, 0x00, 0x00,
- // 0x22b: string_pool_offset
- 0x00, 0x00, 0x00, 0x00,
+ // 0x22c: target_inline_entry_count
+ 0x01, 0x00, 0x00, 0x00,
+
+ // 0x230: overlay_entry_count
+ 0x03, 0x00, 0x00, 0x00,
- // 0x22f: string_pool_byte_length
+ // 0x234: string_pool_offset
0x00, 0x00, 0x00, 0x00,
// TARGET ENTRIES
- // 0x233: 0x7f020000
+ // 0x238: target id (0x7f020000)
0x00, 0x00, 0x02, 0x7f,
- // 0x237: TYPE_REFERENCE
- 0x01,
-
- // 0x238: 0x7f020000
+ // 0x23c: overlay_id (0x7f020000)
0x00, 0x00, 0x02, 0x7f,
- // 0x23c: 0x7f030000
+ // 0x240: target id (0x7f030000)
0x00, 0x00, 0x03, 0x7f,
- // 0x240: TYPE_REFERENCE
- 0x01,
-
- // 0x241: 0x7f030000
+ // 0x244: overlay_id (0x7f030000)
0x00, 0x00, 0x03, 0x7f,
- // 0x245: 0x7f030002
+ // 0x248: target id (0x7f030002)
0x02, 0x00, 0x03, 0x7f,
- // 0x249: TYPE_REFERENCE
- 0x01,
-
- // 0x24a: 0x7f030001
+ // 0x24c: overlay_id (0x7f030001)
0x01, 0x00, 0x03, 0x7f,
+ // INLINE TARGET ENTRIES
+
+ // 0x250: target_id
+ 0x00, 0x00, 0x04, 0x7f,
+
+ // 0x254: Res_value::size (value ignored by idmap)
+ 0x08, 0x00,
+
+ // 0x256: Res_value::res0 (value ignored by idmap)
+ 0x00,
+
+ // 0x257: Res_value::dataType (TYPE_INT_HEX)
+ 0x11,
+
+ // 0x258: Res_value::data
+ 0x78, 0x56, 0x34, 0x12,
+
// OVERLAY ENTRIES
- // 0x24e: 0x7f020000 -> 0x7f020000
+ // 0x25c: 0x7f020000 -> 0x7f020000
0x00, 0x00, 0x02, 0x7f, 0x00, 0x00, 0x02, 0x7f,
- // 0x256: 0x7f030000 -> 0x7f030000
+ // 0x264: 0x7f030000 -> 0x7f030000
0x00, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x03, 0x7f,
- // 0x25e: 0x7f030001 -> 0x7f030002
- 0x01, 0x00, 0x03, 0x7f, 0x02, 0x00, 0x03, 0x7f};
+ // 0x26c: 0x7f030001 -> 0x7f030002
+ 0x01, 0x00, 0x03, 0x7f, 0x02, 0x00, 0x03, 0x7f,
+
+ // 0x274: string pool
+ // string length,
+ 0x04, 0x00, 0x00, 0x00,
+
+ // 0x278 string contents "test" (padded to word alignment)
+ 0x74, 0x65, 0x73, 0x74};
-const unsigned int idmap_raw_data_len = 0x266;
+const unsigned int idmap_raw_data_len = 0x27c;
std::string GetTestDataPath();
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index b9765ea7212c..99dd3134ff8a 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -39,10 +39,8 @@
namespace android {
struct FindEntryResult {
- // A pointer to the resource table entry for this resource.
- // If the size of the entry is > sizeof(ResTable_entry), it can be cast to
- // a ResTable_map_entry and processed as a bag/map.
- ResTable_entry_handle entry;
+ // A pointer to the value of the resource table entry.
+ std::variant<Res_value, const ResTable_map_entry*> entry;
// The configuration for which the resulting entry was defined. This is already swapped to host
// endianness.
@@ -554,11 +552,9 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri
if (!overlay_entry) {
// No id map entry exists for this target resource.
continue;
- }
-
- if (overlay_entry.IsTableEntry()) {
+ } else if (overlay_entry.IsInlineValue()) {
// The target resource is overlaid by an inline value not represented by a resource.
- out_entry->entry = overlay_entry.GetTableEntry();
+ out_entry->entry = overlay_entry.GetInlineValue();
out_entry->dynamic_ref_table = id_map.overlay_res_maps_.GetOverlayDynamicRefTable();
cookie = id_map.cookie;
continue;
@@ -580,7 +576,7 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri
}
cookie = overlay_cookie;
- out_entry->entry = std::move(overlay_result.entry);
+ out_entry->entry = overlay_result.entry;
out_entry->config = overlay_result.config;
out_entry->dynamic_ref_table = id_map.overlay_res_maps_.GetOverlayDynamicRefTable();
if (resource_resolution_logging_enabled_) {
@@ -761,7 +757,19 @@ ApkAssetsCookie AssetManager2::FindEntryInternal(const PackageGroup& package_gro
return kInvalidCookie;
}
- out_entry->entry = ResTable_entry_handle::unmanaged(best_entry);
+ const uint16_t entry_size = dtohs(best_entry->size);
+ if (entry_size >= sizeof(ResTable_map_entry) &&
+ (dtohs(best_entry->flags) & ResTable_entry::FLAG_COMPLEX)) {
+ // The entry represents a bag/map.
+ out_entry->entry = reinterpret_cast<const ResTable_map_entry*>(best_entry);
+ } else {
+ // The entry represents a value.
+ Res_value value;
+ value.copyFrom_dtoh(*reinterpret_cast<const Res_value*>(
+ reinterpret_cast<const uint8_t*>(best_entry) + entry_size));
+ out_entry->entry = value;
+ }
+
out_entry->config = *best_config;
out_entry->type_flags = type_flags;
out_entry->package_name = &best_package->GetPackageName();
@@ -905,8 +913,8 @@ ApkAssetsCookie AssetManager2::GetResource(uint32_t resid, bool may_be_bag,
return kInvalidCookie;
}
- const ResTable_entry* table_entry = *entry.entry;
- if (dtohs(table_entry->flags) & ResTable_entry::FLAG_COMPLEX) {
+ auto result_map_entry = std::get_if<const ResTable_map_entry*>(&entry.entry);
+ if (result_map_entry != nullptr) {
if (!may_be_bag) {
LOG(ERROR) << base::StringPrintf("Resource %08x is a complex map type.", resid);
return kInvalidCookie;
@@ -920,11 +928,8 @@ ApkAssetsCookie AssetManager2::GetResource(uint32_t resid, bool may_be_bag,
return cookie;
}
- const Res_value* device_value = reinterpret_cast<const Res_value*>(
- reinterpret_cast<const uint8_t*>(table_entry) + dtohs(table_entry->size));
- out_value->copyFrom_dtoh(*device_value);
-
// Convert the package ID to the runtime assigned package ID.
+ *out_value = std::get<Res_value>(entry.entry);
entry.dynamic_ref_table->lookupResourceValue(out_value);
*out_selected_config = entry.config;
@@ -1004,19 +1009,15 @@ const ResolvedBag* AssetManager2::GetBag(uint32_t resid, std::vector<uint32_t>&
return nullptr;
}
- // Check that the size of the entry header is at least as big as
- // the desired ResTable_map_entry. Also verify that the entry
- // was intended to be a map.
- const ResTable_entry* table_entry = *entry.entry;
- if (dtohs(table_entry->size) < sizeof(ResTable_map_entry) ||
- (dtohs(table_entry->flags) & ResTable_entry::FLAG_COMPLEX) == 0) {
+ auto result_map_entry = std::get_if<const ResTable_map_entry*>(&entry.entry);
+ if (result_map_entry == nullptr) {
// Not a bag, nothing to do.
return nullptr;
}
- const ResTable_map_entry* map = reinterpret_cast<const ResTable_map_entry*>(table_entry);
- const ResTable_map* map_entry =
- reinterpret_cast<const ResTable_map*>(reinterpret_cast<const uint8_t*>(map) + map->size);
+ auto map = reinterpret_cast<const ResTable_map_entry*>(*result_map_entry);
+ auto map_entry = reinterpret_cast<const ResTable_map*>(
+ reinterpret_cast<const uint8_t*>(map) + map->size);
const ResTable_map* const map_entry_end = map_entry + dtohl(map->count);
// Keep track of ids that have already been seen to prevent infinite loops caused by circular
diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp
index 5f231ffe4786..4e03ce5d9584 100644
--- a/libs/androidfw/Idmap.cpp
+++ b/libs/androidfw/Idmap.cpp
@@ -36,16 +36,12 @@ using ::android::base::StringPrintf;
namespace android {
-static bool compare_target_entries(const Idmap_target_entry &e1, const uint32_t target_id) {
- return dtohl(e1.target_id) < target_id;
-}
-
-static bool compare_overlay_entries(const Idmap_overlay_entry& e1, const uint32_t overlay_id) {
- return dtohl(e1.overlay_id) < overlay_id;
+uint32_t round_to_4_bytes(uint32_t size) {
+ return size + (4U - (size % 4U)) % 4U;
}
size_t Idmap_header::Size() const {
- return sizeof(Idmap_header) + sizeof(uint8_t) * dtohl(debug_info_size);
+ return sizeof(Idmap_header) + sizeof(uint8_t) * round_to_4_bytes(dtohl(debug_info_size));
}
OverlayStringPool::OverlayStringPool(const LoadedIdmap* loaded_idmap)
@@ -88,7 +84,10 @@ OverlayDynamicRefTable::OverlayDynamicRefTable(const Idmap_data_header* data_hea
status_t OverlayDynamicRefTable::lookupResourceId(uint32_t* resId) const {
const Idmap_overlay_entry* first_entry = entries_;
const Idmap_overlay_entry* end_entry = entries_ + dtohl(data_header_->overlay_entry_count);
- auto entry = std::lower_bound(first_entry, end_entry, *resId, compare_overlay_entries);
+ auto entry = std::lower_bound(first_entry, end_entry, *resId,
+ [](const Idmap_overlay_entry& e1, const uint32_t overlay_id) {
+ return dtohl(e1.overlay_id) < overlay_id;
+ });
if (entry == end_entry || dtohl(entry->overlay_id) != *resId) {
// A mapping for the target resource id could not be found.
@@ -96,7 +95,7 @@ status_t OverlayDynamicRefTable::lookupResourceId(uint32_t* resId) const {
}
*resId = (0x00FFFFFFU & dtohl(entry->target_id))
- | (((uint32_t) target_assigned_package_id_) << 24);
+ | (((uint32_t) target_assigned_package_id_) << 24U);
return NO_ERROR;
}
@@ -106,62 +105,58 @@ status_t OverlayDynamicRefTable::lookupResourceIdNoRewrite(uint32_t* resId) cons
IdmapResMap::IdmapResMap(const Idmap_data_header* data_header,
const Idmap_target_entry* entries,
+ const Idmap_target_entry_inline* inline_entries,
uint8_t target_assigned_package_id,
const OverlayDynamicRefTable* overlay_ref_table)
: data_header_(data_header),
entries_(entries),
+ inline_entries_(inline_entries),
target_assigned_package_id_(target_assigned_package_id),
- overlay_ref_table_(overlay_ref_table) { };
+ overlay_ref_table_(overlay_ref_table) { }
IdmapResMap::Result IdmapResMap::Lookup(uint32_t target_res_id) const {
- if ((target_res_id >> 24) != target_assigned_package_id_) {
+ if ((target_res_id >> 24U) != target_assigned_package_id_) {
// The resource id must have the same package id as the target package.
return {};
}
// The resource ids encoded within the idmap are build-time resource ids.
target_res_id = (0x00FFFFFFU & target_res_id)
- | (((uint32_t) data_header_->target_package_id) << 24);
-
- const Idmap_target_entry* first_entry = entries_;
- const Idmap_target_entry* end_entry = entries_ + dtohl(data_header_->target_entry_count);
- auto entry = std::lower_bound(first_entry, end_entry, target_res_id, compare_target_entries);
-
- if (entry == end_entry || dtohl(entry->target_id) != target_res_id) {
- // A mapping for the target resource id could not be found.
- return {};
- }
-
- // A reference should be treated as an alias of the resource. Instead of returning the table
- // entry, return the alias resource id to look up. The alias resource might not reside within the
- // overlay package, so the resource id must be fixed with the dynamic reference table of the
- // overlay before returning.
- if (entry->type == Res_value::TYPE_REFERENCE
- || entry->type == Res_value::TYPE_DYNAMIC_REFERENCE) {
- uint32_t overlay_resource_id = dtohl(entry->value);
-
+ | (((uint32_t) data_header_->target_package_id) << 24U);
+
+ // Check if the target resource is mapped to an overlay resource.
+ auto first_entry = entries_;
+ auto end_entry = entries_ + dtohl(data_header_->target_entry_count);
+ auto entry = std::lower_bound(first_entry, end_entry, target_res_id,
+ [](const Idmap_target_entry &e, const uint32_t target_id) {
+ return dtohl(e.target_id) < target_id;
+ });
+
+ if (entry != end_entry && dtohl(entry->target_id) == target_res_id) {
+ uint32_t overlay_resource_id = dtohl(entry->overlay_id);
// Lookup the resource without rewriting the overlay resource id back to the target resource id
// being looked up.
overlay_ref_table_->lookupResourceIdNoRewrite(&overlay_resource_id);
return Result(overlay_resource_id);
}
- // Copy the type and value into the ResTable_entry structure needed by asset manager.
- uint16_t malloc_size = sizeof(ResTable_entry) + sizeof(Res_value);
- auto table_entry = reinterpret_cast<ResTable_entry*>(malloc(malloc_size));
- memset(table_entry, 0, malloc_size);
- table_entry->size = htods(sizeof(ResTable_entry));
-
- auto table_value = reinterpret_cast<Res_value*>(reinterpret_cast<uint8_t*>(table_entry)
- + sizeof(ResTable_entry));
- table_value->dataType = entry->type;
- table_value->data = entry->value;
-
- return Result(ResTable_entry_handle::managed(table_entry, [](auto p) { free(p); }));
+ // Check if the target resources is mapped to an inline table entry.
+ auto first_inline_entry = inline_entries_;
+ auto end_inline_entry = inline_entries_ + dtohl(data_header_->target_inline_entry_count);
+ auto inline_entry = std::lower_bound(first_inline_entry, end_inline_entry, target_res_id,
+ [](const Idmap_target_entry_inline &e,
+ const uint32_t target_id) {
+ return dtohl(e.target_id) < target_id;
+ });
+
+ if (inline_entry != end_inline_entry && dtohl(inline_entry->target_id) == target_res_id) {
+ return Result(inline_entry->value);
+ }
+ return {};
}
static bool is_word_aligned(const void* data) {
- return (reinterpret_cast<uintptr_t>(data) & 0x03) == 0;
+ return (reinterpret_cast<uintptr_t>(data) & 0x03U) == 0U;
}
static bool IsValidIdmapHeader(const StringPiece& data) {
@@ -175,7 +170,7 @@ static bool IsValidIdmapHeader(const StringPiece& data) {
return false;
}
- const Idmap_header* header = reinterpret_cast<const Idmap_header*>(data.data());
+ auto header = reinterpret_cast<const Idmap_header*>(data.data());
if (dtohl(header->magic) != kIdmapMagic) {
LOG(ERROR) << StringPrintf("Invalid Idmap file: bad magic value (was 0x%08x, expected 0x%08x)",
dtohl(header->magic), kIdmapMagic);
@@ -198,11 +193,13 @@ LoadedIdmap::LoadedIdmap(std::string&& idmap_path,
const Idmap_header* header,
const Idmap_data_header* data_header,
const Idmap_target_entry* target_entries,
+ const Idmap_target_entry_inline* target_inline_entries,
const Idmap_overlay_entry* overlay_entries,
ResStringPool* string_pool)
: header_(header),
data_header_(data_header),
target_entries_(target_entries),
+ target_inline_entries_(target_inline_entries),
overlay_entries_(overlay_entries),
string_pool_(string_pool),
idmap_path_(std::move(idmap_path)),
@@ -233,7 +230,7 @@ std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_pa
data_ptr += sizeof(*data_header);
data_size -= sizeof(*data_header);
- // Make sure there is enough space for the target entries declared in the header.
+ // Make sure there is enough space for the target entries declared in the header
const auto target_entries = reinterpret_cast<const Idmap_target_entry*>(data_ptr);
if (data_size / sizeof(Idmap_target_entry) <
static_cast<size_t>(dtohl(data_header->target_entry_count))) {
@@ -248,6 +245,21 @@ std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_pa
data_ptr += target_entry_size_bytes;
data_size -= target_entry_size_bytes;
+ // Make sure there is enough space for the target entries declared in the header.
+ const auto target_inline_entries = reinterpret_cast<const Idmap_target_entry_inline*>(data_ptr);
+ if (data_size / sizeof(Idmap_target_entry_inline) <
+ static_cast<size_t>(dtohl(data_header->target_inline_entry_count))) {
+ LOG(ERROR) << StringPrintf("Idmap too small for the number of target inline entries (%d)",
+ (int)dtohl(data_header->target_inline_entry_count));
+ return {};
+ }
+
+ // Advance the data pointer past the target entries.
+ const size_t target_inline_entry_size_bytes =
+ (dtohl(data_header->target_inline_entry_count) * sizeof(Idmap_target_entry_inline));
+ data_ptr += target_inline_entry_size_bytes;
+ data_size -= target_inline_entry_size_bytes;
+
// Make sure there is enough space for the overlay entries declared in the header.
const auto overlay_entries = reinterpret_cast<const Idmap_overlay_entry*>(data_ptr);
if (data_size / sizeof(Idmap_overlay_entry) <
@@ -257,22 +269,26 @@ std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_pa
return {};
}
- // Advance the data pointer past the target entries.
+ // Advance the data pointer past the overlay entries.
const size_t overlay_entry_size_bytes =
(dtohl(data_header->overlay_entry_count) * sizeof(Idmap_overlay_entry));
data_ptr += overlay_entry_size_bytes;
data_size -= overlay_entry_size_bytes;
// Read the idmap string pool that holds the value of inline string entries.
- if (data_size < dtohl(data_header->string_pool_length)) {
+ uint32_t string_pool_size = dtohl(*reinterpret_cast<const uint32_t*>(data_ptr));
+ data_ptr += sizeof(uint32_t);
+ data_size -= sizeof(uint32_t);
+
+ if (data_size < string_pool_size) {
LOG(ERROR) << StringPrintf("Idmap too small for string pool (length %d)",
- (int)dtohl(data_header->string_pool_length));
+ (int)string_pool_size);
return {};
}
auto idmap_string_pool = util::make_unique<ResStringPool>();
- if (dtohl(data_header->string_pool_length) > 0) {
- status_t err = idmap_string_pool->setTo(data_ptr, dtohl(data_header->string_pool_length));
+ if (string_pool_size > 0) {
+ status_t err = idmap_string_pool->setTo(data_ptr, string_pool_size);
if (err != NO_ERROR) {
LOG(ERROR) << "idmap string pool corrupt.";
return {};
@@ -280,9 +296,10 @@ std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_pa
}
// Can't use make_unique because LoadedIdmap constructor is private.
- std::unique_ptr<LoadedIdmap> loaded_idmap = std::unique_ptr<LoadedIdmap>(
+ auto loaded_idmap = std::unique_ptr<LoadedIdmap>(
new LoadedIdmap(idmap_path.to_string(), getFileModDate(idmap_path.data()), header,
- data_header, target_entries, overlay_entries, idmap_string_pool.release()));
+ data_header, target_entries, target_inline_entries, overlay_entries,
+ idmap_string_pool.release()));
return std::move(loaded_idmap);
}
diff --git a/libs/androidfw/include/androidfw/Idmap.h b/libs/androidfw/include/androidfw/Idmap.h
index ecc1ce65d124..ab0f47f025d2 100644
--- a/libs/androidfw/include/androidfw/Idmap.h
+++ b/libs/androidfw/include/androidfw/Idmap.h
@@ -77,40 +77,40 @@ class OverlayDynamicRefTable : public DynamicRefTable {
// A mapping of target resource ids to a values or resource ids that should overlay the target.
class IdmapResMap {
public:
- // Represents the result of a idmap lookup. The result can be one of three possibillities:
+ // Represents the result of a idmap lookup. The result can be one of three possibilities:
// 1) The result is a resource id which represents the overlay resource that should act as an
// alias of the target resource.
// 2) The result is a table entry which overlays the type and value of the target resource.
// 3) The result is neither and the target resource is not overlaid.
class Result {
public:
- Result() : data_(nullptr) {};
+ Result() = default;
explicit Result(uint32_t value) : data_(value) {};
- explicit Result(ResTable_entry_handle&& value) : data_(value) { };
+ explicit Result(const Res_value& value) : data_(value) { };
// Returns `true` if the resource is overlaid.
- inline explicit operator bool() const {
- return !std::get_if<nullptr_t>(&data_);
+ explicit operator bool() const {
+ return std::get_if<std::monostate>(&data_) == nullptr;
}
- inline bool IsResourceId() const {
- return std::get_if<uint32_t>(&data_);
+ bool IsResourceId() const {
+ return std::get_if<uint32_t>(&data_) != nullptr;
}
- inline uint32_t GetResourceId() const {
- return *std::get_if<uint32_t>(&data_);
+ uint32_t GetResourceId() const {
+ return std::get<uint32_t>(data_);
}
- inline bool IsTableEntry() const {
- return std::get_if<ResTable_entry_handle>(&data_);
+ bool IsInlineValue() const {
+ return std::get_if<Res_value>(&data_) != nullptr;
}
- inline const ResTable_entry_handle& GetTableEntry() const {
- return *std::get_if<ResTable_entry_handle>(&data_);
+ const Res_value& GetInlineValue() const {
+ return std::get<Res_value>(data_);
}
private:
- std::variant<uint32_t, nullptr_t, ResTable_entry_handle> data_;
+ std::variant<std::monostate, uint32_t, Res_value> data_;
};
// Looks up the value that overlays the target resource id.
@@ -123,11 +123,13 @@ class IdmapResMap {
private:
explicit IdmapResMap(const Idmap_data_header* data_header,
const Idmap_target_entry* entries,
+ const Idmap_target_entry_inline* inline_entries,
uint8_t target_assigned_package_id,
const OverlayDynamicRefTable* overlay_ref_table);
const Idmap_data_header* data_header_;
const Idmap_target_entry* entries_;
+ const Idmap_target_entry_inline* inline_entries_;
const uint8_t target_assigned_package_id_;
const OverlayDynamicRefTable* overlay_ref_table_;
@@ -163,8 +165,8 @@ class LoadedIdmap {
// Returns a mapping from target resource ids to overlay values.
inline const IdmapResMap GetTargetResourcesMap(
uint8_t target_assigned_package_id, const OverlayDynamicRefTable* overlay_ref_table) const {
- return IdmapResMap(data_header_, target_entries_, target_assigned_package_id,
- overlay_ref_table);
+ return IdmapResMap(data_header_, target_entries_, target_inline_entries_,
+ target_assigned_package_id, overlay_ref_table);
}
// Returns a dynamic reference table for a loaded overlay package.
@@ -184,6 +186,7 @@ class LoadedIdmap {
const Idmap_header* header_;
const Idmap_data_header* data_header_;
const Idmap_target_entry* target_entries_;
+ const Idmap_target_entry_inline* target_inline_entries_;
const Idmap_overlay_entry* overlay_entries_;
const std::unique_ptr<ResStringPool> string_pool_;
@@ -200,6 +203,7 @@ class LoadedIdmap {
const Idmap_header* header,
const Idmap_data_header* data_header,
const Idmap_target_entry* target_entries,
+ const Idmap_target_entry_inline* target_inline_entries,
const Idmap_overlay_entry* overlay_entries,
ResStringPool* string_pool);
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index e10a7f3f5c61..04ba78b6705d 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -41,7 +41,7 @@
namespace android {
constexpr const static uint32_t kIdmapMagic = 0x504D4449u;
-constexpr const static uint32_t kIdmapCurrentVersion = 0x00000004u;
+constexpr const static uint32_t kIdmapCurrentVersion = 0x00000005u;
/**
* In C++11, char16_t is defined as *at least* 16 bits. We do a lot of
@@ -1476,7 +1476,7 @@ struct ResTable_entry
// If set, this is a weak resource and may be overriden by strong
// resources of the same name/type. This is only useful during
// linking with other resource tables.
- FLAG_WEAK = 0x0004
+ FLAG_WEAK = 0x0004,
};
uint16_t flags;
@@ -1586,50 +1586,6 @@ struct ResTable_map
Res_value value;
};
-
-// A ResTable_entry variant that either holds an unmanaged pointer to a constant ResTable_entry or
-// holds a ResTable_entry which is tied to the lifetime of the handle.
-class ResTable_entry_handle {
- public:
- ResTable_entry_handle() = default;
-
- ResTable_entry_handle(const ResTable_entry_handle& handle) {
- entry_ = handle.entry_;
- }
-
- ResTable_entry_handle(ResTable_entry_handle&& handle) noexcept {
- entry_ = handle.entry_;
- }
-
- inline static ResTable_entry_handle managed(ResTable_entry* entry, void (*deleter)(void *)) {
- return ResTable_entry_handle(std::shared_ptr<const ResTable_entry>(entry, deleter));
- }
-
- inline static ResTable_entry_handle unmanaged(const ResTable_entry* entry) {
- return ResTable_entry_handle(std::shared_ptr<const ResTable_entry>(entry, [](auto /*p */){}));
- }
-
- inline ResTable_entry_handle& operator=(const ResTable_entry_handle& handle) noexcept {
- entry_ = handle.entry_;
- return *this;
- }
-
- inline ResTable_entry_handle& operator=(ResTable_entry_handle&& handle) noexcept {
- entry_ = handle.entry_;
- return *this;
- }
-
- inline const ResTable_entry* operator*() & {
- return entry_.get();
- }
-
- private:
- explicit ResTable_entry_handle(std::shared_ptr<const ResTable_entry> entry)
- : entry_(std::move(entry)) { }
-
- std::shared_ptr<const ResTable_entry> entry_;
-};
-
/**
* A package-id to package name mapping for any shared libraries used
* in this resource table. The package-id's encoded in this resource
@@ -1740,7 +1696,6 @@ inline ResTable_overlayable_policy_header::PolicyFlags& operator |=(
return first;
}
-#pragma pack(push, 1)
struct Idmap_header {
// Always 0x504D4449 ('IDMP')
uint32_t magic;
@@ -1751,7 +1706,7 @@ struct Idmap_header {
uint32_t overlay_crc32;
uint32_t fulfilled_policies;
- uint8_t enforce_overlayable;
+ uint32_t enforce_overlayable;
uint8_t target_path[256];
uint8_t overlay_path[256];
@@ -1765,23 +1720,31 @@ struct Idmap_header {
struct Idmap_data_header {
uint8_t target_package_id;
uint8_t overlay_package_id;
+
+ // Padding to ensure 4 byte alignment for target_entry_count
+ uint16_t p0;
+
uint32_t target_entry_count;
+ uint32_t target_inline_entry_count;
uint32_t overlay_entry_count;
+
uint32_t string_pool_index_offset;
- uint32_t string_pool_length;
};
struct Idmap_target_entry {
uint32_t target_id;
- uint8_t type;
- uint32_t value;
+ uint32_t overlay_id;
+};
+
+struct Idmap_target_entry_inline {
+ uint32_t target_id;
+ Res_value value;
};
struct Idmap_overlay_entry {
uint32_t overlay_id;
uint32_t target_id;
};
-#pragma pack(pop)
class AssetManager2;
diff --git a/libs/androidfw/tests/data/overlay/overlay.apk b/libs/androidfw/tests/data/overlay/overlay.apk
index f1ed59279fdb..c9bf2527c82a 100644
--- a/libs/androidfw/tests/data/overlay/overlay.apk
+++ b/libs/androidfw/tests/data/overlay/overlay.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/overlay/overlay.idmap b/libs/androidfw/tests/data/overlay/overlay.idmap
index 29c5eb6a9ccf..3ab244eb084a 100644
--- a/libs/androidfw/tests/data/overlay/overlay.idmap
+++ b/libs/androidfw/tests/data/overlay/overlay.idmap
Binary files differ