Accept --overlay-name flag in idmap2
To support allowing for multiple <overlay> tags in one package, idmap2 must be able to generate an idmap for an individual <overlay> tag. `idmap2 create` now accepts a --overlay-name flag that specifies which tag to use to generate the idmap. The value of --overlay-name should be set to the value of the android:name attribute on the <overlay> tag to use. If the flag is not present, idmap2 will look for an <overlay> tag with no value for android:name. Bug: 162841629 Test: libandroidfw_tests Test: libidmap2_tests Change-Id: I02316d0b88773f02c04a5d462be9825016fa496d
This commit is contained in:
@@ -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,8 +39,8 @@ 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, overlay_path, fulfilled_policies, enforce_overlayable);
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -195,12 +195,12 @@ Result<Unit> Lookup(const std::vector<std::string>& args) {
|
||||
}
|
||||
apk_assets.push_back(std::move(target_apk));
|
||||
|
||||
auto manifest_info =
|
||||
ExtractOverlayManifestInfo(idmap_header->GetOverlayPath(), 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().c_str());
|
||||
|
||||
@@ -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 overlay_apk_path, 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());
|
||||
}
|
||||
|
||||
@@ -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,6 +38,7 @@
|
||||
* overlay_entry_count := <uint32_t>
|
||||
* overlay_id := <uint32_t>
|
||||
* overlay_package_id := <uint8_t>
|
||||
* overlay_name := string
|
||||
* overlay_path := string
|
||||
* padding(n) := <uint8_t>[n]
|
||||
* Res_value::size := <uint16_t>
|
||||
@@ -77,9 +79,6 @@ 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;
|
||||
|
||||
@@ -125,6 +124,10 @@ class IdmapHeader {
|
||||
return overlay_path_;
|
||||
}
|
||||
|
||||
const std::string& GetOverlayName() const {
|
||||
return overlay_name_;
|
||||
}
|
||||
|
||||
const std::string& GetDebugInfo() const {
|
||||
return debug_info_;
|
||||
}
|
||||
@@ -133,16 +136,18 @@ class IdmapHeader {
|
||||
// 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 std::string& target_path, const std::string& overlay_path,
|
||||
PolicyBitmask fulfilled_policies, bool enforce_overlayable) const;
|
||||
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,
|
||||
uint32_t target_crc, uint32_t overlay_crc,
|
||||
PolicyBitmask fulfilled_policies, bool enforce_overlayable) const;
|
||||
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_;
|
||||
@@ -152,6 +157,7 @@ class IdmapHeader {
|
||||
bool enforce_overlayable_;
|
||||
std::string target_path_;
|
||||
std::string overlay_path_;
|
||||
std::string overlay_name_;
|
||||
std::string debug_info_;
|
||||
|
||||
friend Idmap;
|
||||
@@ -246,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_;
|
||||
@@ -272,14 +277,15 @@ 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_;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ void BinaryStreamVisitor::visit(const IdmapHeader& header) {
|
||||
Write32(static_cast<uint8_t>(header.GetEnforceOverlayable()));
|
||||
WriteString(header.GetTargetPath());
|
||||
WriteString(header.GetOverlayPath());
|
||||
WriteString(header.GetOverlayName());
|
||||
WriteString(header.GetDebugInfo());
|
||||
}
|
||||
|
||||
|
||||
@@ -109,6 +109,7 @@ std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& s
|
||||
!Read32(stream, &idmap_header->fulfilled_policies_) ||
|
||||
!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;
|
||||
}
|
||||
@@ -119,6 +120,7 @@ std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& s
|
||||
|
||||
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);
|
||||
@@ -141,12 +143,13 @@ Result<Unit> IdmapHeader::IsUpToDate(const std::string& target_path,
|
||||
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 std::string& target_path,
|
||||
const std::string& overlay_path, uint32_t target_crc,
|
||||
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) {
|
||||
@@ -187,6 +190,11 @@ Result<Unit> IdmapHeader::IsUpToDate(const std::string& target_path,
|
||||
overlay_path_.c_str());
|
||||
}
|
||||
|
||||
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{};
|
||||
}
|
||||
|
||||
@@ -317,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";
|
||||
@@ -352,15 +361,16 @@ Result<std::unique_ptr<const Idmap>> Idmap::FromApkAssets(const ApkAssets& targe
|
||||
header->enforce_overlayable_ = enforce_overlayable;
|
||||
header->target_path_ = target_apk_path;
|
||||
header->overlay_path_ = overlay_apk_path;
|
||||
header->overlay_name_ = overlay_name;
|
||||
|
||||
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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -45,6 +45,7 @@ void RawPrintVisitor::visit(const IdmapHeader& header) {
|
||||
print(static_cast<uint32_t>(header.GetEnforceOverlayable()), "enforce overlayable");
|
||||
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");
|
||||
|
||||
auto target_apk_ = ApkAssets::Load(header.GetTargetPath());
|
||||
|
||||
@@ -92,7 +92,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 +113,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());
|
||||
}
|
||||
OverlayManifestInfo info{};
|
||||
if (auto result_str = it.GetAttributeStringValue("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_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;
|
||||
if (auto result_str = it.GetAttributeStringValue("targetPackage")) {
|
||||
info.target_package = *result_str;
|
||||
} else {
|
||||
return Error("android:resourcesMap is not a reference 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("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;
|
||||
} else {
|
||||
return Error("android:isStatic is not a boolean in AndroidManifest.xml of %s", path.c_str());
|
||||
if (auto result_str = it.GetAttributeStringValue("targetName")) {
|
||||
info.target_name = *result_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_value = 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());
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
if (auto result_str = overlay_it->GetAttributeStringValue("requiredSystemPropertyName")) {
|
||||
info.requiredSystemPropertyName = *result_str;
|
||||
}
|
||||
|
||||
if (auto result_str = overlay_it->GetAttributeStringValue("requiredSystemPropertyValue")) {
|
||||
info.requiredSystemPropertyValue = *result_str;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
@@ -60,12 +61,12 @@ 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(), 0x06U);
|
||||
ASSERT_EQ(header->GetVersion(), 0x07U);
|
||||
ASSERT_EQ(header->GetTargetCrc(), 0x1234U);
|
||||
ASSERT_EQ(header->GetOverlayCrc(), 0x5678U);
|
||||
ASSERT_EQ(header->GetFulfilledPolicies(), 0x11);
|
||||
@@ -76,9 +77,9 @@ TEST(IdmapTests, CreateIdmapHeaderFromBinaryStream) {
|
||||
}
|
||||
|
||||
TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) {
|
||||
const size_t offset = idmap_raw_data_offset;
|
||||
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);
|
||||
@@ -88,9 +89,9 @@ TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) {
|
||||
}
|
||||
|
||||
TEST(IdmapTests, CreateIdmapDataFromBinaryStream) {
|
||||
const size_t offset = idmap_raw_data_offset;
|
||||
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);
|
||||
@@ -115,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);
|
||||
@@ -124,13 +125,14 @@ TEST(IdmapTests, CreateIdmapFromBinaryStream) {
|
||||
|
||||
ASSERT_THAT(idmap->GetHeader(), NotNull());
|
||||
ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
|
||||
ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x06U);
|
||||
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(), idmap_raw_data_target_path);
|
||||
ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), idmap_raw_data_overlay_path);
|
||||
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);
|
||||
@@ -175,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(), 0x06U);
|
||||
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(), 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) {
|
||||
@@ -229,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;
|
||||
@@ -259,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";
|
||||
@@ -269,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;
|
||||
@@ -284,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;
|
||||
@@ -331,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();
|
||||
@@ -345,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,
|
||||
@@ -361,13 +392,14 @@ TEST(IdmapTests, CreateIdmapDataInlineResources) {
|
||||
TEST(IdmapTests, IdmapHeaderIsUpToDate) {
|
||||
fclose(stderr); // silence expected warnings from libandroidfw
|
||||
|
||||
const std::string target_apk_path = idmap_raw_data_target_path;
|
||||
const std::string overlay_apk_path = idmap_raw_data_overlay_path;
|
||||
const PolicyBitmask policies = idmap_raw_data_policies;
|
||||
const uint32_t target_crc = idmap_raw_data_target_crc;
|
||||
const uint32_t overlay_crc = idmap_raw_data_overlay_crc;
|
||||
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;
|
||||
|
||||
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 result = Idmap::FromBinaryStream(raw_stream);
|
||||
@@ -380,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, overlay_apk_path, idmap_raw_data_target_crc,
|
||||
overlay_crc, policies, /* 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());
|
||||
@@ -394,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, overlay_apk_path, target_crc,
|
||||
overlay_crc, policies, /* 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());
|
||||
@@ -408,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, overlay_apk_path, target_crc,
|
||||
overlay_crc, policies, /* 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());
|
||||
@@ -422,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, overlay_apk_path, target_crc,
|
||||
overlay_crc, policies, /* 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());
|
||||
@@ -436,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, overlay_apk_path, target_crc,
|
||||
overlay_crc, policies, /* 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());
|
||||
@@ -450,8 +487,8 @@ 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, overlay_apk_path, target_crc,
|
||||
overlay_crc, policies,
|
||||
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)
|
||||
@@ -462,8 +499,8 @@ 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, overlay_apk_path, target_crc,
|
||||
overlay_crc, policies,
|
||||
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 (0x1c, 0x27)
|
||||
@@ -474,8 +511,9 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) {
|
||||
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, overlay_apk_path, target_crc,
|
||||
overlay_crc, policies, /* 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 (0x2c, 0x37)
|
||||
std::string bad_overlay_path_string(stream.str());
|
||||
@@ -485,9 +523,23 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) {
|
||||
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_overlay_path_header->IsUpToDate(target_apk_path, overlay_apk_path, target_crc,
|
||||
overlay_crc, policies,
|
||||
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 {
|
||||
@@ -516,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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
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::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;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -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 "00000006 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("000001bc: ........ 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 "00000006 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("00000098: ........ string pool\n", stream.str());
|
||||
ASSERT_CONTAINS_REGEX("000000a8: ........ string pool\n", stream.str());
|
||||
}
|
||||
|
||||
} // namespace android::idmap2
|
||||
|
||||
@@ -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,8 @@ 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);
|
||||
|
||||
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 */));
|
||||
ASSERT_RESULT(MappingExists(res, R::target::string::policy_system,
|
||||
R::system_overlay::string::policy_system, false /* rewrite */));
|
||||
ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor,
|
||||
R::system_overlay::string::policy_system_vendor,
|
||||
false /* 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 +199,38 @@ 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 fulfill must not map to overlay resources.
|
||||
TEST(ResourceMappingTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) {
|
||||
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::overlay::string::policy_public, true /* rewrite */));
|
||||
ASSERT_RESULT(MappingExists(res, R::target::string::policy_system,
|
||||
R::overlay::string::policy_system, true /* rewrite */));
|
||||
ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor,
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ const unsigned char idmap_raw_data[] = {
|
||||
0x49, 0x44, 0x4d, 0x50,
|
||||
|
||||
// 0x4: version
|
||||
0x06, 0x00, 0x00, 0x00,
|
||||
0x07, 0x00, 0x00, 0x00,
|
||||
|
||||
// 0x8: target crc
|
||||
0x34, 0x12, 0x00, 0x00,
|
||||
@@ -56,95 +56,102 @@ const unsigned char idmap_raw_data[] = {
|
||||
// 0x2c: overlay path "overlayX.apk"
|
||||
0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x58, 0x2e, 0x61, 0x70, 0x6b,
|
||||
|
||||
// 0x38: debug string
|
||||
// 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,
|
||||
|
||||
// 0x3c 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
|
||||
// 0x44: target_package_id
|
||||
// 0x54: target_package_id
|
||||
0x7f,
|
||||
|
||||
// 0x45: overlay_package_id
|
||||
// 0x55: overlay_package_id
|
||||
0x7f,
|
||||
|
||||
// 0x46: padding
|
||||
// 0x56: padding
|
||||
0x00, 0x00,
|
||||
|
||||
// 0x48: target_entry_count
|
||||
// 0x58: target_entry_count
|
||||
0x03, 0x00, 0x00, 0x00,
|
||||
|
||||
// 0x4c: target_inline_entry_count
|
||||
// 0x5c: target_inline_entry_count
|
||||
0x01, 0x00, 0x00, 0x00,
|
||||
|
||||
// 0x50: overlay_entry_count
|
||||
// 0x60: overlay_entry_count
|
||||
0x03, 0x00, 0x00, 0x00,
|
||||
|
||||
// 0x54: string_pool_offset
|
||||
// 0x64: string_pool_offset
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
// TARGET ENTRIES
|
||||
// 0x58: target id (0x7f020000)
|
||||
// 0x68: target id (0x7f020000)
|
||||
0x00, 0x00, 0x02, 0x7f,
|
||||
|
||||
// 0x5c: overlay_id (0x7f020000)
|
||||
// 0x6c: overlay_id (0x7f020000)
|
||||
0x00, 0x00, 0x02, 0x7f,
|
||||
|
||||
// 0x60: target id (0x7f030000)
|
||||
// 0x70: target id (0x7f030000)
|
||||
0x00, 0x00, 0x03, 0x7f,
|
||||
|
||||
// 0x64: overlay_id (0x7f030000)
|
||||
// 0x74: overlay_id (0x7f030000)
|
||||
0x00, 0x00, 0x03, 0x7f,
|
||||
|
||||
// 0x68: target id (0x7f030002)
|
||||
// 0x78: target id (0x7f030002)
|
||||
0x02, 0x00, 0x03, 0x7f,
|
||||
|
||||
// 0x6c: overlay_id (0x7f030001)
|
||||
// 0x7c: overlay_id (0x7f030001)
|
||||
0x01, 0x00, 0x03, 0x7f,
|
||||
|
||||
// INLINE TARGET ENTRIES
|
||||
|
||||
// 0x70: target_id
|
||||
// 0x80: target_id
|
||||
0x00, 0x00, 0x04, 0x7f,
|
||||
|
||||
// 0x74: Res_value::size (value ignored by idmap)
|
||||
// 0x84: Res_value::size (value ignored by idmap)
|
||||
0x08, 0x00,
|
||||
|
||||
// 0x77: Res_value::res0 (value ignored by idmap)
|
||||
// 0x87: Res_value::res0 (value ignored by idmap)
|
||||
0x00,
|
||||
|
||||
// 0x78: Res_value::dataType (TYPE_INT_HEX)
|
||||
// 0x88: Res_value::dataType (TYPE_INT_HEX)
|
||||
0x11,
|
||||
|
||||
// 0x7c: Res_value::data
|
||||
// 0x8c: Res_value::data
|
||||
0x78, 0x56, 0x34, 0x12,
|
||||
|
||||
// OVERLAY ENTRIES
|
||||
// 0x80: 0x7f020000 -> 0x7f020000
|
||||
// 0x90: 0x7f020000 -> 0x7f020000
|
||||
0x00, 0x00, 0x02, 0x7f, 0x00, 0x00, 0x02, 0x7f,
|
||||
|
||||
// 0x88: 0x7f030000 -> 0x7f030000
|
||||
// 0x98: 0x7f030000 -> 0x7f030000
|
||||
0x00, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x03, 0x7f,
|
||||
|
||||
// 0x90: 0x7f030001 -> 0x7f030002
|
||||
// 0xa0: 0x7f030001 -> 0x7f030002
|
||||
0x01, 0x00, 0x03, 0x7f, 0x02, 0x00, 0x03, 0x7f,
|
||||
|
||||
// 0x94: string pool
|
||||
// 0xa4: string pool
|
||||
// string length,
|
||||
0x04, 0x00, 0x00, 0x00,
|
||||
|
||||
// 0x98 string contents "test"
|
||||
// 0xa8 string contents "test"
|
||||
0x74, 0x65, 0x73, 0x74};
|
||||
|
||||
const unsigned int idmap_raw_data_len = 0x9c;
|
||||
const unsigned int idmap_raw_data_offset = 0x44;
|
||||
const unsigned int idmap_raw_data_target_crc = 0x1234;
|
||||
const unsigned int idmap_raw_data_overlay_crc = 0x5678;
|
||||
const unsigned int idmap_raw_data_policies = 0x11;
|
||||
inline const std::string idmap_raw_data_target_path = "targetX.apk";
|
||||
inline const std::string idmap_raw_data_overlay_path = "overlayX.apk";
|
||||
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();
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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.static1">
|
||||
<overlay
|
||||
android:targetPackage="test.target"
|
||||
android:targetName="TestResources"
|
||||
android:isStatic="true"
|
||||
android:priority="1" />
|
||||
</manifest>
|
||||
@@ -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>
|
||||
@@ -26,37 +26,16 @@ 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 \
|
||||
compiled.flata
|
||||
|
||||
aapt2 link \
|
||||
--no-resource-removal \
|
||||
-I "$FRAMEWORK_RES_APK" \
|
||||
--manifest AndroidManifestStatic2.xml \
|
||||
-o overlay-static-2.apk \
|
||||
compiled.flata
|
||||
|
||||
aapt2 link \
|
||||
--no-resource-removal \
|
||||
--shared-lib \
|
||||
-I "$FRAMEWORK_RES_APK" \
|
||||
--manifest AndroidManifest.xml \
|
||||
-o overlay-shared.apk \
|
||||
--shared-lib \
|
||||
compiled.flata
|
||||
|
||||
aapt2 link \
|
||||
--no-resource-removal \
|
||||
-I "$FRAMEWORK_RES_APK" \
|
||||
--manifest AndroidManifestLegacy.xml \
|
||||
-o overlay-legacy.apk \
|
||||
compiled.flata
|
||||
|
||||
rm compiled.flata
|
||||
|
||||
BIN
cmds/idmap2/tests/data/overlay/overlay-legacy.apk
Normal file
BIN
cmds/idmap2/tests/data/overlay/overlay-legacy.apk
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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>
|
||||
|
||||
33
cmds/idmap2/tests/data/overlay/res/xml/overlays_policies.xml
Normal file
33
cmds/idmap2/tests/data/overlay/res/xml/overlays_policies.xml
Normal file
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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>
|
||||
Binary file not shown.
@@ -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>
|
||||
@@ -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
|
||||
@@ -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>
|
||||
Binary file not shown.
@@ -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
|
||||
@@ -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>
|
||||
Binary file not shown.
@@ -288,7 +288,8 @@ std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_pa
|
||||
if (!target_path) {
|
||||
return {};
|
||||
}
|
||||
if (!ReadString(&data_ptr, &data_size, "debug info")) {
|
||||
if (!ReadString(&data_ptr, &data_size, "target name") ||
|
||||
!ReadString(&data_ptr, &data_size, "debug info")) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
namespace android {
|
||||
|
||||
constexpr const static uint32_t kIdmapMagic = 0x504D4449u;
|
||||
constexpr const static uint32_t kIdmapCurrentVersion = 0x00000006u;
|
||||
constexpr const static uint32_t kIdmapCurrentVersion = 0x00000007u;
|
||||
|
||||
/**
|
||||
* In C++11, char16_t is defined as *at least* 16 bits. We do a lot of
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user