diff options
author | Ryan Mitchell <rtmitchell@google.com> | 2021-01-10 18:01:49 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-01-10 18:01:49 +0000 |
commit | 3d91609e47d43f8796b1f4989cdfe5081ba23e4b (patch) | |
tree | b72d7954a37d61e244aba7c43600e9e2c8bd2579 | |
parent | d5d79830ad7506b36bfc2cbf823b3bb05d415653 (diff) | |
parent | fb4d09cadd27a3fb1a2e268417f0f511aa92e344 (diff) |
Merge changes I09965e58,I02316d0b,Ic240cdb8
* changes:
Read manifest values using resource id in idmap2
Accept --overlay-name flag in idmap2
Remove idmap path 256 length limit
64 files changed, 906 insertions, 1134 deletions
diff --git a/cmds/idmap2/idmap2/CommandUtils.cpp b/cmds/idmap2/idmap2/CommandUtils.cpp index 8f5845bf2e53..09867f3a9c20 100644 --- a/cmds/idmap2/idmap2/CommandUtils.cpp +++ b/cmds/idmap2/idmap2/CommandUtils.cpp @@ -29,8 +29,8 @@ using android::idmap2::Result; using android::idmap2::Unit; Result<Unit> Verify(const std::string& idmap_path, const std::string& target_path, - const std::string& overlay_path, PolicyBitmask fulfilled_policies, - bool enforce_overlayable) { + const std::string& overlay_path, const std::string& overlay_name, + PolicyBitmask fulfilled_policies, bool enforce_overlayable) { SYSTRACE << "Verify " << idmap_path; std::ifstream fin(idmap_path); const std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(fin); @@ -39,7 +39,7 @@ Result<Unit> Verify(const std::string& idmap_path, const std::string& target_pat return Error("failed to parse idmap header"); } - const auto header_ok = header->IsUpToDate(target_path.c_str(), overlay_path.c_str(), + const auto header_ok = header->IsUpToDate(target_path, overlay_path, overlay_name, fulfilled_policies, enforce_overlayable); if (!header_ok) { return Error(header_ok.GetError(), "idmap not up to date"); diff --git a/cmds/idmap2/idmap2/CommandUtils.h b/cmds/idmap2/idmap2/CommandUtils.h index e717e046d15d..e06896784d6a 100644 --- a/cmds/idmap2/idmap2/CommandUtils.h +++ b/cmds/idmap2/idmap2/CommandUtils.h @@ -20,10 +20,8 @@ #include "idmap2/PolicyUtils.h" #include "idmap2/Result.h" -android::idmap2::Result<android::idmap2::Unit> Verify(const std::string& idmap_path, - const std::string& target_path, - const std::string& overlay_path, - PolicyBitmask fulfilled_policies, - bool enforce_overlayable); +android::idmap2::Result<android::idmap2::Unit> Verify( + const std::string& idmap_path, const std::string& target_path, const std::string& overlay_path, + const std::string& overlay_name, PolicyBitmask fulfilled_policies, bool enforce_overlayable); #endif // IDMAP2_IDMAP2_COMMAND_UTILS_H_ diff --git a/cmds/idmap2/idmap2/Create.cpp b/cmds/idmap2/idmap2/Create.cpp index 648b78e24c23..c93c717a15d2 100644 --- a/cmds/idmap2/idmap2/Create.cpp +++ b/cmds/idmap2/idmap2/Create.cpp @@ -50,6 +50,7 @@ Result<Unit> Create(const std::vector<std::string>& args) { std::string target_apk_path; std::string overlay_apk_path; std::string idmap_path; + std::string overlay_name; std::vector<std::string> policies; bool ignore_overlayable = false; @@ -62,9 +63,11 @@ Result<Unit> Create(const std::vector<std::string>& args) { "input: path to apk which contains the new resource values", &overlay_apk_path) .MandatoryOption("--idmap-path", "output: path to where to write idmap file", &idmap_path) + .OptionalOption("--overlay-name", "input: the value of android:name of the overlay", + &overlay_name) .OptionalOption("--policy", "input: an overlayable policy this overlay fulfills " - "(if none or supplied, the overlay policy will default to \"public\")", + "(if none are supplied, the overlay policy will default to \"public\")", &policies) .OptionalFlag("--ignore-overlayable", "disables overlayable and policy checks", &ignore_overlayable); @@ -100,8 +103,8 @@ Result<Unit> Create(const std::vector<std::string>& args) { return Error("failed to load apk %s", overlay_apk_path.c_str()); } - const auto idmap = - Idmap::FromApkAssets(*target_apk, *overlay_apk, fulfilled_policies, !ignore_overlayable); + const auto idmap = Idmap::FromApkAssets(*target_apk, *overlay_apk, overlay_name, + fulfilled_policies, !ignore_overlayable); if (!idmap) { return Error(idmap.GetError(), "failed to create idmap"); } diff --git a/cmds/idmap2/idmap2/CreateMultiple.cpp b/cmds/idmap2/idmap2/CreateMultiple.cpp index 19622c4ef65a..5db391caac30 100644 --- a/cmds/idmap2/idmap2/CreateMultiple.cpp +++ b/cmds/idmap2/idmap2/CreateMultiple.cpp @@ -105,7 +105,8 @@ Result<Unit> CreateMultiple(const std::vector<std::string>& args) { continue; } - if (!Verify(idmap_path, target_apk_path, overlay_apk_path, fulfilled_policies, + // TODO(b/175014391): Support multiple overlay tags in OverlayConfig + if (!Verify(idmap_path, target_apk_path, overlay_apk_path, "", fulfilled_policies, !ignore_overlayable)) { const std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); if (!overlay_apk) { @@ -113,8 +114,8 @@ Result<Unit> CreateMultiple(const std::vector<std::string>& args) { continue; } - const auto idmap = - Idmap::FromApkAssets(*target_apk, *overlay_apk, fulfilled_policies, !ignore_overlayable); + const auto idmap = Idmap::FromApkAssets(*target_apk, *overlay_apk, "", fulfilled_policies, + !ignore_overlayable); if (!idmap) { LOG(WARNING) << "failed to create idmap"; continue; diff --git a/cmds/idmap2/idmap2/Lookup.cpp b/cmds/idmap2/idmap2/Lookup.cpp index 437180d3d1be..43a1951a5ba9 100644 --- a/cmds/idmap2/idmap2/Lookup.cpp +++ b/cmds/idmap2/idmap2/Lookup.cpp @@ -188,29 +188,27 @@ Result<Unit> Lookup(const std::vector<std::string>& args) { } if (i == 0) { - target_path = idmap_header->GetTargetPath().to_string(); + target_path = idmap_header->GetTargetPath(); auto target_apk = ApkAssets::Load(target_path); if (!target_apk) { return Error("failed to read target apk from %s", target_path.c_str()); } apk_assets.push_back(std::move(target_apk)); - auto manifest_info = ExtractOverlayManifestInfo(idmap_header->GetOverlayPath().to_string(), - true /* assert_overlay */); + auto manifest_info = ExtractOverlayManifestInfo(idmap_header->GetOverlayPath(), + idmap_header->GetOverlayName()); if (!manifest_info) { return manifest_info.GetError(); } - target_package_name = (*manifest_info).target_package; + target_package_name = manifest_info->target_package; } else if (target_path != idmap_header->GetTargetPath()) { return Error("different target APKs (expected target APK %s but %s has target APK %s)", - target_path.c_str(), idmap_path.c_str(), - idmap_header->GetTargetPath().to_string().c_str()); + target_path.c_str(), idmap_path.c_str(), idmap_header->GetTargetPath().c_str()); } auto overlay_apk = ApkAssets::LoadOverlay(idmap_path); if (!overlay_apk) { - return Error("failed to read overlay apk from %s", - idmap_header->GetOverlayPath().to_string().c_str()); + return Error("failed to read overlay apk from %s", idmap_header->GetOverlayPath().c_str()); } apk_assets.push_back(std::move(overlay_apk)); } diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index 15e22a3410cf..93537d32299b 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -155,8 +155,9 @@ Status Idmap2Service::verifyIdmap(const std::string& target_apk_path, return overlay_crc_status; } + // TODO(162841629): Support passing overlay name to idmap2d verify auto up_to_date = - header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), target_crc, overlay_crc, + header->IsUpToDate(target_apk_path, overlay_apk_path, "", target_crc, overlay_crc, ConvertAidlArgToPolicyBitmask(fulfilled_policies), enforce_overlayable); *_aidl_return = static_cast<bool>(up_to_date); @@ -190,8 +191,9 @@ Status Idmap2Service::createIdmap(const std::string& target_apk_path, return error("failed to load apk " + overlay_apk_path); } + // TODO(162841629): Support passing overlay name to idmap2d create const auto idmap = - Idmap::FromApkAssets(*target_apk, *overlay_apk, policy_bitmask, enforce_overlayable); + Idmap::FromApkAssets(*target_apk, *overlay_apk, "", policy_bitmask, enforce_overlayable); if (!idmap) { return error(idmap.GetErrorMessage()); } diff --git a/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h b/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h index bf31cbf8d4f7..5e189f2c1340 100644 --- a/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h +++ b/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h @@ -39,7 +39,6 @@ class BinaryStreamVisitor : public Visitor { void Write8(uint8_t value); void Write16(uint16_t value); void Write32(uint32_t value); - void WriteString256(const StringPiece& 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 a35fad9d686c..1b815c1197ca 100644 --- a/cmds/idmap2/include/idmap2/Idmap.h +++ b/cmds/idmap2/include/idmap2/Idmap.h @@ -19,7 +19,8 @@ * * idmap := header data* * header := magic version target_crc overlay_crc fulfilled_policies - * enforce_overlayable target_path overlay_path debug_info + * enforce_overlayable target_path overlay_path overlay_name + * 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 @@ -37,13 +38,13 @@ * overlay_entry_count := <uint32_t> * overlay_id := <uint32_t> * overlay_package_id := <uint8_t> - * overlay_path := string256 + * overlay_name := string + * overlay_path := string * 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> @@ -52,7 +53,7 @@ * target_inline_entry_count := <uint32_t> * target_id := <uint32_t> * target_package_id := <uint8_t> - * target_path := string256 + * target_path := string * value_type := <uint8_t> * value_data := <uint32_t> * version := <uint32_t> @@ -78,19 +79,12 @@ namespace android::idmap2 { class Idmap; class Visitor; -static constexpr const ResourceId kPadding = 0xffffffffu; -static constexpr const EntryId kNoEntry = 0xffffu; - // magic number: all idmap files start with this static constexpr const uint32_t kIdmapMagic = android::kIdmapMagic; // current version of the idmap binary format; must be incremented when the format is changed static constexpr const uint32_t kIdmapCurrentVersion = android::kIdmapCurrentVersion; -// strings in the idmap are encoded char arrays of length 'kIdmapStringLength' (including mandatory -// terminating null) -static constexpr const size_t kIdmapStringLength = 256; - // Retrieves a crc generated using all of the files within the zip that can affect idmap generation. Result<uint32_t> GetPackageCrc(const ZipFile& zip_info); @@ -122,32 +116,38 @@ class IdmapHeader { return enforce_overlayable_; } - inline StringPiece GetTargetPath() const { - return StringPiece(target_path_); + const std::string& GetTargetPath() const { + return target_path_; } - inline StringPiece GetOverlayPath() const { - return StringPiece(overlay_path_); + const std::string& GetOverlayPath() const { + return overlay_path_; } - inline const std::string& GetDebugInfo() const { + const std::string& GetOverlayName() const { + return overlay_name_; + } + + const std::string& GetDebugInfo() const { return debug_info_; } // Invariant: anytime the idmap data encoding is changed, the idmap version // field *must* be incremented. Because of this, we know that if the idmap // header is up-to-date the entire file is up-to-date. - Result<Unit> IsUpToDate(const char* target_path, const char* overlay_path, - PolicyBitmask fulfilled_policies, bool enforce_overlayable) const; - Result<Unit> IsUpToDate(const char* target_path, const char* overlay_path, uint32_t target_crc, + Result<Unit> IsUpToDate(const std::string& target_path, const std::string& overlay_path, + const std::string& overlay_name, PolicyBitmask fulfilled_policies, + bool enforce_overlayable) const; + + Result<Unit> IsUpToDate(const std::string& target_path, const std::string& overlay_path, + const std::string& overlay_name, uint32_t target_crc, uint32_t overlay_crc, PolicyBitmask fulfilled_policies, bool enforce_overlayable) const; void accept(Visitor* v) const; private: - IdmapHeader() { - } + IdmapHeader() = default; uint32_t magic_; uint32_t version_; @@ -155,8 +155,9 @@ class IdmapHeader { uint32_t overlay_crc_; uint32_t fulfilled_policies_; bool enforce_overlayable_; - char target_path_[kIdmapStringLength]; - char overlay_path_[kIdmapStringLength]; + std::string target_path_; + std::string overlay_path_; + std::string overlay_name_; std::string debug_info_; friend Idmap; @@ -251,8 +252,7 @@ class IdmapData { void accept(Visitor* v) const; private: - IdmapData() { - } + IdmapData() = default; std::unique_ptr<const Header> header_; std::vector<TargetEntry> target_entries_; @@ -277,22 +277,22 @@ class Idmap { // the target and overlay package names static Result<std::unique_ptr<const Idmap>> FromApkAssets(const ApkAssets& target_apk_assets, const ApkAssets& overlay_apk_assets, + const std::string& overlay_name, const PolicyBitmask& fulfilled_policies, bool enforce_overlayable); - inline const std::unique_ptr<const IdmapHeader>& GetHeader() const { + const std::unique_ptr<const IdmapHeader>& GetHeader() const { return header_; } - inline const std::vector<std::unique_ptr<const IdmapData>>& GetData() const { + const std::vector<std::unique_ptr<const IdmapData>>& GetData() const { return data_; } void accept(Visitor* v) const; private: - Idmap() { - } + Idmap() = default; std::unique_ptr<const IdmapHeader> header_; std::vector<std::unique_ptr<const IdmapData>> data_; @@ -302,8 +302,7 @@ class Idmap { class Visitor { public: - virtual ~Visitor() { - } + virtual ~Visitor() = default; virtual void visit(const Idmap& idmap) = 0; virtual void visit(const IdmapHeader& header) = 0; virtual void visit(const IdmapData& data) = 0; diff --git a/cmds/idmap2/include/idmap2/RawPrintVisitor.h b/cmds/idmap2/include/idmap2/RawPrintVisitor.h index 58edc99715fd..45835164ef8e 100644 --- a/cmds/idmap2/include/idmap2/RawPrintVisitor.h +++ b/cmds/idmap2/include/idmap2/RawPrintVisitor.h @@ -44,7 +44,9 @@ class RawPrintVisitor : public Visitor { void print(uint8_t value, const char* fmt, ...); 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(const std::string& value, bool print_value, const char* fmt, ...); + void align(); + void pad(size_t padding); std::ostream& stream_; std::vector<std::unique_ptr<const ApkAssets>> apk_assets_; diff --git a/cmds/idmap2/include/idmap2/ResourceUtils.h b/cmds/idmap2/include/idmap2/ResourceUtils.h index c643b0e8800c..cd14d3e7254c 100644 --- a/cmds/idmap2/include/idmap2/ResourceUtils.h +++ b/cmds/idmap2/include/idmap2/ResourceUtils.h @@ -44,17 +44,14 @@ bool IsReference(uint8_t data_type); StringPiece DataTypeToString(uint8_t data_type); struct OverlayManifestInfo { - std::string target_package; // NOLINT(misc-non-private-member-variables-in-classes) - std::string target_name; // NOLINT(misc-non-private-member-variables-in-classes) - std::string requiredSystemPropertyName; // NOLINT(misc-non-private-member-variables-in-classes) - std::string requiredSystemPropertyValue; // NOLINT(misc-non-private-member-variables-in-classes) - uint32_t resource_mapping; // NOLINT(misc-non-private-member-variables-in-classes) - bool is_static; // NOLINT(misc-non-private-member-variables-in-classes) - int priority = -1; // NOLINT(misc-non-private-member-variables-in-classes) + std::string name; // NOLINT(misc-non-private-member-variables-in-classes) + std::string target_package; // NOLINT(misc-non-private-member-variables-in-classes) + std::string target_name; // NOLINT(misc-non-private-member-variables-in-classes) + uint32_t resource_mapping; // NOLINT(misc-non-private-member-variables-in-classes) }; Result<OverlayManifestInfo> ExtractOverlayManifestInfo(const std::string& path, - bool assert_overlay = true); + const std::string& name); Result<std::string> ResToTypeEntryName(const AssetManager2& am, ResourceId resid); diff --git a/cmds/idmap2/include/idmap2/XmlParser.h b/cmds/idmap2/include/idmap2/XmlParser.h index 972a6d7e3427..1c74ab3bb691 100644 --- a/cmds/idmap2/include/idmap2/XmlParser.h +++ b/cmds/idmap2/include/idmap2/XmlParser.h @@ -22,6 +22,7 @@ #include <memory> #include <string> +#include "ResourceUtils.h" #include "Result.h" #include "android-base/macros.h" #include "androidfw/ResourceTypes.h" @@ -39,8 +40,11 @@ class XmlParser { Event event() const; std::string name() const; - Result<std::string> GetAttributeStringValue(const std::string& name) const; Result<Res_value> GetAttributeValue(const std::string& name) const; + Result<Res_value> GetAttributeValue(ResourceId attr, const std::string& label) const; + + Result<std::string> GetAttributeStringValue(const std::string& name) const; + Result<std::string> GetAttributeStringValue(ResourceId attr, const std::string& label) const; bool operator==(const Node& rhs) const; bool operator!=(const Node& rhs) const; diff --git a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp index 726f6c5c2c99..c16310792d12 100644 --- a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp +++ b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp @@ -38,13 +38,6 @@ void BinaryStreamVisitor::Write32(uint32_t value) { stream_.write(reinterpret_cast<char*>(&x), sizeof(uint32_t)); } -void BinaryStreamVisitor::WriteString256(const StringPiece& value) { - char buf[kIdmapStringLength]; - memset(buf, 0, sizeof(buf)); - memcpy(buf, value.data(), std::min(value.size(), sizeof(buf))); - stream_.write(buf, sizeof(buf)); -} - void BinaryStreamVisitor::WriteString(const StringPiece& value) { // pad with null to nearest word boundary; size_t padding_size = CalculatePadding(value.size()); @@ -64,8 +57,9 @@ void BinaryStreamVisitor::visit(const IdmapHeader& header) { Write32(header.GetOverlayCrc()); Write32(header.GetFulfilledPolicies()); Write32(static_cast<uint8_t>(header.GetEnforceOverlayable())); - WriteString256(header.GetTargetPath()); - WriteString256(header.GetOverlayPath()); + WriteString(header.GetTargetPath()); + WriteString(header.GetOverlayPath()); + WriteString(header.GetOverlayName()); WriteString(header.GetDebugInfo()); } diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp index 1129413584b2..5af84b0c6e4e 100644 --- a/cmds/idmap2/libidmap2/Idmap.cpp +++ b/cmds/idmap2/libidmap2/Idmap.cpp @@ -69,38 +69,26 @@ bool WARN_UNUSED Read32(std::istream& stream, uint32_t* out) { return false; } -// a string is encoded as a kIdmapStringLength char array; the array is always null-terminated -bool WARN_UNUSED ReadString256(std::istream& stream, char out[kIdmapStringLength]) { - char buf[kIdmapStringLength]; - memset(buf, 0, sizeof(buf)); - if (!stream.read(buf, sizeof(buf))) { - return false; - } - if (buf[sizeof(buf) - 1] != '\0') { - return false; - } - memcpy(out, buf, sizeof(buf)); - return true; -} - -Result<std::string> ReadString(std::istream& stream) { +bool WARN_UNUSED ReadString(std::istream& stream, std::string* out) { uint32_t size; if (!Read32(stream, &size)) { - return Error("failed to read string size"); + return false; } if (size == 0) { - return std::string(""); + *out = ""; + return true; } std::string buf(size, '\0'); if (!stream.read(buf.data(), size)) { - return Error("failed to read string of size %u", size); + return false; } 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 false; } - return buf; + *out = buf; + return true; } } // namespace @@ -119,28 +107,25 @@ std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& s 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_) || - !Read32(stream, &enforce_overlayable) || !ReadString256(stream, idmap_header->target_path_) || - !ReadString256(stream, idmap_header->overlay_path_)) { + !Read32(stream, &enforce_overlayable) || !ReadString(stream, &idmap_header->target_path_) || + !ReadString(stream, &idmap_header->overlay_path_) || + !ReadString(stream, &idmap_header->overlay_name_) || + !ReadString(stream, &idmap_header->debug_info_)) { return nullptr; } idmap_header->enforce_overlayable_ = enforce_overlayable != 0U; - - auto debug_str = ReadString(stream); - if (!debug_str) { - return nullptr; - } - idmap_header->debug_info_ = std::move(*debug_str); - return std::move(idmap_header); } -Result<Unit> IdmapHeader::IsUpToDate(const char* target_path, const char* overlay_path, +Result<Unit> IdmapHeader::IsUpToDate(const std::string& target_path, + const std::string& overlay_path, + const std::string& overlay_name, PolicyBitmask fulfilled_policies, bool enforce_overlayable) const { const std::unique_ptr<const ZipFile> target_zip = ZipFile::Open(target_path); if (!target_zip) { - return Error("failed to open target %s", target_path); + return Error("failed to open target %s", target_path.c_str()); } const Result<uint32_t> target_crc = GetPackageCrc(*target_zip); @@ -150,7 +135,7 @@ Result<Unit> IdmapHeader::IsUpToDate(const char* target_path, const char* overla const std::unique_ptr<const ZipFile> overlay_zip = ZipFile::Open(overlay_path); if (!overlay_zip) { - return Error("failed to overlay target %s", overlay_path); + return Error("failed to overlay target %s", overlay_path.c_str()); } const Result<uint32_t> overlay_crc = GetPackageCrc(*overlay_zip); @@ -158,13 +143,14 @@ Result<Unit> IdmapHeader::IsUpToDate(const char* target_path, const char* overla return Error("failed to get overlay crc"); } - return IsUpToDate(target_path, overlay_path, *target_crc, *overlay_crc, fulfilled_policies, - enforce_overlayable); + return IsUpToDate(target_path, overlay_path, overlay_name, *target_crc, *overlay_crc, + fulfilled_policies, enforce_overlayable); } -Result<Unit> IdmapHeader::IsUpToDate(const char* target_path, const char* overlay_path, - uint32_t target_crc, uint32_t overlay_crc, - PolicyBitmask fulfilled_policies, +Result<Unit> IdmapHeader::IsUpToDate(const std::string& target_path, + const std::string& overlay_path, + const std::string& overlay_name, uint32_t target_crc, + uint32_t overlay_crc, PolicyBitmask fulfilled_policies, bool enforce_overlayable) const { if (magic_ != kIdmapMagic) { return Error("bad magic: actual 0x%08x, expected 0x%08x", magic_, kIdmapMagic); @@ -194,14 +180,19 @@ Result<Unit> IdmapHeader::IsUpToDate(const char* target_path, const char* overla enforce_overlayable ? "true" : "false", enforce_overlayable_ ? "true" : "false"); } - if (strcmp(target_path, target_path_) != 0) { - return Error("bad target path: idmap version %s, file system version %s", target_path, - target_path_); + if (target_path != target_path_) { + return Error("bad target path: idmap version %s, file system version %s", target_path.c_str(), + target_path_.c_str()); + } + + if (overlay_path != overlay_path_) { + return Error("bad overlay path: idmap version %s, file system version %s", overlay_path.c_str(), + overlay_path_.c_str()); } - if (strcmp(overlay_path, overlay_path_) != 0) { - return Error("bad overlay path: idmap version %s, file system version %s", overlay_path, - overlay_path_); + if (overlay_name != overlay_name_) { + return Error("bad overlay name: idmap version %s, file system version %s", overlay_name.c_str(), + overlay_name_.c_str()); } return Unit{}; @@ -262,12 +253,9 @@ std::unique_ptr<const IdmapData> IdmapData::FromBinaryStream(std::istream& strea } // Read raw string pool bytes. - auto string_pool_data = ReadString(stream); - if (!string_pool_data) { + if (!ReadString(stream, &data->string_pool_data_)) { return nullptr; } - data->string_pool_data_ = std::move(*string_pool_data); - return std::move(data); } @@ -337,6 +325,7 @@ Result<std::unique_ptr<const IdmapData>> IdmapData::FromResourceMapping( Result<std::unique_ptr<const Idmap>> Idmap::FromApkAssets(const ApkAssets& target_apk_assets, const ApkAssets& overlay_apk_assets, + const std::string& overlay_name, const PolicyBitmask& fulfilled_policies, bool enforce_overlayable) { SYSTRACE << "Idmap::FromApkAssets"; @@ -368,32 +357,20 @@ Result<std::unique_ptr<const Idmap>> Idmap::FromApkAssets(const ApkAssets& targe return Error(crc.GetError(), "failed to get zip CRC for overlay"); } header->overlay_crc_ = *crc; - header->fulfilled_policies_ = fulfilled_policies; header->enforce_overlayable_ = enforce_overlayable; + header->target_path_ = target_apk_path; + header->overlay_path_ = overlay_apk_path; + header->overlay_name_ = overlay_name; - if (target_apk_path.size() > sizeof(header->target_path_)) { - return Error("target apk path \"%s\" longer than maximum size %zu", target_apk_path.c_str(), - sizeof(header->target_path_)); - } - memset(header->target_path_, 0, sizeof(header->target_path_)); - memcpy(header->target_path_, target_apk_path.data(), target_apk_path.size()); - - if (overlay_apk_path.size() > sizeof(header->overlay_path_)) { - return Error("overlay apk path \"%s\" longer than maximum size %zu", overlay_apk_path.c_str(), - sizeof(header->target_path_)); - } - memset(header->overlay_path_, 0, sizeof(header->overlay_path_)); - memcpy(header->overlay_path_, overlay_apk_path.data(), overlay_apk_path.size()); - - auto overlay_info = utils::ExtractOverlayManifestInfo(overlay_apk_path); - if (!overlay_info) { - return overlay_info.GetError(); + auto info = utils::ExtractOverlayManifestInfo(overlay_apk_path, overlay_name); + if (!info) { + return info.GetError(); } LogInfo log_info; auto resource_mapping = - ResourceMapping::FromApkAssets(target_apk_assets, overlay_apk_assets, *overlay_info, + ResourceMapping::FromApkAssets(target_apk_assets, overlay_apk_assets, *info, fulfilled_policies, enforce_overlayable, log_info); if (!resource_mapping) { return resource_mapping.GetError(); diff --git a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp index 3037a791328e..7e090a983f95 100644 --- a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp +++ b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp @@ -39,6 +39,10 @@ void PrettyPrintVisitor::visit(const IdmapHeader& header) { << TAB "target apk path : " << header.GetTargetPath() << std::endl << TAB "overlay apk path : " << header.GetOverlayPath() << std::endl; + if (!header.GetOverlayName().empty()) { + stream_ << "Overlay name: " << header.GetOverlayName() << std::endl; + } + const std::string& debug = header.GetDebugInfo(); if (!debug.empty()) { std::istringstream debug_stream(debug); @@ -49,12 +53,12 @@ void PrettyPrintVisitor::visit(const IdmapHeader& header) { } } - if (auto target_apk_ = ApkAssets::Load(header.GetTargetPath().to_string())) { + if (auto target_apk_ = ApkAssets::Load(header.GetTargetPath())) { target_am_.SetApkAssets({target_apk_.get()}); apk_assets_.push_back(std::move(target_apk_)); } - if (auto overlay_apk = ApkAssets::Load(header.GetOverlayPath().to_string())) { + if (auto overlay_apk = ApkAssets::Load(header.GetOverlayPath())) { overlay_am_.SetApkAssets({overlay_apk.get()}); apk_assets_.push_back(std::move(overlay_apk)); } diff --git a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp index 82f5d26cbbb3..b517aa3a0c01 100644 --- a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp +++ b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp @@ -43,20 +43,18 @@ void RawPrintVisitor::visit(const IdmapHeader& header) { print(header.GetFulfilledPolicies(), "fulfilled policies: %s", PoliciesToDebugString(header.GetFulfilledPolicies()).c_str()); 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(header.GetTargetPath(), true /* print_value */, "target path"); + print(header.GetOverlayPath(), true /* print_value */, "overlay path"); + print(header.GetOverlayName(), true /* print_value */, "overlay name"); + print(header.GetDebugInfo(), false /* print_value */, "debug info"); - 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()); + auto target_apk_ = ApkAssets::Load(header.GetTargetPath()); if (target_apk_) { target_am_.SetApkAssets({target_apk_.get()}); apk_assets_.push_back(std::move(target_apk_)); } - auto overlay_apk_ = ApkAssets::Load(header.GetOverlayPath().to_string()); + auto overlay_apk_ = ApkAssets::Load(header.GetOverlayPath()); if (overlay_apk_) { overlay_am_.SetApkAssets({overlay_apk_.get()}); apk_assets_.push_back(std::move(overlay_apk_)); @@ -100,7 +98,7 @@ void RawPrintVisitor::visit(const IdmapData& data ATTRIBUTE_UNUSED) { print(target_entry.target_id, "target id"); } - print("...", sizeof(Res_value::size) + sizeof(Res_value::res0), "padding"); + pad(sizeof(Res_value::size) + sizeof(Res_value::res0)); print(target_entry.value.data_type, "type: %s", utils::DataTypeToString(target_entry.value.data_type).data()); @@ -143,15 +141,13 @@ void RawPrintVisitor::visit(const IdmapData& data ATTRIBUTE_UNUSED) { } } - 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"); + print(data.GetStringPoolData(), false /* print_value */, "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"); + align(); print(header.GetTargetEntryCount(), "target entry count"); print(header.GetTargetInlineEntryCount(), "target inline entry count"); print(header.GetOverlayEntryCount(), "overlay entry count"); @@ -168,7 +164,6 @@ void RawPrintVisitor::print(uint8_t value, const char* fmt, ...) { stream_ << base::StringPrintf("%08zx: %02x", offset_, value) << " " << comment << std::endl; - offset_ += sizeof(uint8_t); } @@ -181,7 +176,6 @@ void RawPrintVisitor::print(uint16_t value, const char* fmt, ...) { va_end(ap); stream_ << base::StringPrintf("%08zx: %04x", offset_, value) << " " << comment << std::endl; - offset_ += sizeof(uint16_t); } @@ -194,22 +188,35 @@ void RawPrintVisitor::print(uint32_t value, const char* fmt, ...) { va_end(ap); stream_ << base::StringPrintf("%08zx: %08x", offset_, value) << " " << comment << std::endl; - offset_ += sizeof(uint32_t); } // NOLINTNEXTLINE(cert-dcl50-cpp) -void RawPrintVisitor::print(const std::string& value, size_t encoded_size, const char* fmt, ...) { +void RawPrintVisitor::print(const std::string& value, bool print_value, 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 << ": " << value - << std::endl; + stream_ << base::StringPrintf("%08zx: %08x", offset_, (uint32_t)value.size()) << " " << comment + << " size" << std::endl; + offset_ += sizeof(uint32_t); - offset_ += encoded_size; + stream_ << base::StringPrintf("%08zx: ", offset_) << "........ " << comment; + offset_ += value.size() + CalculatePadding(value.size()); + + if (print_value) { + stream_ << ": " << value; + } + stream_ << std::endl; } +void RawPrintVisitor::align() { + offset_ += CalculatePadding(offset_); +} + +void RawPrintVisitor::pad(size_t padding) { + offset_ += padding; +} } // namespace android::idmap2 diff --git a/cmds/idmap2/libidmap2/ResourceMapping.cpp b/cmds/idmap2/libidmap2/ResourceMapping.cpp index d777cbfa9a14..9abb9e458902 100644 --- a/cmds/idmap2/libidmap2/ResourceMapping.cpp +++ b/cmds/idmap2/libidmap2/ResourceMapping.cpp @@ -230,8 +230,8 @@ Result<ResourceMapping> ResourceMapping::CreateResourceMappingLegacy( base::StringPrintf("%s:%s", target_package->GetPackageName().c_str(), name->c_str()); auto target_resource_result = target_am->GetResourceId(full_name); if (!target_resource_result.has_value()) { - log_info.Warning(LogMessage() << "failed to find resource \"" << full_name - << "\" in target resources"); + log_info.Warning(LogMessage() + << "failed to find resource \"" << full_name << "\" in target resources"); continue; } diff --git a/cmds/idmap2/libidmap2/ResourceUtils.cpp b/cmds/idmap2/libidmap2/ResourceUtils.cpp index e817140238ae..4e85e5751300 100644 --- a/cmds/idmap2/libidmap2/ResourceUtils.cpp +++ b/cmds/idmap2/libidmap2/ResourceUtils.cpp @@ -32,6 +32,12 @@ using android::idmap2::ZipFile; using android::util::Utf16ToUtf8; namespace android::idmap2::utils { +namespace { +constexpr ResourceId kAttrName = 0x01010003; +constexpr ResourceId kAttrResourcesMap = 0x01010609; +constexpr ResourceId kAttrTargetName = 0x0101044d; +constexpr ResourceId kAttrTargetPackage = 0x01010021; +} // namespace bool IsReference(uint8_t data_type) { return data_type == Res_value::TYPE_REFERENCE || data_type == Res_value::TYPE_DYNAMIC_REFERENCE; @@ -92,7 +98,7 @@ Result<std::string> ResToTypeEntryName(const AssetManager2& am, uint32_t resid) } Result<OverlayManifestInfo> ExtractOverlayManifestInfo(const std::string& path, - bool assert_overlay) { + const std::string& name) { std::unique_ptr<const ZipFile> zip = ZipFile::Open(path); if (!zip) { return Error("failed to open %s as a zip file", path.c_str()); @@ -113,65 +119,49 @@ Result<OverlayManifestInfo> ExtractOverlayManifestInfo(const std::string& path, return Error("root element tag is not <manifest> in AndroidManifest.xml of %s", path.c_str()); } - auto overlay_it = std::find_if(manifest_it.begin(), manifest_it.end(), [](const auto& it) { - return it.event() == XmlParser::Event::START_TAG && it.name() == "overlay"; - }); - - OverlayManifestInfo info{}; - if (overlay_it == manifest_it.end()) { - if (!assert_overlay) { - return info; + for (auto&& it : manifest_it) { + if (it.event() != XmlParser::Event::START_TAG || it.name() != "overlay") { + continue; } - return Error("<overlay> missing from AndroidManifest.xml of %s", path.c_str()); - } - - if (auto result_str = overlay_it->GetAttributeStringValue("targetPackage")) { - info.target_package = *result_str; - } else { - return Error("android:targetPackage missing from <overlay> of %s: %s", path.c_str(), - result_str.GetErrorMessage().c_str()); - } - - if (auto result_str = overlay_it->GetAttributeStringValue("targetName")) { - info.target_name = *result_str; - } - if (auto result_value = overlay_it->GetAttributeValue("resourcesMap")) { - if (IsReference((*result_value).dataType)) { - info.resource_mapping = (*result_value).data; - } else { - return Error("android:resourcesMap is not a reference in AndroidManifest.xml of %s", - path.c_str()); + OverlayManifestInfo info{}; + if (auto result_str = it.GetAttributeStringValue(kAttrName, "android:name")) { + if (*result_str != name) { + // A value for android:name was found, but either a the name does not match the requested + // name, or an <overlay> tag with no name was requested. + continue; + } + info.name = *result_str; + } else if (!name.empty()) { + // This tag does not have a value for android:name, but an <overlay> tag with a specific name + // has been requested. + continue; } - } - if (auto result_value = overlay_it->GetAttributeValue("isStatic")) { - if ((*result_value).dataType >= Res_value::TYPE_FIRST_INT && - (*result_value).dataType <= Res_value::TYPE_LAST_INT) { - info.is_static = (*result_value).data != 0U; + if (auto result_str = it.GetAttributeStringValue(kAttrTargetPackage, "android:targetPackage")) { + info.target_package = *result_str; } else { - return Error("android:isStatic is not a boolean in AndroidManifest.xml of %s", path.c_str()); + return Error("android:targetPackage missing from <overlay> of %s: %s", path.c_str(), + result_str.GetErrorMessage().c_str()); } - } - if (auto result_value = overlay_it->GetAttributeValue("priority")) { - if ((*result_value).dataType >= Res_value::TYPE_FIRST_INT && - (*result_value).dataType <= Res_value::TYPE_LAST_INT) { - info.priority = (*result_value).data; - } else { - return Error("android:priority is not an integer in AndroidManifest.xml of %s", path.c_str()); + if (auto result_str = it.GetAttributeStringValue(kAttrTargetName, "android:targetName")) { + info.target_name = *result_str; } - } - if (auto result_str = overlay_it->GetAttributeStringValue("requiredSystemPropertyName")) { - info.requiredSystemPropertyName = *result_str; - } - - if (auto result_str = overlay_it->GetAttributeStringValue("requiredSystemPropertyValue")) { - info.requiredSystemPropertyValue = *result_str; + if (auto result_value = it.GetAttributeValue(kAttrResourcesMap, "android:resourcesMap")) { + if (IsReference((*result_value).dataType)) { + info.resource_mapping = (*result_value).data; + } else { + return Error("android:resourcesMap is not a reference in AndroidManifest.xml of %s", + path.c_str()); + } + } + return info; } - return info; + return Error("<overlay> with android:name \"%s\" missing from AndroidManifest.xml of %s", + name.c_str(), path.c_str()); } } // namespace android::idmap2::utils diff --git a/cmds/idmap2/libidmap2/XmlParser.cpp b/cmds/idmap2/libidmap2/XmlParser.cpp index 4030b83b3a41..00baea46f909 100644 --- a/cmds/idmap2/libidmap2/XmlParser.cpp +++ b/cmds/idmap2/libidmap2/XmlParser.cpp @@ -90,15 +90,27 @@ std::string XmlParser::Node::name() const { return String8(key16).c_str(); } -Result<std::string> XmlParser::Node::GetAttributeStringValue(const std::string& name) const { - auto value = GetAttributeValue(name); - if (!value) { - return value.GetError(); +template <typename Func> +Result<Res_value> FindAttribute(const ResXMLParser& parser, const std::string& label, + Func&& predicate) { + for (size_t i = 0; i < parser.getAttributeCount(); i++) { + if (!predicate(i)) { + continue; + } + Res_value res_value{}; + if (parser.getAttributeValue(i, &res_value) == BAD_TYPE) { + return Error(R"(Bad value for attribute "%s")", label.c_str()); + } + return res_value; } + return Error(R"(Failed to find attribute "%s")", label.c_str()); +} - switch ((*value).dataType) { +Result<std::string> GetStringValue(const ResXMLParser& parser, const Res_value& value, + const std::string& label) { + switch (value.dataType) { case Res_value::TYPE_STRING: { - if (auto str = parser_.getStrings().string8ObjectAt((*value).data); str.ok()) { + if (auto str = parser.getStrings().string8ObjectAt(value.data); str.ok()) { return std::string(str->string()); } break; @@ -106,31 +118,37 @@ Result<std::string> XmlParser::Node::GetAttributeStringValue(const std::string& case Res_value::TYPE_INT_DEC: case Res_value::TYPE_INT_HEX: case Res_value::TYPE_INT_BOOLEAN: { - return std::to_string((*value).data); + return std::to_string(value.data); } } + return Error(R"(Failed to convert attribute "%s" value to a string)", label.c_str()); +} - return Error(R"(Failed to convert attribute "%s" value to a string)", name.c_str()); +Result<Res_value> XmlParser::Node::GetAttributeValue(ResourceId attr, + const std::string& label) const { + return FindAttribute(parser_, label, [&](size_t index) -> bool { + return parser_.getAttributeNameResID(index) == attr; + }); } Result<Res_value> XmlParser::Node::GetAttributeValue(const std::string& name) const { - size_t len; - for (size_t i = 0; i < parser_.getAttributeCount(); i++) { - const String16 key16(parser_.getAttributeName(i, &len)); + return FindAttribute(parser_, name, [&](size_t index) -> bool { + size_t len; + const String16 key16(parser_.getAttributeName(index, &len)); std::string key = String8(key16).c_str(); - if (key != name) { - continue; - } - - Res_value res_value{}; - if (parser_.getAttributeValue(i, &res_value) == BAD_TYPE) { - return Error(R"(Bad value for attribute "%s")", name.c_str()); - } + return key == name; + }); +} - return res_value; - } +Result<std::string> XmlParser::Node::GetAttributeStringValue(ResourceId attr, + const std::string& label) const { + auto value = GetAttributeValue(attr, label); + return value ? GetStringValue(parser_, *value, label) : value.GetError(); +} - return Error(R"(Failed to find attribute "%s")", name.c_str()); +Result<std::string> XmlParser::Node::GetAttributeStringValue(const std::string& name) const { + auto value = GetAttributeValue(name); + return value ? GetStringValue(parser_, *value, name) : value.GetError(); } Result<std::unique_ptr<const XmlParser>> XmlParser::Create(const void* data, size_t size, diff --git a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp index c3a3e0ba9047..524aabcec652 100644 --- a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp +++ b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp @@ -33,7 +33,7 @@ using ::testing::NotNull; namespace android::idmap2 { TEST(BinaryStreamVisitorTests, CreateBinaryStreamViaBinaryStreamVisitor) { - std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len); + std::string raw(reinterpret_cast<const char*>(idmap_raw_data), kIdmapRawDataLen); std::istringstream raw_stream(raw); auto result1 = Idmap::FromBinaryStream(raw_stream); diff --git a/cmds/idmap2/tests/Idmap2BinaryTests.cpp b/cmds/idmap2/tests/Idmap2BinaryTests.cpp index e7e9e4cf5091..a55b41b83c93 100644 --- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp +++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp @@ -35,6 +35,7 @@ #include <vector> #include "R.h" +#include "TestConstants.h" #include "TestHelpers.h" #include "androidfw/PosixUtils.h" #include "gmock/gmock.h" @@ -43,6 +44,7 @@ #include "idmap2/Idmap.h" #include "private/android_filesystem_config.h" +using ::android::base::StringPrintf; using ::android::util::ExecuteBinary; using ::testing::NotNull; @@ -90,6 +92,7 @@ TEST_F(Idmap2BinaryTests, Create) { "create", "--target-apk-path", GetTargetApkPath(), "--overlay-apk-path", GetOverlayApkPath(), + "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT, "--idmap-path", GetIdmapPath()}); // clang-format on ASSERT_THAT(result, NotNull()); @@ -116,6 +119,7 @@ TEST_F(Idmap2BinaryTests, Dump) { "create", "--target-apk-path", GetTargetApkPath(), "--overlay-apk-path", GetOverlayApkPath(), + "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT, "--idmap-path", GetIdmapPath()}); // clang-format on ASSERT_THAT(result, NotNull()); @@ -128,14 +132,23 @@ 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"), - std::string::npos); - 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"), - std::string::npos); - ASSERT_NE(result->stdout.find(R::target::string::literal::str4 + " -> 0x7f020002"), - std::string::npos); + + ASSERT_NE(result->stdout.find(StringPrintf("0x%08x -> 0x%08x", R::target::integer::int1, + R::overlay::integer::int1)), + std::string::npos) + << result->stdout; + ASSERT_NE(result->stdout.find(StringPrintf("0x%08x -> 0x%08x", R::target::string::str1, + R::overlay::string::str1)), + std::string::npos) + << result->stdout; + ASSERT_NE(result->stdout.find(StringPrintf("0x%08x -> 0x%08x", R::target::string::str3, + R::overlay::string::str3)), + std::string::npos) + << result->stdout; + ASSERT_NE(result->stdout.find(StringPrintf("0x%08x -> 0x%08x", R::target::string::str4, + R::overlay::string::str4)), + std::string::npos) + << result->stdout; // clang-format off result = ExecuteBinary({"idmap2", @@ -167,6 +180,7 @@ TEST_F(Idmap2BinaryTests, Lookup) { "create", "--target-apk-path", GetTargetApkPath(), "--overlay-apk-path", GetOverlayApkPath(), + "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT, "--idmap-path", GetIdmapPath()}); // clang-format on ASSERT_THAT(result, NotNull()); @@ -177,7 +191,7 @@ TEST_F(Idmap2BinaryTests, Lookup) { "lookup", "--idmap-path", GetIdmapPath(), "--config", "", - "--resid", R::target::string::literal::str1}); + "--resid", StringPrintf("0x%08x", R::target::string::str1)}); // clang-format on ASSERT_THAT(result, NotNull()); ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr; @@ -229,6 +243,7 @@ TEST_F(Idmap2BinaryTests, InvalidCommandLineOptions) { "create", "--target-apk-path", GetTargetApkPath(), "--overlay-apk-path", GetOverlayApkPath(), + "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT, "--idmap-path"}); // clang-format on ASSERT_THAT(result, NotNull()); @@ -240,6 +255,7 @@ TEST_F(Idmap2BinaryTests, InvalidCommandLineOptions) { "create", "--target-apk-path", invalid_target_apk_path, "--overlay-apk-path", GetOverlayApkPath(), + "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT, "--idmap-path", GetIdmapPath()}); // clang-format on ASSERT_THAT(result, NotNull()); @@ -251,6 +267,7 @@ TEST_F(Idmap2BinaryTests, InvalidCommandLineOptions) { "create", "--target-apk-path", GetTargetApkPath(), "--overlay-apk-path", GetOverlayApkPath(), + "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT, "--idmap-path", GetIdmapPath(), "--policy", "this-does-not-exist"}); // clang-format on diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp index 9b42a2781b58..c13b049eadfe 100644 --- a/cmds/idmap2/tests/IdmapTests.cpp +++ b/cmds/idmap2/tests/IdmapTests.cpp @@ -27,6 +27,7 @@ #include "TestHelpers.h" #include "android-base/macros.h" #include "androidfw/ApkAssets.h" +#include "androidfw/ResourceUtils.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "idmap2/BinaryStreamVisitor.h" @@ -35,7 +36,6 @@ #include "idmap2/LogInfo.h" using android::Res_value; -using ::testing::IsNull; using ::testing::NotNull; using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; @@ -61,36 +61,25 @@ TEST(IdmapTests, TestCanonicalIdmapPathFor) { } TEST(IdmapTests, CreateIdmapHeaderFromBinaryStream) { - std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len); + std::string raw(reinterpret_cast<const char*>(idmap_raw_data), kIdmapRawDataLen); std::istringstream stream(raw); std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream); ASSERT_THAT(header, NotNull()); ASSERT_EQ(header->GetMagic(), 0x504d4449U); - ASSERT_EQ(header->GetVersion(), 0x05U); + ASSERT_EQ(header->GetVersion(), 0x07U); ASSERT_EQ(header->GetTargetCrc(), 0x1234U); ASSERT_EQ(header->GetOverlayCrc(), 0x5678U); ASSERT_EQ(header->GetFulfilledPolicies(), 0x11); ASSERT_EQ(header->GetEnforceOverlayable(), true); - ASSERT_EQ(header->GetTargetPath().to_string(), "targetX.apk"); - ASSERT_EQ(header->GetOverlayPath().to_string(), "overlayX.apk"); + ASSERT_EQ(header->GetTargetPath(), "targetX.apk"); + ASSERT_EQ(header->GetOverlayPath(), "overlayX.apk"); ASSERT_EQ(header->GetDebugInfo(), "debug"); } -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 = 0x18; i < 0x118; i++) { - raw[i] = '.'; - } - std::istringstream stream(raw); - std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream); - ASSERT_THAT(header, IsNull()); -} - TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) { - const size_t offset = 0x224; + const size_t offset = kIdmapRawDataOffset; std::string raw(reinterpret_cast<const char*>(idmap_raw_data + offset), - idmap_raw_data_len - offset); + kIdmapRawDataLen - offset); std::istringstream stream(raw); std::unique_ptr<const IdmapData::Header> header = IdmapData::Header::FromBinaryStream(stream); @@ -100,9 +89,9 @@ TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) { } TEST(IdmapTests, CreateIdmapDataFromBinaryStream) { - const size_t offset = 0x224; + const size_t offset = kIdmapRawDataOffset; std::string raw(reinterpret_cast<const char*>(idmap_raw_data + offset), - idmap_raw_data_len - offset); + kIdmapRawDataLen - offset); std::istringstream stream(raw); std::unique_ptr<const IdmapData> data = IdmapData::FromBinaryStream(stream); @@ -127,7 +116,7 @@ TEST(IdmapTests, CreateIdmapDataFromBinaryStream) { } TEST(IdmapTests, CreateIdmapFromBinaryStream) { - std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len); + std::string raw(reinterpret_cast<const char*>(idmap_raw_data), kIdmapRawDataLen); std::istringstream stream(raw); auto result = Idmap::FromBinaryStream(stream); @@ -136,13 +125,14 @@ TEST(IdmapTests, CreateIdmapFromBinaryStream) { ASSERT_THAT(idmap->GetHeader(), NotNull()); ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U); - ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x05U); + ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x07U); ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x1234U); ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x5678U); - ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), 0x11); + ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), kIdmapRawDataPolicies); ASSERT_EQ(idmap->GetHeader()->GetEnforceOverlayable(), true); - ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), "targetX.apk"); - ASSERT_EQ(idmap->GetHeader()->GetOverlayPath().to_string(), "overlayX.apk"); + ASSERT_EQ(idmap->GetHeader()->GetTargetPath(), kIdmapRawTargetPath); + ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), kIdmapRawOverlayPath); + ASSERT_EQ(idmap->GetHeader()->GetOverlayName(), kIdmapRawOverlayName); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); ASSERT_EQ(dataBlocks.size(), 1U); @@ -187,48 +177,23 @@ TEST(IdmapTests, CreateIdmapHeaderFromApkAssets) { std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - auto idmap_result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, - /* enforce_overlayable */ true); + auto idmap_result = Idmap::FromApkAssets( + *target_apk, *overlay_apk, TestConstants::OVERLAY_NAME_ALL_POLICIES, PolicyFlags::PUBLIC, + /* enforce_overlayable */ true); ASSERT_TRUE(idmap_result) << idmap_result.GetErrorMessage(); auto& idmap = *idmap_result; ASSERT_THAT(idmap, NotNull()); ASSERT_THAT(idmap->GetHeader(), NotNull()); ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U); - ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x05U); + ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x07U); 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); ASSERT_EQ(idmap->GetHeader()->GetEnforceOverlayable(), true); - ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), target_apk_path); + ASSERT_EQ(idmap->GetHeader()->GetTargetPath(), target_apk_path); ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path); -} - -Result<std::unique_ptr<const IdmapData>> TestIdmapDataFromApkAssets( - const android::StringPiece& local_target_apk_path, - const android::StringPiece& local_overlay_apk_path, const OverlayManifestInfo& overlay_info, - const PolicyBitmask& fulfilled_policies, bool enforce_overlayable) { - const std::string target_apk_path(GetTestDataPath() + local_target_apk_path.data()); - std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); - if (!target_apk) { - return Error(R"(Failed to load target apk "%s")", target_apk_path.data()); - } - - const std::string overlay_apk_path(GetTestDataPath() + local_overlay_apk_path.data()); - std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); - if (!overlay_apk) { - return Error(R"(Failed to load overlay apk "%s")", overlay_apk_path.data()); - } - - LogInfo log_info; - auto mapping = ResourceMapping::FromApkAssets(*target_apk, *overlay_apk, overlay_info, - fulfilled_policies, enforce_overlayable, log_info); - - if (!mapping) { - return mapping.GetError(); - } - - return IdmapData::FromResourceMapping(*mapping); + ASSERT_EQ(idmap->GetHeader()->GetOverlayName(), TestConstants::OVERLAY_NAME_ALL_POLICIES); } TEST(IdmapTests, CreateIdmapDataFromApkAssets) { @@ -241,7 +206,8 @@ TEST(IdmapTests, CreateIdmapDataFromApkAssets) { std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - auto idmap_result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, + auto idmap_result = Idmap::FromApkAssets(*target_apk, *overlay_apk, + TestConstants::OVERLAY_NAME_DEFAULT, PolicyFlags::PUBLIC, /* enforce_overlayable */ true); ASSERT_TRUE(idmap_result) << idmap_result.GetErrorMessage(); auto& idmap = *idmap_result; @@ -271,6 +237,29 @@ TEST(IdmapTests, CreateIdmapDataFromApkAssets) { ASSERT_OVERLAY_ENTRY(overlay_entries[3], R::overlay::string::str4, R::target::string::str4); } +TEST(IdmapTests, FailCreateIdmapInvalidName) { + std::string target_apk_path = GetTestDataPath() + "/target/target.apk"; + std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay.apk"; + + std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); + ASSERT_THAT(target_apk, NotNull()); + + std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); + ASSERT_THAT(overlay_apk, NotNull()); + + { + auto idmap_result = Idmap::FromApkAssets(*target_apk, *overlay_apk, "", PolicyFlags::PUBLIC, + /* enforce_overlayable */ true); + ASSERT_FALSE(idmap_result); + } + { + auto idmap_result = + Idmap::FromApkAssets(*target_apk, *overlay_apk, "unknown", PolicyFlags::PUBLIC, + /* enforce_overlayable */ true); + ASSERT_FALSE(idmap_result); + } +} + TEST(IdmapTests, CreateIdmapDataFromApkAssetsSharedLibOverlay) { std::string target_apk_path = GetTestDataPath() + "/target/target.apk"; std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay-shared.apk"; @@ -281,7 +270,8 @@ TEST(IdmapTests, CreateIdmapDataFromApkAssetsSharedLibOverlay) { std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - auto idmap_result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, + auto idmap_result = Idmap::FromApkAssets(*target_apk, *overlay_apk, + TestConstants::OVERLAY_NAME_DEFAULT, PolicyFlags::PUBLIC, /* enforce_overlayable */ true); ASSERT_TRUE(idmap_result) << idmap_result.GetErrorMessage(); auto& idmap = *idmap_result; @@ -296,34 +286,67 @@ 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, - 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); + fix_package_id(R::overlay::integer::int1, 0)); + ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str1, + fix_package_id(R::overlay::string::str1, 0)); + ASSERT_TARGET_ENTRY(target_entries[2], R::target::string::str3, + fix_package_id(R::overlay::string::str3, 0)); + ASSERT_TARGET_ENTRY(target_entries[3], R::target::string::str4, + fix_package_id(R::overlay::string::str4, 0)); 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); - ASSERT_OVERLAY_ENTRY(overlay_entries[0], R::overlay_shared::integer::int1, + ASSERT_OVERLAY_ENTRY(overlay_entries[0], fix_package_id(R::overlay::integer::int1, 0), R::target::integer::int1); - ASSERT_OVERLAY_ENTRY(overlay_entries[1], R::overlay_shared::string::str1, + ASSERT_OVERLAY_ENTRY(overlay_entries[1], fix_package_id(R::overlay::string::str1, 0), R::target::string::str1); - ASSERT_OVERLAY_ENTRY(overlay_entries[2], R::overlay_shared::string::str3, + ASSERT_OVERLAY_ENTRY(overlay_entries[2], fix_package_id(R::overlay::string::str3, 0), R::target::string::str3); - ASSERT_OVERLAY_ENTRY(overlay_entries[3], R::overlay_shared::string::str4, + ASSERT_OVERLAY_ENTRY(overlay_entries[3], fix_package_id(R::overlay::string::str4, 0), R::target::string::str4); } +Result<std::unique_ptr<const IdmapData>> TestIdmapDataFromApkAssets( + const std::string& local_target_apk_path, const std::string& local_overlay_apk_path, + const std::string& overlay_name, const PolicyBitmask& fulfilled_policies, + bool enforce_overlayable) { + auto overlay_info = + utils::ExtractOverlayManifestInfo(GetTestDataPath() + local_overlay_apk_path, overlay_name); + if (!overlay_info) { + return overlay_info.GetError(); + } + + const std::string target_apk_path(GetTestDataPath() + local_target_apk_path); + std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); + if (!target_apk) { + return Error(R"(Failed to load target apk "%s")", target_apk_path.data()); + } + + const std::string overlay_apk_path(GetTestDataPath() + local_overlay_apk_path); + std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); + if (!overlay_apk) { + return Error(R"(Failed to load overlay apk "%s")", overlay_apk_path.data()); + } + + LogInfo log_info; + auto mapping = ResourceMapping::FromApkAssets(*target_apk, *overlay_apk, *overlay_info, + fulfilled_policies, enforce_overlayable, log_info); + if (!mapping) { + return mapping.GetError(); + } + + return IdmapData::FromResourceMapping(*mapping); +} + TEST(IdmapTests, CreateIdmapDataDoNotRewriteNonOverlayResourceId) { - OverlayManifestInfo info{}; - info.target_package = "test.target"; - info.target_name = "TestResources"; - info.resource_mapping = 0x7f030001; // xml/overlays_different_packages - auto idmap_data = TestIdmapDataFromApkAssets("/target/target.apk", "/overlay/overlay.apk", info, - PolicyFlags::PUBLIC, - /* enforce_overlayable */ false); + auto idmap_data = + TestIdmapDataFromApkAssets("/target/target.apk", "/overlay/overlay.apk", "DifferentPackages", + + PolicyFlags::PUBLIC, + /* enforce_overlayable */ false); ASSERT_TRUE(idmap_data) << idmap_data.GetErrorMessage(); auto& data = *idmap_data; @@ -343,12 +366,8 @@ TEST(IdmapTests, CreateIdmapDataDoNotRewriteNonOverlayResourceId) { } TEST(IdmapTests, CreateIdmapDataInlineResources) { - OverlayManifestInfo info{}; - info.target_package = "test.target"; - info.target_name = "TestResources"; - info.resource_mapping = 0x7f030002; // xml/overlays_inline - auto idmap_data = TestIdmapDataFromApkAssets("/target/target.apk", "/overlay/overlay.apk", info, - PolicyFlags::PUBLIC, + auto idmap_data = TestIdmapDataFromApkAssets("/target/target.apk", "/overlay/overlay.apk", + "Inline", PolicyFlags::PUBLIC, /* enforce_overlayable */ false); ASSERT_TRUE(idmap_data) << idmap_data.GetErrorMessage(); @@ -357,7 +376,7 @@ TEST(IdmapTests, CreateIdmapDataInlineResources) { const auto& target_entries = data->GetTargetEntries(); ASSERT_EQ(target_entries.size(), 0U); - constexpr size_t overlay_string_pool_size = 8U; + constexpr size_t overlay_string_pool_size = 10U; 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, @@ -370,38 +389,20 @@ TEST(IdmapTests, CreateIdmapDataInlineResources) { ASSERT_EQ(overlay_entries.size(), 0U); } -TEST(IdmapTests, FailToCreateIdmapFromApkAssetsIfPathTooLong) { - std::string target_apk_path(GetTestDataPath()); - for (int i = 0; i < 32; i++) { - target_apk_path += "/target/../"; - } - target_apk_path += "/target/target.apk"; - ASSERT_GT(target_apk_path.size(), kIdmapStringLength); - std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); - ASSERT_THAT(target_apk, NotNull()); - - const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay.apk"); - std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); - ASSERT_THAT(overlay_apk, NotNull()); - - const auto result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, - /* enforce_overlayable */ true); - ASSERT_FALSE(result); -} - TEST(IdmapTests, IdmapHeaderIsUpToDate) { fclose(stderr); // silence expected warnings from libandroidfw - const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); - std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); - ASSERT_THAT(target_apk, NotNull()); + const std::string target_apk_path = kIdmapRawTargetPath; + const std::string overlay_apk_path = kIdmapRawOverlayPath; + const std::string overlay_name = kIdmapRawOverlayName; + const PolicyBitmask policies = kIdmapRawDataPolicies; + const uint32_t target_crc = kIdmapRawDataTargetCrc; + const uint32_t overlay_crc = kIdmapRawOverlayCrc; - const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay.apk"); - std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); - ASSERT_THAT(overlay_apk, NotNull()); + std::string raw(reinterpret_cast<const char*>(idmap_raw_data), kIdmapRawDataLen); + std::istringstream raw_stream(raw); - auto result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, - /* enforce_overlayable */ true); + auto result = Idmap::FromBinaryStream(raw_stream); ASSERT_TRUE(result); const auto idmap = std::move(*result); @@ -411,8 +412,9 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream); ASSERT_THAT(header, NotNull()); - ASSERT_TRUE(header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_TRUE(header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name, + kIdmapRawDataTargetCrc, overlay_crc, policies, + /* enforce_overlayable */ true)); // magic: bytes (0x0, 0x03) std::string bad_magic_string(stream.str()); @@ -425,8 +427,9 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { IdmapHeader::FromBinaryStream(bad_magic_stream); ASSERT_THAT(bad_magic_header, NotNull()); ASSERT_NE(header->GetMagic(), bad_magic_header->GetMagic()); - ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name, + target_crc, overlay_crc, policies, + /* enforce_overlayable */ true)); // version: bytes (0x4, 0x07) std::string bad_version_string(stream.str()); @@ -439,8 +442,9 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { IdmapHeader::FromBinaryStream(bad_version_stream); ASSERT_THAT(bad_version_header, NotNull()); ASSERT_NE(header->GetVersion(), bad_version_header->GetVersion()); - ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name, + target_crc, overlay_crc, policies, + /* enforce_overlayable */ true)); // target crc: bytes (0x8, 0xb) std::string bad_target_crc_string(stream.str()); @@ -453,8 +457,9 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { IdmapHeader::FromBinaryStream(bad_target_crc_stream); ASSERT_THAT(bad_target_crc_header, NotNull()); ASSERT_NE(header->GetTargetCrc(), bad_target_crc_header->GetTargetCrc()); - ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name, + target_crc, overlay_crc, policies, + /* enforce_overlayable */ true)); // overlay crc: bytes (0xc, 0xf) std::string bad_overlay_crc_string(stream.str()); @@ -467,8 +472,9 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { IdmapHeader::FromBinaryStream(bad_overlay_crc_stream); ASSERT_THAT(bad_overlay_crc_header, NotNull()); ASSERT_NE(header->GetOverlayCrc(), bad_overlay_crc_header->GetOverlayCrc()); - ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name, + target_crc, overlay_crc, policies, + /* enforce_overlayable */ true)); // fulfilled policy: bytes (0x10, 0x13) std::string bad_policy_string(stream.str()); @@ -481,8 +487,9 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { IdmapHeader::FromBinaryStream(bad_policy_stream); ASSERT_THAT(bad_policy_header, NotNull()); ASSERT_NE(header->GetFulfilledPolicies(), bad_policy_header->GetFulfilledPolicies()); - ASSERT_FALSE(bad_policy_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_policy_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name, + target_crc, overlay_crc, policies, + /* enforce_overlayable */ true)); // enforce overlayable: bytes (0x14) std::string bad_enforce_string(stream.str()); @@ -492,30 +499,47 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { IdmapHeader::FromBinaryStream(bad_enforce_stream); ASSERT_THAT(bad_enforce_header, NotNull()); ASSERT_NE(header->GetEnforceOverlayable(), bad_enforce_header->GetEnforceOverlayable()); - ASSERT_FALSE(bad_enforce_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_enforce_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name, + target_crc, overlay_crc, policies, + /* enforce_overlayable */ true)); - // target path: bytes (0x18, 0x117) + // target path: bytes (0x1c, 0x27) std::string bad_target_path_string(stream.str()); - bad_target_path_string[0x18] = '\0'; + bad_target_path_string[0x1c] = '\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); ASSERT_THAT(bad_target_path_header, NotNull()); ASSERT_NE(header->GetTargetPath(), bad_target_path_header->GetTargetPath()); - ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name, + target_crc, overlay_crc, policies, + /* enforce_overlayable */ true)); - // overlay path: bytes (0x118, 0x217) + // overlay path: bytes (0x2c, 0x37) std::string bad_overlay_path_string(stream.str()); - bad_overlay_path_string[0x118] = '\0'; + bad_overlay_path_string[0x33] = '\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); ASSERT_THAT(bad_overlay_path_header, NotNull()); ASSERT_NE(header->GetOverlayPath(), bad_overlay_path_header->GetOverlayPath()); - ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), - PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + ASSERT_FALSE(bad_overlay_path_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name, + target_crc, overlay_crc, policies, + /* enforce_overlayable */ true)); + + // overlay path: bytes (0x3c, 0x47) + std::string bad_overlay_name_string(stream.str()); + bad_overlay_name_string[0x3c] = '\0'; + std::stringstream bad_overlay_name_stream(bad_overlay_name_string); + std::unique_ptr<const IdmapHeader> bad_overlay_name_header = + IdmapHeader::FromBinaryStream(bad_overlay_name_stream); + ASSERT_THAT(bad_overlay_name_header, NotNull()); + ASSERT_NE(header->GetOverlayName(), bad_overlay_name_header->GetOverlayName()); + ASSERT_FALSE(bad_overlay_name_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name, + target_crc, overlay_crc, policies, + /* enforce_overlayable */ true)); + + // overlay name: bytes (0x2c, 0x37) } class TestVisitor : public Visitor { @@ -544,7 +568,7 @@ class TestVisitor : public Visitor { }; TEST(IdmapTests, TestVisitor) { - std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len); + std::string raw(reinterpret_cast<const char*>(idmap_raw_data), kIdmapRawDataLen); std::istringstream stream(raw); const auto idmap = Idmap::FromBinaryStream(stream); diff --git a/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp b/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp index d30fbfcb1d3c..87ce0f13d19e 100644 --- a/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp +++ b/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp @@ -15,22 +15,21 @@ */ #include <memory> -#include <sstream> #include <string> #include "R.h" +#include "TestConstants.h" #include "TestHelpers.h" #include "androidfw/ApkAssets.h" -#include "androidfw/Idmap.h" #include "androidfw/ResourceTypes.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "idmap2/Idmap.h" #include "idmap2/PrettyPrintVisitor.h" -using ::testing::NotNull; - using android::ApkAssets; +using android::base::StringPrintf; +using ::testing::NotNull; using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; @@ -46,7 +45,8 @@ TEST(PrettyPrintVisitorTests, CreatePrettyPrintVisitor) { std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - const auto idmap = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, + const auto idmap = Idmap::FromApkAssets(*target_apk, *overlay_apk, + TestConstants::OVERLAY_NAME_DEFAULT, PolicyFlags::PUBLIC, /* enforce_overlayable */ true); ASSERT_TRUE(idmap); @@ -56,15 +56,15 @@ 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 -> integer/int1)\n"), + ASSERT_NE(stream.str().find(StringPrintf("0x%08x -> 0x%08x (integer/int1 -> integer/int1)\n", + R::target::integer::int1, R::overlay::integer::int1)), std::string::npos); } TEST(PrettyPrintVisitorTests, CreatePrettyPrintVisitorWithoutAccessToApks) { fclose(stderr); // silence expected warnings from libandroidfw - std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len); + std::string raw(reinterpret_cast<const char*>(idmap_raw_data), kIdmapRawDataLen); std::istringstream raw_stream(raw); const auto idmap = Idmap::FromBinaryStream(raw_stream); diff --git a/cmds/idmap2/tests/R.h b/cmds/idmap2/tests/R.h index 854b57fb22aa..ac9b0580d2d9 100644 --- a/cmds/idmap2/tests/R.h +++ b/cmds/idmap2/tests/R.h @@ -23,22 +23,11 @@ namespace android::idmap2 { -static std::string hexify(ResourceId id) { - std::stringstream stream; - stream << std::hex << static_cast<uint32_t>(id); - return stream.str(); -} - // clang-format off namespace R::target { namespace integer { // NOLINT(runtime/indentation_namespace) constexpr ResourceId int1 = 0x7f010000; - - namespace literal { // NOLINT(runtime/indentation_namespace) - inline const std::string int1 = hexify(R::target::integer::int1); - } } - namespace string { // NOLINT(runtime/indentation_namespace) constexpr ResourceId not_overlayable = 0x7f020003; constexpr ResourceId other = 0x7f020004; @@ -54,56 +43,31 @@ namespace R::target { constexpr ResourceId str1 = 0x7f02000e; constexpr ResourceId str3 = 0x7f020010; constexpr ResourceId str4 = 0x7f020011; - - namespace literal { // NOLINT(runtime/indentation_namespace) - inline const std::string str1 = hexify(R::target::string::str1); - inline const std::string str3 = hexify(R::target::string::str3); - inline const std::string str4 = hexify(R::target::string::str4); - } } // namespace string } // namespace R::target namespace R::overlay { namespace integer { // NOLINT(runtime/indentation_namespace) constexpr ResourceId int1 = 0x7f010000; + constexpr ResourceId not_in_target = 0x7f010001; } namespace string { // NOLINT(runtime/indentation_namespace) - constexpr ResourceId str1 = 0x7f020000; - constexpr ResourceId str3 = 0x7f020001; - constexpr ResourceId str4 = 0x7f020002; - } -} - -namespace R::overlay_shared { - namespace integer { // NOLINT(runtime/indentation_namespace) - constexpr ResourceId int1 = 0x00010000; - } - namespace string { // NOLINT(runtime/indentation_namespace) - constexpr ResourceId str1 = 0x00020000; - constexpr ResourceId str3 = 0x00020001; - constexpr ResourceId str4 = 0x00020002; + constexpr ResourceId not_overlayable = 0x7f020000; + constexpr ResourceId other = 0x7f020001; + constexpr ResourceId policy_actor = 0x7f020002; + constexpr ResourceId policy_config_signature = 0x7f020003; + constexpr ResourceId policy_odm = 0x7f020004; + constexpr ResourceId policy_oem = 0x7f020005; + constexpr ResourceId policy_product = 0x7f020006; + constexpr ResourceId policy_public = 0x7f020007; + constexpr ResourceId policy_signature = 0x7f020008; + constexpr ResourceId policy_system = 0x7f020009; + constexpr ResourceId policy_system_vendor = 0x7f02000a; + constexpr ResourceId str1 = 0x7f02000b; + constexpr ResourceId str3 = 0x7f02000c; + constexpr ResourceId str4 = 0x7f02000d; } } - -namespace R::system_overlay::string { - constexpr ResourceId policy_public = 0x7f010000; - constexpr ResourceId policy_system = 0x7f010001; - constexpr ResourceId policy_system_vendor = 0x7f010002; -} - -namespace R::system_overlay_invalid::string { - constexpr ResourceId not_overlayable = 0x7f010000; - constexpr ResourceId other = 0x7f010001; - constexpr ResourceId policy_actor = 0x7f010002; - constexpr ResourceId policy_config_signature = 0x7f010003; - constexpr ResourceId policy_odm = 0x7f010004; - constexpr ResourceId policy_oem = 0x7f010005; - constexpr ResourceId policy_product = 0x7f010006; - constexpr ResourceId policy_public = 0x7f010007; - constexpr ResourceId policy_signature = 0x7f010008; - constexpr ResourceId policy_system = 0x7f010009; - constexpr ResourceId policy_system_vendor = 0x7f01000a; -} // namespace R::system_overlay_invalid::string // clang-format on } // namespace android::idmap2 diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp index 95bd94733ab3..88f85efb0f84 100644 --- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp +++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp @@ -56,8 +56,9 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) { std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - const auto idmap = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, - /* enforce_overlayable */ true); + const auto idmap = + Idmap::FromApkAssets(*target_apk, *overlay_apk, TestConstants::OVERLAY_NAME_DEFAULT, + PolicyFlags::PUBLIC, /* enforce_overlayable */ true); ASSERT_TRUE(idmap); std::stringstream stream; @@ -65,7 +66,7 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) { (*idmap)->accept(&visitor); ASSERT_CONTAINS_REGEX(ADDRESS "504d4449 magic\n", stream.str()); - ASSERT_CONTAINS_REGEX(ADDRESS "00000005 version\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000007 version\n", stream.str()); ASSERT_CONTAINS_REGEX( StringPrintf(ADDRESS "%s target crc\n", android::idmap2::TestConstants::TARGET_CRC_STRING), stream.str()); @@ -76,22 +77,34 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) { 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 "7f010000 target id: 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()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000004 target entry count", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000000 target inline entry count", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000004 overlay entry count", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "0000000a string pool index offset", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 target id: integer/int1", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 overlay id: integer/int1", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f02000e target id: string/str1", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f02000b overlay id: string/str1", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f020010 target id: string/str3", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f02000c overlay id: string/str3", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f020011 target id: string/str4", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f02000d overlay id: string/str4", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 overlay id: integer/int1", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 target id: integer/int1", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f02000b overlay id: string/str1", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f02000e target id: string/str1", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f02000c overlay id: string/str3", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f020010 target id: string/str3", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f02000d overlay id: string/str4", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f020011 target id: string/str4", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "000000b4 string pool size", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "........ string pool", stream.str()); } TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) { fclose(stderr); // silence expected warnings from libandroidfw - std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len); + std::string raw(reinterpret_cast<const char*>(idmap_raw_data), kIdmapRawDataLen); std::istringstream raw_stream(raw); const auto idmap = Idmap::FromBinaryStream(raw_stream); @@ -102,11 +115,17 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) { (*idmap)->accept(&visitor); ASSERT_CONTAINS_REGEX(ADDRESS "504d4449 magic\n", stream.str()); - ASSERT_CONTAINS_REGEX(ADDRESS "00000005 version\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000007 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 "00000001 enforce overlayable\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "0000000b target path size\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "........ target path: targetX.apk\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "0000000c overlay path size\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "........ overlay path: overlayX.apk\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "0000000b overlay name size\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "........ overlay name: OverlayName\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()); @@ -121,7 +140,7 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) { 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()); + ASSERT_CONTAINS_REGEX("000000a8: ........ string pool\n", stream.str()); } } // namespace android::idmap2 diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp index 185e9292346d..0362529c4f3b 100644 --- a/cmds/idmap2/tests/ResourceMappingTests.cpp +++ b/cmds/idmap2/tests/ResourceMappingTests.cpp @@ -17,12 +17,10 @@ #include <cstdio> // fclose #include <fstream> #include <memory> -#include <sstream> #include <string> -#include <utility> -#include <vector> #include "R.h" +#include "TestConstants.h" #include "TestHelpers.h" #include "androidfw/ResourceTypes.h" #include "gmock/gmock.h" @@ -43,38 +41,32 @@ namespace android::idmap2 { ASSERT_TRUE(result) << result.GetErrorMessage(); \ } while (0) -Result<ResourceMapping> TestGetResourceMapping(const android::StringPiece& local_target_apk_path, - const android::StringPiece& local_overlay_apk_path, - const OverlayManifestInfo& overlay_info, +Result<ResourceMapping> TestGetResourceMapping(const std::string& local_target_apk_path, + const std::string& local_overlay_apk_path, + const std::string& overlay_name, const PolicyBitmask& fulfilled_policies, bool enforce_overlayable) { - const std::string target_apk_path(GetTestDataPath() + local_target_apk_path.data()); + auto overlay_info = + ExtractOverlayManifestInfo(GetTestDataPath() + local_overlay_apk_path, overlay_name); + if (!overlay_info) { + return overlay_info.GetError(); + } + + const std::string target_apk_path(GetTestDataPath() + local_target_apk_path); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); if (!target_apk) { return Error(R"(Failed to load target apk "%s")", target_apk_path.data()); } - const std::string overlay_apk_path(GetTestDataPath() + local_overlay_apk_path.data()); + const std::string overlay_apk_path(GetTestDataPath() + local_overlay_apk_path); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); if (!overlay_apk) { return Error(R"(Failed to load overlay apk "%s")", overlay_apk_path.data()); } LogInfo log_info; - return ResourceMapping::FromApkAssets(*target_apk, *overlay_apk, overlay_info, fulfilled_policies, - enforce_overlayable, log_info); -} - -Result<ResourceMapping> TestGetResourceMapping(const android::StringPiece& local_target_apk_path, - const android::StringPiece& local_overlay_apk_path, - const PolicyBitmask& fulfilled_policies, - bool enforce_overlayable) { - auto overlay_info = ExtractOverlayManifestInfo(GetTestDataPath() + local_overlay_apk_path.data()); - if (!overlay_info) { - return overlay_info.GetError(); - } - return TestGetResourceMapping(local_target_apk_path, local_overlay_apk_path, *overlay_info, - fulfilled_policies, enforce_overlayable); + return ResourceMapping::FromApkAssets(*target_apk, *overlay_apk, *overlay_info, + fulfilled_policies, enforce_overlayable, log_info); } Result<Unit> MappingExists(const ResourceMapping& mapping, ResourceId target_resource, @@ -136,13 +128,8 @@ Result<Unit> MappingExists(const ResourceMapping& mapping, const ResourceId& tar } TEST(ResourceMappingTests, ResourcesFromApkAssetsLegacy) { - OverlayManifestInfo info{}; - info.target_package = "test.target"; - info.target_name = "TestResources"; - info.resource_mapping = 0U; // no xml - auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", info, - PolicyFlags::PUBLIC, - /* enforce_overlayable */ false); + auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay-legacy.apk", "", + PolicyFlags::PUBLIC, /* enforce_overlayable */ false); ASSERT_TRUE(resources) << resources.GetErrorMessage(); auto& res = *resources; @@ -158,11 +145,7 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsLegacy) { } TEST(ResourceMappingTests, ResourcesFromApkAssetsNonMatchingNames) { - OverlayManifestInfo info{}; - info.target_package = "test.target"; - info.target_name = "TestResources"; - info.resource_mapping = 0x7f030003; // xml/overlays_swap - auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", info, + auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", "SwapNames", PolicyFlags::PUBLIC, /* enforce_overlayable */ false); @@ -178,12 +161,8 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsNonMatchingNames) { } TEST(ResourceMappingTests, DoNotRewriteNonOverlayResourceId) { - OverlayManifestInfo info{}; - info.target_package = "test.target"; - info.target_name = "TestResources"; - info.resource_mapping = 0x7f030001; // xml/overlays_different_packages - auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", info, - PolicyFlags::PUBLIC, + auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", + "DifferentPackages", PolicyFlags::PUBLIC, /* enforce_overlayable */ false); ASSERT_TRUE(resources) << resources.GetErrorMessage(); @@ -192,19 +171,15 @@ TEST(ResourceMappingTests, DoNotRewriteNonOverlayResourceId) { ASSERT_EQ(res.GetOverlayToTargetMap().size(), 1U); ASSERT_RESULT(MappingExists(res, R::target::string::str1, 0x0104000a, false /* rewrite */)); // -> android:string/ok - ASSERT_RESULT(MappingExists(res, R::target::string::str3, 0x7f020001, true /* rewrite */)); + ASSERT_RESULT( + MappingExists(res, R::target::string::str3, R::overlay::string::str3, true /* rewrite */)); } TEST(ResourceMappingTests, InlineResources) { - OverlayManifestInfo info{}; - info.target_package = "test.target"; - info.target_name = "TestResources"; - info.resource_mapping = 0x7f030002; // xml/overlays_inline - auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", info, - PolicyFlags::PUBLIC, - /* enforce_overlayable */ false); + auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", "Inline", + PolicyFlags::PUBLIC, /* enforce_overlayable */ false); - constexpr size_t overlay_string_pool_size = 8U; + constexpr size_t overlay_string_pool_size = 10U; ASSERT_TRUE(resources) << resources.GetErrorMessage(); auto& res = *resources; ASSERT_EQ(res.GetTargetToOverlayMap().size(), 2U); @@ -215,28 +190,27 @@ TEST(ResourceMappingTests, InlineResources) { } TEST(ResourceMappingTests, CreateIdmapFromApkAssetsPolicySystemPublic) { - auto resources = - TestGetResourceMapping("/target/target.apk", "/system-overlay/system-overlay.apk", - PolicyFlags::SYSTEM_PARTITION | PolicyFlags::PUBLIC, - /* enforce_overlayable */ true); + auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", + TestConstants::OVERLAY_NAME_ALL_POLICIES, + PolicyFlags::SYSTEM_PARTITION | PolicyFlags::PUBLIC, + /* enforce_overlayable */ true); ASSERT_TRUE(resources) << resources.GetErrorMessage(); auto& res = *resources; ASSERT_EQ(res.GetTargetToOverlayMap().size(), 3U); ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, - R::system_overlay::string::policy_public, false /* rewrite */)); + R::overlay::string::policy_public, true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, - R::system_overlay::string::policy_system, false /* rewrite */)); + R::overlay::string::policy_system, true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor, - R::system_overlay::string::policy_system_vendor, - false /* rewrite */)); + R::overlay::string::policy_system_vendor, true /* rewrite */)); } // Resources that are not declared as overlayable and resources that a protected by policies the // overlay does not fulfill must not map to overlay resources. TEST(ResourceMappingTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) { - auto resources = TestGetResourceMapping("/target/target.apk", - "/system-overlay-invalid/system-overlay-invalid.apk", + auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", + TestConstants::OVERLAY_NAME_ALL_POLICIES, PolicyFlags::SYSTEM_PARTITION | PolicyFlags::PUBLIC, /* enforce_overlayable */ true); @@ -244,22 +218,19 @@ TEST(ResourceMappingTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) { auto& res = *resources; ASSERT_EQ(res.GetTargetToOverlayMap().size(), 3U); ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, - R::system_overlay_invalid::string::policy_public, - false /* rewrite */)); + R::overlay::string::policy_public, true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, - R::system_overlay_invalid::string::policy_system, - false /* rewrite */)); + R::overlay::string::policy_system, true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor, - R::system_overlay_invalid::string::policy_system_vendor, - false /* rewrite */)); + R::overlay::string::policy_system_vendor, true /* rewrite */)); } // Resources that are not declared as overlayable and resources that a protected by policies the // overlay does not fulfilled can map to overlay resources when overlayable enforcement is turned // off. TEST(ResourceMappingTests, ResourcesFromApkAssetsPolicySystemPublicInvalidIgnoreOverlayable) { - auto resources = TestGetResourceMapping("/target/target.apk", - "/system-overlay-invalid/system-overlay-invalid.apk", + auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", + TestConstants::OVERLAY_NAME_ALL_POLICIES, PolicyFlags::SYSTEM_PARTITION | PolicyFlags::PUBLIC, /* enforce_overlayable */ false); @@ -267,41 +238,33 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsPolicySystemPublicInvalidIgnore auto& res = *resources; ASSERT_EQ(res.GetTargetToOverlayMap().size(), 11U); 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, - R::system_overlay_invalid::string::other, false /* rewrite */)); + R::overlay::string::not_overlayable, true /* rewrite */)); + ASSERT_RESULT( + MappingExists(res, R::target::string::other, R::overlay::string::other, true /* rewrite */)); 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, - R::system_overlay_invalid::string::policy_odm, false /* rewrite */)); - ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem, - R::system_overlay_invalid::string::policy_oem, false /* rewrite */)); + R::overlay::string::policy_actor, true /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm, R::overlay::string::policy_odm, + true /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem, R::overlay::string::policy_oem, + true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_product, - R::system_overlay_invalid::string::policy_product, - false /* rewrite */)); + R::overlay::string::policy_product, true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, - R::system_overlay_invalid::string::policy_public, - false /* rewrite */)); + R::overlay::string::policy_public, true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_config_signature, - R::system_overlay_invalid::string::policy_config_signature, - false /* rewrite */)); + R::overlay::string::policy_config_signature, true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, - R::system_overlay_invalid::string::policy_signature, - false /* rewrite */)); + R::overlay::string::policy_signature, true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, - R::system_overlay_invalid::string::policy_system, - false /* rewrite */)); + R::overlay::string::policy_system, true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor, - R::system_overlay_invalid::string::policy_system_vendor, - false /* rewrite */)); + R::overlay::string::policy_system_vendor, true /* rewrite */)); } -// Overlays that do not target an <overlayable> tag can overlay resources defined within any -// <overlayable> tag. +// Overlays that do not target an <overlayable> tag can overlay any resource if overlayable +// enforcement is disabled. TEST(ResourceMappingTests, ResourcesFromApkAssetsNoDefinedOverlayableAndNoTargetName) { - auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay-no-name.apk", + auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay-legacy.apk", "", PolicyFlags::PUBLIC, /* enforce_overlayable */ false); @@ -321,9 +284,10 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsNoDefinedOverlayableAndNoTarget // Overlays that are neither pre-installed nor signed with the same signature as the target cannot // overlay packages that have not defined overlayable resources. TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPoliciesPublicFail) { - auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk", - "/overlay/overlay-no-name.apk", PolicyFlags::PUBLIC, - /* enforce_overlayable */ true); + auto resources = + TestGetResourceMapping("/target/target-no-overlayable.apk", "/overlay/overlay.apk", + "NoTargetName", PolicyFlags::PUBLIC, + /* enforce_overlayable */ true); ASSERT_TRUE(resources) << resources.GetErrorMessage(); ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 0U); @@ -334,46 +298,36 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPoliciesPublicFail) { // defined overlayable resources. TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) { auto CheckEntries = [&](const PolicyBitmask& fulfilled_policies) -> void { - auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk", - "/system-overlay-invalid/system-overlay-invalid.apk", - fulfilled_policies, - /* enforce_overlayable */ true); + auto resources = + TestGetResourceMapping("/target/target-no-overlayable.apk", "/overlay/overlay.apk", + TestConstants::OVERLAY_NAME_ALL_POLICIES, fulfilled_policies, + /* enforce_overlayable */ true); ASSERT_TRUE(resources) << resources.GetErrorMessage(); auto& res = *resources; ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 11U); 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, - R::system_overlay_invalid::string::other, false /* rewrite */)); + R::overlay::string::not_overlayable, true /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::other, R::overlay::string::other, + true /* rewrite */)); 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, - R::system_overlay_invalid::string::policy_odm, - false /* rewrite */)); - ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem, - R::system_overlay_invalid::string::policy_oem, - false /* rewrite */)); + R::overlay::string::policy_actor, true /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm, R::overlay::string::policy_odm, + true /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem, R::overlay::string::policy_oem, + true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_product, - R::system_overlay_invalid::string::policy_product, - false /* rewrite */)); + R::overlay::string::policy_product, true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, - R::system_overlay_invalid::string::policy_public, - false /* rewrite */)); + R::overlay::string::policy_public, true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_config_signature, - R::system_overlay_invalid::string::policy_config_signature, - false /* rewrite */)); + R::overlay::string::policy_config_signature, true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, - R::system_overlay_invalid::string::policy_signature, - false /* rewrite */)); + R::overlay::string::policy_signature, true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, - R::system_overlay_invalid::string::policy_system, - false /* rewrite */)); + R::overlay::string::policy_system, true /* rewrite */)); ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor, - R::system_overlay_invalid::string::policy_system_vendor, - false /* rewrite */)); + R::overlay::string::policy_system_vendor, true /* rewrite */)); }; CheckEntries(PolicyFlags::SIGNATURE); diff --git a/cmds/idmap2/tests/ResourceUtilsTests.cpp b/cmds/idmap2/tests/ResourceUtilsTests.cpp index 9ed807ccd8f9..1f6bf49f5f0e 100644 --- a/cmds/idmap2/tests/ResourceUtilsTests.cpp +++ b/cmds/idmap2/tests/ResourceUtilsTests.cpp @@ -59,4 +59,26 @@ TEST_F(ResourceUtilsTests, ResToTypeEntryNameNoSuchResourceId) { ASSERT_FALSE(name); } -} // namespace android::idmap2 +TEST_F(ResourceUtilsTests, InvalidValidOverlayNameInvalidAttributes) { + auto info = utils::ExtractOverlayManifestInfo(GetTestDataPath() + "/overlay/overlay-invalid.apk", + "InvalidName"); + ASSERT_FALSE(info); +} + +TEST_F(ResourceUtilsTests, ValidOverlayNameInvalidAttributes) { + auto info = utils::ExtractOverlayManifestInfo(GetTestDataPath() + "/overlay/overlay-invalid.apk", + "ValidName"); + ASSERT_FALSE(info); +} + +TEST_F(ResourceUtilsTests, ValidOverlayNameAndTargetPackageInvalidAttributes) { + auto info = utils::ExtractOverlayManifestInfo(GetTestDataPath() + "/overlay/overlay-invalid.apk", + "ValidNameAndTargetPackage"); + ASSERT_TRUE(info); + ASSERT_EQ("ValidNameAndTargetPackage", info->name); + ASSERT_EQ("Valid", info->target_package); + ASSERT_EQ("", info->target_name); // Attribute resource id could not be found + ASSERT_EQ(0, info->resource_mapping); // Attribute resource id could not be found +} + +}// namespace android::idmap2 diff --git a/cmds/idmap2/tests/TestConstants.h b/cmds/idmap2/tests/TestConstants.h index 69575b8f9c01..d5799adf0ec3 100644 --- a/cmds/idmap2/tests/TestConstants.h +++ b/cmds/idmap2/tests/TestConstants.h @@ -22,8 +22,11 @@ namespace android::idmap2::TestConstants { constexpr const auto TARGET_CRC = 0x7c2d4719; constexpr const auto TARGET_CRC_STRING = "7c2d4719"; -constexpr const auto OVERLAY_CRC = 0x5afff726; -constexpr const auto OVERLAY_CRC_STRING = "5afff726"; +constexpr const auto OVERLAY_CRC = 0xb71095cf; +constexpr const auto OVERLAY_CRC_STRING = "b71095cf"; + +constexpr const char* OVERLAY_NAME_DEFAULT = "Default"; +constexpr const char* OVERLAY_NAME_ALL_POLICIES = "AllPolicies"; } // namespace android::idmap2::TestConstants diff --git a/cmds/idmap2/tests/TestHelpers.h b/cmds/idmap2/tests/TestHelpers.h index d0a8e3db8eca..842af3dd7b3c 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 - 0x05, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, // 0x8: target crc 0x34, 0x12, 0x00, 0x00, @@ -44,125 +44,114 @@ const unsigned char idmap_raw_data[] = { // 0x14: enforce overlayable 0x01, 0x00, 0x00, 0x00, - // 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, - 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - // 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, - 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - // 0x218: debug string + // 0x18: target path length + 0x0b, 0x00, 0x00, 0x00, + + // 0x1c: target path "targetX.apk" + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x58, 0x2e, 0x61, 0x70, 0x6b, 0x00, + + // 0x28: overlay path length + 0x0c, 0x00, 0x00, 0x00, + + // 0x2c: overlay path "overlayX.apk" + 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x58, 0x2e, 0x61, 0x70, 0x6b, + + // 0x38: overlay name length + 0x0b, 0x00, 0x00, 0x00, + + // 0x3c: overlay name "OverlayName" + 0x4f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6D, 0x65, 0x00, + + // 0x48 -> 4c: debug string // string length, 0x05, 0x00, 0x00, 0x00, - // 0x21c string contents "debug\0\0\0" (padded to word alignment) + // 0x4c string contents "debug\0\0\0" (padded to word alignment) 0x64, 0x65, 0x62, 0x75, 0x67, 0x00, 0x00, 0x00, // DATA HEADER - // 0x224: target_package_id + // 0x54: target_package_id 0x7f, - // 0x225: overlay_package_id + // 0x55: overlay_package_id 0x7f, - // 0x226: padding + // 0x56: padding 0x00, 0x00, - // 0x228: target_entry_count + // 0x58: target_entry_count 0x03, 0x00, 0x00, 0x00, - // 0x22c: target_inline_entry_count + // 0x5c: target_inline_entry_count 0x01, 0x00, 0x00, 0x00, - // 0x230: overlay_entry_count + // 0x60: overlay_entry_count 0x03, 0x00, 0x00, 0x00, - // 0x234: string_pool_offset + // 0x64: string_pool_offset 0x00, 0x00, 0x00, 0x00, // TARGET ENTRIES - // 0x238: target id (0x7f020000) + // 0x68: target id (0x7f020000) 0x00, 0x00, 0x02, 0x7f, - // 0x23c: overlay_id (0x7f020000) + // 0x6c: overlay_id (0x7f020000) 0x00, 0x00, 0x02, 0x7f, - // 0x240: target id (0x7f030000) + // 0x70: target id (0x7f030000) 0x00, 0x00, 0x03, 0x7f, - // 0x244: overlay_id (0x7f030000) + // 0x74: overlay_id (0x7f030000) 0x00, 0x00, 0x03, 0x7f, - // 0x248: target id (0x7f030002) + // 0x78: target id (0x7f030002) 0x02, 0x00, 0x03, 0x7f, - // 0x24c: overlay_id (0x7f030001) + // 0x7c: overlay_id (0x7f030001) 0x01, 0x00, 0x03, 0x7f, // INLINE TARGET ENTRIES - // 0x250: target_id + // 0x80: target_id 0x00, 0x00, 0x04, 0x7f, - // 0x254: Res_value::size (value ignored by idmap) + // 0x84: Res_value::size (value ignored by idmap) 0x08, 0x00, - // 0x256: Res_value::res0 (value ignored by idmap) + // 0x87: Res_value::res0 (value ignored by idmap) 0x00, - // 0x257: Res_value::dataType (TYPE_INT_HEX) + // 0x88: Res_value::dataType (TYPE_INT_HEX) 0x11, - // 0x258: Res_value::data + // 0x8c: Res_value::data 0x78, 0x56, 0x34, 0x12, // OVERLAY ENTRIES - // 0x25c: 0x7f020000 -> 0x7f020000 + // 0x90: 0x7f020000 -> 0x7f020000 0x00, 0x00, 0x02, 0x7f, 0x00, 0x00, 0x02, 0x7f, - // 0x264: 0x7f030000 -> 0x7f030000 + // 0x98: 0x7f030000 -> 0x7f030000 0x00, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x03, 0x7f, - // 0x26c: 0x7f030001 -> 0x7f030002 + // 0xa0: 0x7f030001 -> 0x7f030002 0x01, 0x00, 0x03, 0x7f, 0x02, 0x00, 0x03, 0x7f, - // 0x274: string pool + // 0xa4: string pool // string length, 0x04, 0x00, 0x00, 0x00, - // 0x278 string contents "test" (padded to word alignment) + // 0xa8 string contents "test" 0x74, 0x65, 0x73, 0x74}; -const unsigned int idmap_raw_data_len = 0x27c; +const unsigned int kIdmapRawDataLen = 0xac; +const unsigned int kIdmapRawDataOffset = 0x54; +const unsigned int kIdmapRawDataTargetCrc = 0x1234; +const unsigned int kIdmapRawOverlayCrc = 0x5678; +const unsigned int kIdmapRawDataPolicies = 0x11; +inline const std::string kIdmapRawTargetPath = "targetX.apk"; +inline const std::string kIdmapRawOverlayPath = "overlayX.apk"; +inline const std::string kIdmapRawOverlayName = "OverlayName"; std::string GetTestDataPath(); diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifest.xml b/cmds/idmap2/tests/data/overlay/AndroidManifest.xml index cf3691c3b3cf..2c50dee05b11 100644 --- a/cmds/idmap2/tests/data/overlay/AndroidManifest.xml +++ b/cmds/idmap2/tests/data/overlay/AndroidManifest.xml @@ -13,14 +13,37 @@ See the License for the specific language governing permissions and limitations under the License. --> -<manifest - xmlns:android="http://schemas.android.com/apk/res/android" - package="test.overlay"> - +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="test.overlay"> <application android:hasCode="false"/> - <overlay - android:targetPackage="test.target" - android:targetName="TestResources" - android:resourcesMap="@xml/overlays"/> + <overlay android:name="Default" + android:targetPackage="test.target" + android:targetName="TestResources" + android:resourcesMap="@xml/overlays"/> + + <overlay android:name="NoTargetName" + android:targetPackage="test.target" + android:resourcesMap="@xml/overlays"/> + + <overlay android:name="Inline" + android:targetName="TestResources" + android:targetPackage="test.target" + android:resourcesMap="@xml/overlays_inline"/> + + <overlay android:name="DifferentPackages" + android:targetName="TestResources" + android:targetPackage="test.target" + android:resourcesMap="@xml/overlays_different_package"/> + + <overlay android:name="SwapNames" + android:targetName="TestResources" + android:targetPackage="test.target" + android:resourcesMap="@xml/overlays_swap"/> + + <overlay android:name="AllPolicies" + android:targetName="TestResources" + android:targetPackage="test.target" + android:resourcesMap="@xml/overlays_policies"/> + </manifest> diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifestStatic1.xml b/cmds/idmap2/tests/data/overlay/AndroidManifestInvalid.xml index 1c4dae6cf69c..d61c36cad60c 100644 --- a/cmds/idmap2/tests/data/overlay/AndroidManifestStatic1.xml +++ b/cmds/idmap2/tests/data/overlay/AndroidManifestInvalid.xml @@ -13,12 +13,22 @@ See the License for the specific language governing permissions and limitations under the License. --> -<manifest - xmlns:android="http://schemas.android.com/apk/res/android" - package="test.overlay.static1"> - <overlay - android:targetPackage="test.target" - android:targetName="TestResources" - android:isStatic="true" - android:priority="1" /> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="test.overlay"> + <application android:hasCode="false"/> + + <overlay name="InvalidName" + android:targetName="Invalid" + android:targetPackage="Invalid" + android:resourcesMap="@xml/overlays_swap"/> + + <overlay android:name="ValidName" + targetName="Invalid" + targetPackage="Invalid" + resourcesMap="@xml/overlays_swap"/> + + <overlay android:name="ValidNameAndTargetPackage" + targetName="Invalid" + android:targetPackage="Valid" + resourcesMap="@xml/overlays_swap"/> </manifest> diff --git a/cmds/idmap2/tests/data/system-overlay/AndroidManifest.xml b/cmds/idmap2/tests/data/overlay/AndroidManifestLegacy.xml index 9e6a4536cb51..9fc2105fe827 100644 --- a/cmds/idmap2/tests/data/system-overlay/AndroidManifest.xml +++ b/cmds/idmap2/tests/data/overlay/AndroidManifestLegacy.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project +<!-- Copyright (C) 2018 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -13,11 +13,9 @@ See the License for the specific language governing permissions and limitations under the License. --> -<manifest - xmlns:android="http://schemas.android.com/apk/res/android" - package="test.overlay.system"> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="test.overlay"> <application android:hasCode="false"/> - <overlay - android:targetPackage="test.target" - android:targetName="TestResources"/> + + <overlay android:targetPackage="test.target"/> </manifest> diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifestNoName.xml b/cmds/idmap2/tests/data/overlay/AndroidManifestNoName.xml deleted file mode 100644 index bc6b733e849f..000000000000 --- a/cmds/idmap2/tests/data/overlay/AndroidManifestNoName.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<manifest - xmlns:android="http://schemas.android.com/apk/res/android" - package="test.overlay.no.name"> - <overlay - android:targetPackage="test.target"/> -</manifest> diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifestNoNameStatic.xml b/cmds/idmap2/tests/data/overlay/AndroidManifestNoNameStatic.xml deleted file mode 100644 index ed327ce0e630..000000000000 --- a/cmds/idmap2/tests/data/overlay/AndroidManifestNoNameStatic.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<manifest - xmlns:android="http://schemas.android.com/apk/res/android" - package="test.overlay.no.name.static"> - <overlay - android:targetPackage="test.target" - android:targetName="TestResources" - android:isStatic="true" - android:priority="1" /> -</manifest> diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifestStatic2.xml b/cmds/idmap2/tests/data/overlay/AndroidManifestStatic2.xml deleted file mode 100644 index 70efc8603670..000000000000 --- a/cmds/idmap2/tests/data/overlay/AndroidManifestStatic2.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2018 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<manifest - xmlns:android="http://schemas.android.com/apk/res/android" - package="test.overlay.static2"> - <overlay - android:targetPackage="test.target" - android:targetName="TestResources" - android:isStatic="true" - android:priority="2" /> -</manifest> diff --git a/cmds/idmap2/tests/data/overlay/build b/cmds/idmap2/tests/data/overlay/build index 114b099598fa..7b1a66f31e61 100755 --- a/cmds/idmap2/tests/data/overlay/build +++ b/cmds/idmap2/tests/data/overlay/build @@ -26,37 +26,23 @@ aapt2 link \ aapt2 link \ --no-resource-removal \ -I "$FRAMEWORK_RES_APK" \ - --manifest AndroidManifestNoName.xml \ - -o overlay-no-name.apk \ - compiled.flata - -aapt2 link \ - --no-resource-removal \ - -I "$FRAMEWORK_RES_APK" \ - --manifest AndroidManifestNoNameStatic.xml \ - -o overlay-no-name-static.apk \ - compiled.flata - -aapt2 link \ - --no-resource-removal \ - -I "$FRAMEWORK_RES_APK" \ - --manifest AndroidManifestStatic1.xml \ - -o overlay-static-1.apk \ + --manifest AndroidManifest.xml \ + -o overlay-shared.apk \ + --shared-lib \ compiled.flata aapt2 link \ --no-resource-removal \ -I "$FRAMEWORK_RES_APK" \ - --manifest AndroidManifestStatic2.xml \ - -o overlay-static-2.apk \ + --manifest AndroidManifestLegacy.xml \ + -o overlay-legacy.apk \ compiled.flata aapt2 link \ --no-resource-removal \ - --shared-lib \ -I "$FRAMEWORK_RES_APK" \ - --manifest AndroidManifest.xml \ - -o overlay-shared.apk \ + --manifest AndroidManifestInvalid.xml \ + -o overlay-invalid.apk \ compiled.flata rm compiled.flata diff --git a/cmds/idmap2/tests/data/overlay/overlay-invalid.apk b/cmds/idmap2/tests/data/overlay/overlay-invalid.apk Binary files differnew file mode 100644 index 000000000000..888c871e4101 --- /dev/null +++ b/cmds/idmap2/tests/data/overlay/overlay-invalid.apk diff --git a/cmds/idmap2/tests/data/overlay/overlay-legacy.apk b/cmds/idmap2/tests/data/overlay/overlay-legacy.apk Binary files differnew file mode 100644 index 000000000000..f03eebbf6872 --- /dev/null +++ b/cmds/idmap2/tests/data/overlay/overlay-legacy.apk diff --git a/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk b/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk Binary files differdeleted file mode 100644 index dab25b1f8131..000000000000 --- a/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk +++ /dev/null diff --git a/cmds/idmap2/tests/data/overlay/overlay-no-name.apk b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk Binary files differdeleted file mode 100644 index c8b95c2601ad..000000000000 --- a/cmds/idmap2/tests/data/overlay/overlay-no-name.apk +++ /dev/null diff --git a/cmds/idmap2/tests/data/overlay/overlay-shared.apk b/cmds/idmap2/tests/data/overlay/overlay-shared.apk Binary files differindex 0a8b7372172e..3c896ea79505 100644 --- a/cmds/idmap2/tests/data/overlay/overlay-shared.apk +++ b/cmds/idmap2/tests/data/overlay/overlay-shared.apk diff --git a/cmds/idmap2/tests/data/overlay/overlay-static-1.apk b/cmds/idmap2/tests/data/overlay/overlay-static-1.apk Binary files differdeleted file mode 100644 index fd41182f8493..000000000000 --- a/cmds/idmap2/tests/data/overlay/overlay-static-1.apk +++ /dev/null diff --git a/cmds/idmap2/tests/data/overlay/overlay-static-2.apk b/cmds/idmap2/tests/data/overlay/overlay-static-2.apk Binary files differdeleted file mode 100644 index b24765fc666a..000000000000 --- a/cmds/idmap2/tests/data/overlay/overlay-static-2.apk +++ /dev/null diff --git a/cmds/idmap2/tests/data/overlay/overlay.apk b/cmds/idmap2/tests/data/overlay/overlay.apk Binary files differindex 870575efa10c..c7ea623f64f2 100644 --- a/cmds/idmap2/tests/data/overlay/overlay.apk +++ b/cmds/idmap2/tests/data/overlay/overlay.apk diff --git a/cmds/idmap2/tests/data/overlay/res/values/values.xml b/cmds/idmap2/tests/data/overlay/res/values/values.xml index 815d1a88fa7b..6e98b212cee6 100644 --- a/cmds/idmap2/tests/data/overlay/res/values/values.xml +++ b/cmds/idmap2/tests/data/overlay/res/values/values.xml @@ -18,4 +18,25 @@ <string name="str3">overlay-3</string> <integer name="int1">-1</integer> <integer name="not_in_target">-1</integer> + + <!-- This overlay will fulfill the policies "public|system". This allows it overlay the + following resources. --> + <string name="overlay_policy_system">overlaid</string> + <string name="overlay_policy_system_vendor">overlaid</string> + <string name="overlay_policy_public">overlaid</string> + + <!-- Requests to overlay a resource that belongs to a policy the overlay does not fulfill. --> + <string name="overlay_policy_product">overlaid</string> + <string name="overlay_policy_signature">overlaid</string> + <string name="overlay_policy_odm">overlaid</string> + <string name="overlay_policy_oem">overlaid</string> + <string name="overlay_policy_actor">overlaid</string> + <string name="overlay_policy_config_signature">overlaid</string> + + <!-- Requests to overlay a resource that is not declared as overlayable. --> + <string name="overlay_not_overlayable">overlaid</string> + + <!-- Requests to overlay a resource that is defined in an overlayable with a name other than + the targetName in the manifest. --> + <string name="overlay_other">overlaid</string> </resources> diff --git a/cmds/idmap2/tests/data/overlay/res/xml/overlays_policies.xml b/cmds/idmap2/tests/data/overlay/res/xml/overlays_policies.xml new file mode 100644 index 000000000000..747f448d46fd --- /dev/null +++ b/cmds/idmap2/tests/data/overlay/res/xml/overlays_policies.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<overlay> + <item target="string/policy_system" value="@string/overlay_policy_system"/> + <item target="string/policy_system_vendor" value="@string/overlay_policy_system_vendor" /> + <item target="string/policy_public" value="@string/overlay_policy_public" /> + <item target="string/policy_product" value="@string/overlay_policy_product"/> + <item target="string/policy_signature" value="@string/overlay_policy_signature" /> + <item target="string/policy_odm" value="@string/overlay_policy_odm" /> + <item target="string/policy_oem" value="@string/overlay_policy_oem"/> + <item target="string/policy_actor" value="@string/overlay_policy_actor" /> + <item target="string/policy_config_signature" value="@string/overlay_policy_config_signature" /> + + <!-- Requests to overlay a resource that is not declared as overlayable. --> + <item target="string/not_overlayable" value="@string/overlay_not_overlayable" /> + + <!-- Requests to overlay a resource that is defined in an overlayable with a name other than + the targetName in the manifest. --> + <item target="string/other" value="@string/overlay_other" /> +</overlay>
\ No newline at end of file diff --git a/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml b/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml deleted file mode 100644 index 5df0bea555b1..000000000000 --- a/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<manifest - xmlns:android="http://schemas.android.com/apk/res/android" - package="test.overlay.system"> - <application android:hasCode="false"/> - <overlay - android:targetPackage="test.target" - android:targetName="TestResources" - android:isStatic="true" - android:priority="10"/> -</manifest> diff --git a/cmds/idmap2/tests/data/signature-overlay/build b/cmds/idmap2/tests/data/signature-overlay/build deleted file mode 100755 index fdd8301c3b7d..000000000000 --- a/cmds/idmap2/tests/data/signature-overlay/build +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2019 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FRAMEWORK_RES_APK=${ANDROID_BUILD_TOP}/prebuilts/sdk/current/public/android.jar - -aapt2 compile --dir res -o compiled.flata - -aapt2 link \ - --no-resource-removal \ - -I "$FRAMEWORK_RES_APK" \ - --manifest AndroidManifest.xml \ - -o signature-overlay.apk \ - compiled.flata - -rm compiled.flata diff --git a/cmds/idmap2/tests/data/signature-overlay/res/values/values.xml b/cmds/idmap2/tests/data/signature-overlay/res/values/values.xml deleted file mode 100644 index 59e7d8ed69c1..000000000000 --- a/cmds/idmap2/tests/data/signature-overlay/res/values/values.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources> - <!-- This overlay will fulfill the policy "signature". This allows it overlay the - following resources. --> - <string name="policy_signature">policy_signature</string> -</resources> diff --git a/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk Binary files differdeleted file mode 100644 index e0fd20499671..000000000000 --- a/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk +++ /dev/null diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/AndroidManifest.xml b/cmds/idmap2/tests/data/system-overlay-invalid/AndroidManifest.xml deleted file mode 100644 index c7b652cdb287..000000000000 --- a/cmds/idmap2/tests/data/system-overlay-invalid/AndroidManifest.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<manifest - xmlns:android="http://schemas.android.com/apk/res/android" - package="test.overlay.system.invalid"> - <application android:hasCode="false"/> - <overlay - android:targetPackage="test.target" - android:targetName="TestResources"/> -</manifest> diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/build b/cmds/idmap2/tests/data/system-overlay-invalid/build deleted file mode 100755 index 920e1f8ad6f3..000000000000 --- a/cmds/idmap2/tests/data/system-overlay-invalid/build +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2019 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FRAMEWORK_RES_APK=${ANDROID_BUILD_TOP}/prebuilts/sdk/current/public/android.jar - -aapt2 compile --dir res -o compiled.flata - -aapt2 link \ - --no-resource-removal \ - -I "$FRAMEWORK_RES_APK" \ - --manifest AndroidManifest.xml \ - -o system-overlay-invalid.apk \ - compiled.flata - -rm compiled.flata diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml b/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml deleted file mode 100644 index ebaf49c34762..000000000000 --- a/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources> - <!-- This overlay will fulfill the policies "public|system". This allows it overlay the - following resources. --> - <string name="policy_system">policy_system</string> - <string name="policy_system_vendor">policy_system_vendor</string> - <string name="policy_public">policy_public</string> - - <!-- Requests to overlay a resource that belongs to a policy the overlay does not fulfill. --> - <string name="policy_product">policy_product</string> - <string name="policy_signature">policy_signature</string> - <string name="policy_odm">policy_odm</string> - <string name="policy_oem">policy_oem</string> - <string name="policy_actor">policy_actor</string> - <string name="policy_config_signature">policy_config_signature</string> - - <!-- Requests to overlay a resource that is not declared as overlayable. --> - <string name="not_overlayable">not_overlayable</string> - - <!-- Requests to overlay a resource that is defined in an overlayable with a name other than - the targetName in the manifest. --> - <string name="other">other</string> -</resources> diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk b/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk Binary files differdeleted file mode 100644 index a63daf86caf5..000000000000 --- a/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk +++ /dev/null diff --git a/cmds/idmap2/tests/data/system-overlay/build b/cmds/idmap2/tests/data/system-overlay/build deleted file mode 100755 index be0d2390f535..000000000000 --- a/cmds/idmap2/tests/data/system-overlay/build +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2019 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FRAMEWORK_RES_APK=${ANDROID_BUILD_TOP}/prebuilts/sdk/current/public/android.jar - -aapt2 compile --dir res -o compiled.flata - -aapt2 link \ - --no-resource-removal \ - -I "$FRAMEWORK_RES_APK" \ - --manifest AndroidManifest.xml \ - -o system-overlay.apk \ - compiled.flata - -rm compiled.flata diff --git a/cmds/idmap2/tests/data/system-overlay/res/values/values.xml b/cmds/idmap2/tests/data/system-overlay/res/values/values.xml deleted file mode 100644 index 6aaa0b02639e..000000000000 --- a/cmds/idmap2/tests/data/system-overlay/res/values/values.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources> - <!-- This overlay will fulfill the policies "public|system". This allows it overlay the - following resources. --> - <string name="policy_system">policy_system</string> - <string name="policy_system_vendor">policy_system_vendor</string> - <string name="policy_public">policy_public</string> -</resources> diff --git a/cmds/idmap2/tests/data/system-overlay/system-overlay.apk b/cmds/idmap2/tests/data/system-overlay/system-overlay.apk Binary files differdeleted file mode 100644 index 90d2803a1eca..000000000000 --- a/cmds/idmap2/tests/data/system-overlay/system-overlay.apk +++ /dev/null diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp index cb56a5172a45..011a0de8031f 100755 --- a/libs/androidfw/ApkAssets.cpp +++ b/libs/androidfw/ApkAssets.cpp @@ -385,7 +385,7 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadOverlay(const std::string& idmap return {}; } - auto overlay_path = loaded_idmap->OverlayApkPath(); + auto overlay_path = std::string(loaded_idmap->OverlayApkPath()); auto assets = ZipAssetsProvider::Create(overlay_path); return (assets) ? LoadImpl(std::move(assets), overlay_path, flags | PROPERTY_OVERLAY, nullptr /* override_asset */, std::move(idmap_asset), diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp index bec80a7d605e..3f0600040139 100644 --- a/libs/androidfw/AssetManager2.cpp +++ b/libs/androidfw/AssetManager2.cpp @@ -157,7 +157,8 @@ void AssetManager2::BuildDynamicRefTable() { // The target package must precede the overlay package in the apk assets paths in order // to take effect. const auto& loaded_idmap = apk_assets->GetLoadedIdmap(); - auto target_package_iter = apk_assets_package_ids.find(loaded_idmap->TargetApkPath()); + auto target_package_iter = apk_assets_package_ids.find( + std::string(loaded_idmap->TargetApkPath())); if (target_package_iter == apk_assets_package_ids.end()) { LOG(INFO) << "failed to find target package for overlay " << loaded_idmap->OverlayApkPath(); diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp index a61309514143..73e040c42826 100644 --- a/libs/androidfw/Idmap.cpp +++ b/libs/androidfw/Idmap.cpp @@ -36,13 +36,51 @@ using ::android::base::StringPrintf; namespace android { -uint32_t round_to_4_bytes(uint32_t size) { - return size + (4U - (size % 4U)) % 4U; -} +// See frameworks/base/cmds/idmap2/include/idmap2/Idmap.h for full idmap file format specification. +struct Idmap_header { + // Always 0x504D4449 ('IDMP') + uint32_t magic; + uint32_t version; -size_t Idmap_header::Size() const { - return sizeof(Idmap_header) + sizeof(uint8_t) * round_to_4_bytes(dtohl(debug_info_size)); -} + uint32_t target_crc32; + uint32_t overlay_crc32; + + uint32_t fulfilled_policies; + uint32_t enforce_overlayable; + + // overlay_path, target_path, and other string values encoded in the idmap header and read and + // stored in separate structures. This allows the idmap header data to be casted to this struct + // without having to read/store each header entry separately. +}; + +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; +}; + +struct Idmap_target_entry { + uint32_t target_id; + 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; +}; OverlayStringPool::OverlayStringPool(const LoadedIdmap* loaded_idmap) : data_header_(loaded_idmap->data_header_), @@ -155,140 +193,133 @@ IdmapResMap::Result IdmapResMap::Lookup(uint32_t target_res_id) const { return {}; } -static bool is_word_aligned(const void* data) { - return (reinterpret_cast<uintptr_t>(data) & 0x03U) == 0U; -} - -static bool IsValidIdmapHeader(const StringPiece& data) { - if (!is_word_aligned(data.data())) { - LOG(ERROR) << "Idmap header is not word aligned."; - return false; +namespace { +template <typename T> +const T* ReadType(const uint8_t** in_out_data_ptr, size_t* in_out_size, const std::string& label, + size_t count = 1) { + if (!util::IsFourByteAligned(*in_out_data_ptr)) { + LOG(ERROR) << "Idmap " << label << " is not word aligned."; + return {}; } - - if (data.size() < sizeof(Idmap_header)) { - LOG(ERROR) << "Idmap header is too small."; - return false; + if ((*in_out_size / sizeof(T)) < count) { + LOG(ERROR) << "Idmap too small for the number of " << label << " entries (" + << count << ")."; + return nullptr; } + auto data_ptr = *in_out_data_ptr; + const size_t read_size = sizeof(T) * count; + *in_out_data_ptr += read_size; + *in_out_size -= read_size; + return reinterpret_cast<const T*>(data_ptr); +} - 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); - return false; +std::optional<std::string_view> ReadString(const uint8_t** in_out_data_ptr, size_t* in_out_size, + const std::string& label) { + const auto* len = ReadType<uint32_t>(in_out_data_ptr, in_out_size, label + " length"); + if (len == nullptr) { + return {}; } - - if (dtohl(header->version) != kIdmapCurrentVersion) { - // We are strict about versions because files with this format are auto-generated and don't need - // backwards compatibility. - LOG(ERROR) << StringPrintf("Version mismatch in Idmap (was 0x%08x, expected 0x%08x)", - dtohl(header->version), kIdmapCurrentVersion); - return false; + const auto* data = ReadType<char>(in_out_data_ptr, in_out_size, label, *len); + if (data == nullptr) { + return {}; } - - return true; + // Strings are padded to the next 4 byte boundary. + const uint32_t padding_size = (4U - ((size_t)*in_out_data_ptr & 0x3U)) % 4U; + for (uint32_t i = 0; i < padding_size; i++) { + if (**in_out_data_ptr != 0) { + LOG(ERROR) << " Idmap padding of " << label << " is non-zero."; + return {}; + } + *in_out_data_ptr += sizeof(uint8_t); + *in_out_size -= sizeof(uint8_t); + } + return std::string_view(data, *len); +} } LoadedIdmap::LoadedIdmap(std::string&& idmap_path, - const time_t last_mod_time, 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) + std::unique_ptr<ResStringPool>&& string_pool, + std::string_view overlay_apk_path, + std::string_view target_apk_path) : header_(header), data_header_(data_header), target_entries_(target_entries), target_inline_entries_(target_inline_entries), overlay_entries_(overlay_entries), - string_pool_(string_pool), + string_pool_(std::move(string_pool)), idmap_path_(std::move(idmap_path)), - idmap_last_mod_time_(last_mod_time) { - - size_t length = strnlen(reinterpret_cast<const char*>(header_->overlay_path), - arraysize(header_->overlay_path)); - overlay_apk_path_.assign(reinterpret_cast<const char*>(header_->overlay_path), length); - - length = strnlen(reinterpret_cast<const char*>(header_->target_path), - arraysize(header_->target_path)); - target_apk_path_.assign(reinterpret_cast<const char*>(header_->target_path), length); -} + overlay_apk_path_(overlay_apk_path), + target_apk_path_(target_apk_path), + idmap_last_mod_time_(getFileModDate(idmap_path_.data())) {} std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_path, const StringPiece& idmap_data) { ATRACE_CALL(); - if (!IsValidIdmapHeader(idmap_data)) { + size_t data_size = idmap_data.size(); + auto data_ptr = reinterpret_cast<const uint8_t*>(idmap_data.data()); + + // Parse the idmap header + auto header = ReadType<Idmap_header>(&data_ptr, &data_size, "header"); + if (header == nullptr) { return {}; } - - auto header = reinterpret_cast<const Idmap_header*>(idmap_data.data()); - const uint8_t* data_ptr = reinterpret_cast<const uint8_t*>(idmap_data.data()) + header->Size(); - size_t data_size = idmap_data.size() - header->Size(); - - // Currently idmap2 can only generate one data block. - auto data_header = reinterpret_cast<const Idmap_data_header*>(data_ptr); - data_ptr += sizeof(*data_header); - data_size -= sizeof(*data_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))) { - LOG(ERROR) << StringPrintf("Idmap too small for the number of target entries (%d)", - (int)dtohl(data_header->target_entry_count)); + if (dtohl(header->magic) != kIdmapMagic) { + LOG(ERROR) << StringPrintf("Invalid Idmap file: bad magic value (was 0x%08x, expected 0x%08x)", + dtohl(header->magic), kIdmapMagic); return {}; } - - // Advance the data pointer past the target entries. - const size_t target_entry_size_bytes = - (dtohl(data_header->target_entry_count) * sizeof(Idmap_target_entry)); - 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)); + if (dtohl(header->version) != kIdmapCurrentVersion) { + // We are strict about versions because files with this format are generated at runtime and + // don't need backwards compatibility. + LOG(ERROR) << StringPrintf("Version mismatch in Idmap (was 0x%08x, expected 0x%08x)", + dtohl(header->version), kIdmapCurrentVersion); 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) < - static_cast<size_t>(dtohl(data_header->overlay_entry_count))) { - LOG(ERROR) << StringPrintf("Idmap too small for the number of overlay entries (%d)", - (int)dtohl(data_header->overlay_entry_count)); + std::optional<std::string_view> overlay_path = ReadString(&data_ptr, &data_size, "overlay path"); + if (!overlay_path) { return {}; } - - // 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. - 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)string_pool_size); + std::optional<std::string_view> target_path = ReadString(&data_ptr, &data_size, "target path"); + if (!target_path) { + return {}; + } + if (!ReadString(&data_ptr, &data_size, "target name") || + !ReadString(&data_ptr, &data_size, "debug info")) { return {}; } + // Parse the idmap data blocks. Currently idmap2 can only generate one data block. + auto data_header = ReadType<Idmap_data_header>(&data_ptr, &data_size, "data header"); + if (data_header == nullptr) { + return {}; + } + auto target_entries = ReadType<Idmap_target_entry>(&data_ptr, &data_size, "target", + dtohl(data_header->target_entry_count)); + if (target_entries == nullptr) { + return {}; + } + auto target_inline_entries = ReadType<Idmap_target_entry_inline>( + &data_ptr, &data_size, "target inline", dtohl(data_header->target_inline_entry_count)); + if (target_inline_entries == nullptr) { + return {}; + } + auto overlay_entries = ReadType<Idmap_overlay_entry>(&data_ptr, &data_size, "target inline", + dtohl(data_header->overlay_entry_count)); + if (overlay_entries == nullptr) { + return {}; + } + std::optional<std::string_view> string_pool = ReadString(&data_ptr, &data_size, "string pool"); + if (!string_pool) { + return {}; + } auto idmap_string_pool = util::make_unique<ResStringPool>(); - if (string_pool_size > 0) { - status_t err = idmap_string_pool->setTo(data_ptr, string_pool_size); + if (!string_pool->empty()) { + const status_t err = idmap_string_pool->setTo(string_pool->data(), string_pool->size()); if (err != NO_ERROR) { LOG(ERROR) << "idmap string pool corrupt."; return {}; @@ -296,12 +327,10 @@ std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_pa } // Can't use make_unique because LoadedIdmap constructor is private. - auto loaded_idmap = std::unique_ptr<LoadedIdmap>( - new LoadedIdmap(idmap_path.to_string(), getFileModDate(idmap_path.data()), header, - data_header, target_entries, target_inline_entries, overlay_entries, - idmap_string_pool.release())); - - return std::move(loaded_idmap); + return std::unique_ptr<LoadedIdmap>( + new LoadedIdmap(idmap_path.to_string(), header, data_header, target_entries, + target_inline_entries, overlay_entries, std::move(idmap_string_pool), + *target_path, *overlay_path)); } bool LoadedIdmap::IsUpToDate() const { diff --git a/libs/androidfw/include/androidfw/Idmap.h b/libs/androidfw/include/androidfw/Idmap.h index fdab03ba2de4..fd9a8d13e0c6 100644 --- a/libs/androidfw/include/androidfw/Idmap.h +++ b/libs/androidfw/include/androidfw/Idmap.h @@ -31,6 +31,11 @@ namespace android { class LoadedIdmap; class IdmapResMap; +struct Idmap_header; +struct Idmap_data_header; +struct Idmap_target_entry; +struct Idmap_target_entry_inline; +struct Idmap_overlay_entry; // A string pool for overlay apk assets. The string pool holds the strings of the overlay resources // table and additionally allows for loading strings from the idmap string pool. The idmap string @@ -148,29 +153,29 @@ class LoadedIdmap { const StringPiece& idmap_data); // Returns the path to the IDMAP. - inline const std::string& IdmapPath() const { + std::string_view IdmapPath() const { return idmap_path_; } // Returns the path to the RRO (Runtime Resource Overlay) APK for which this IDMAP was generated. - inline const std::string& OverlayApkPath() const { + std::string_view OverlayApkPath() const { return overlay_apk_path_; } // Returns the path to the RRO (Runtime Resource Overlay) APK for which this IDMAP was generated. - inline const std::string& TargetApkPath() const { + std::string_view TargetApkPath() const { return target_apk_path_; } // Returns a mapping from target resource ids to overlay values. - inline const IdmapResMap GetTargetResourcesMap( + const IdmapResMap GetTargetResourcesMap( uint8_t target_assigned_package_id, const OverlayDynamicRefTable* overlay_ref_table) const { 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. - inline const OverlayDynamicRefTable GetOverlayDynamicRefTable( + const OverlayDynamicRefTable GetOverlayDynamicRefTable( uint8_t target_assigned_package_id) const { return OverlayDynamicRefTable(data_header_, overlay_entries_, target_assigned_package_id); } @@ -190,22 +195,23 @@ class LoadedIdmap { const Idmap_overlay_entry* overlay_entries_; const std::unique_ptr<ResStringPool> string_pool_; - const std::string idmap_path_; - std::string overlay_apk_path_; - std::string target_apk_path_; - const time_t idmap_last_mod_time_; + std::string idmap_path_; + std::string_view overlay_apk_path_; + std::string_view target_apk_path_; + time_t idmap_last_mod_time_; private: DISALLOW_COPY_AND_ASSIGN(LoadedIdmap); explicit LoadedIdmap(std::string&& idmap_path, - time_t last_mod_time, 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); + std::unique_ptr<ResStringPool>&& string_pool, + std::string_view overlay_apk_path, + std::string_view target_apk_path); friend OverlayStringPool; }; diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h index fb5f86473189..bfd564c258ee 100644 --- a/libs/androidfw/include/androidfw/ResourceTypes.h +++ b/libs/androidfw/include/androidfw/ResourceTypes.h @@ -44,7 +44,7 @@ namespace android { constexpr const static uint32_t kIdmapMagic = 0x504D4449u; -constexpr const static uint32_t kIdmapCurrentVersion = 0x00000005u; +constexpr const static uint32_t kIdmapCurrentVersion = 0x00000007u; /** * In C++11, char16_t is defined as *at least* 16 bits. We do a lot of @@ -1700,56 +1700,6 @@ inline ResTable_overlayable_policy_header::PolicyFlags& operator |=( return first; } -struct Idmap_header { - // Always 0x504D4449 ('IDMP') - uint32_t magic; - - uint32_t version; - - uint32_t target_crc32; - uint32_t overlay_crc32; - - uint32_t fulfilled_policies; - uint32_t enforce_overlayable; - - uint8_t target_path[256]; - uint8_t overlay_path[256]; - - uint32_t debug_info_size; - uint8_t debug_info[0]; - - size_t Size() const; -}; - -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; -}; - -struct Idmap_target_entry { - uint32_t target_id; - 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; -}; - class AssetManager2; /** diff --git a/libs/androidfw/include/androidfw/Util.h b/libs/androidfw/include/androidfw/Util.h index aceeeccccb61..c59b5b6c51a2 100644 --- a/libs/androidfw/include/androidfw/Util.h +++ b/libs/androidfw/include/androidfw/Util.h @@ -128,10 +128,14 @@ std::string Utf16ToUtf8(const StringPiece16& utf16); std::vector<std::string> SplitAndLowercase(const android::StringPiece& str, char sep); template <typename T> -bool IsFourByteAligned(const incfs::map_ptr<T>& data) { +inline bool IsFourByteAligned(const incfs::map_ptr<T>& data) { return ((size_t)data.unsafe_ptr() & 0x3U) == 0; } +inline bool IsFourByteAligned(const void* data) { + return ((size_t)data & 0x3U) == 0; +} + } // namespace util } // namespace android diff --git a/libs/androidfw/tests/data/app/app.apk b/libs/androidfw/tests/data/app/app.apk Binary files differindex c8ad86ded851..67036959d185 100644 --- a/libs/androidfw/tests/data/app/app.apk +++ b/libs/androidfw/tests/data/app/app.apk diff --git a/libs/androidfw/tests/data/overlay/overlay.idmap b/libs/androidfw/tests/data/overlay/overlay.idmap Binary files differindex 3ab244eb084a..723413c3cea8 100644 --- a/libs/androidfw/tests/data/overlay/overlay.idmap +++ b/libs/androidfw/tests/data/overlay/overlay.idmap |