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:
Ryan Mitchell
2020-12-02 11:43:18 -08:00
parent 0699f1de6a
commit 30dc2e0171
53 changed files with 566 additions and 786 deletions

View File

@@ -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");
}

View File

@@ -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_

View File

@@ -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");
}

View File

@@ -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;

View File

@@ -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());

View File

@@ -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());
}

View File

@@ -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_;
}

View File

@@ -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);

View File

@@ -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());
}

View File

@@ -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();

View File

@@ -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);

View File

@@ -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());

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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();

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

Binary file not shown.

View File

@@ -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>

View 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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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 {};
}

View File

@@ -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