From 42fe2b2ac7debe61bfa8b63ef3bb41b774f12cdf Mon Sep 17 00:00:00 2001 From: Donald Chai Date: Tue, 7 May 2019 20:03:27 -0700 Subject: [aapt2] Close empty lists in "dump resources". Bug: 129134933 Test: manual (b/129134933#comment4) since there's no Debug_test.cpp Change-Id: Ib31481457089eade6f1d380cff4eeba0ff0c499d --- tools/aapt2/Debug.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'tools/aapt2/Debug.cpp') diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp index 98324850f3f5..fbe147206d9c 100644 --- a/tools/aapt2/Debug.cpp +++ b/tools/aapt2/Debug.cpp @@ -170,19 +170,17 @@ class ValueBodyPrinter : public ConstValueVisitor { void Visit(const Array* array) override { const size_t count = array->elements.size(); printer_->Print("["); - if (count > 0) { - for (size_t i = 0u; i < count; i++) { - if (i != 0u && i % 4u == 0u) { - printer_->Println(); - printer_->Print(" "); - } - PrintItem(*array->elements[i]); - if (i != count - 1) { - printer_->Print(", "); - } + for (size_t i = 0u; i < count; i++) { + if (i != 0u && i % 4u == 0u) { + printer_->Println(); + printer_->Print(" "); + } + PrintItem(*array->elements[i]); + if (i != count - 1) { + printer_->Print(", "); } - printer_->Println("]"); } + printer_->Println("]"); } void Visit(const Plural* plural) override { -- cgit v1.2.3-59-g8ed1b From 1d3b64855b0d4178d6d8cb7beba9156a39caecfa Mon Sep 17 00:00:00 2001 From: MÃ¥rten Kongstad Date: Tue, 17 Sep 2019 13:02:32 +0200 Subject: aapt2: add 'dump overlayable' command Add a command to print a resource table's resources. Given the following input aapt2 dump overlayable will produce name="TestResources" actor="" policies="system" string/a policies="system|vendor" string/b string/c Bug: 120609160 Test: manual (aapt2 dump overlayable $(gettop)/frameworks/base/cmds/idmap2/tests/data/target/target.apk) Change-Id: I21041e6169c62d01f1a469624911ce7cad3e18a8 --- tools/aapt2/Debug.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ tools/aapt2/Debug.h | 1 + tools/aapt2/cmd/Dump.cpp | 11 ++++++ tools/aapt2/cmd/Dump.h | 12 ++++++- 4 files changed, 115 insertions(+), 1 deletion(-) (limited to 'tools/aapt2/Debug.cpp') diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp index 7ffa5ffc09fe..137fbd671865 100644 --- a/tools/aapt2/Debug.cpp +++ b/tools/aapt2/Debug.cpp @@ -246,6 +246,36 @@ class ValueBodyPrinter : public ConstValueVisitor { Printer* printer_; }; +std::string OverlayablePoliciesToString(OverlayableItem::PolicyFlags policies) { + static const std::map kFlagToString = { + {OverlayableItem::kPublic, "public"}, + {OverlayableItem::kSystem, "system"}, + {OverlayableItem::kVendor, "vendor"}, + {OverlayableItem::kProduct, "product"}, + {OverlayableItem::kSignature, "signature"}, + {OverlayableItem::kOdm, "odm"}, + {OverlayableItem::kOem, "oem"}, + }; + std::string str; + for (auto const& policy : kFlagToString) { + if ((policies & policy.first) != policy.first) { + continue; + } + if (!str.empty()) { + str.append("|"); + } + str.append(policy.second); + policies &= ~policy.first; + } + if (policies != 0) { + if (!str.empty()) { + str.append("|"); + } + str.append(StringPrintf("0x%08x", policies)); + } + return !str.empty() ? str : "none"; +} + } // namespace void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions& options, @@ -312,6 +342,10 @@ void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions& break; } + if (entry->overlayable_item) { + printer->Print(" OVERLAYABLE"); + } + printer->Println(); if (options.show_values) { @@ -525,4 +559,62 @@ void Debug::DumpXml(const xml::XmlResource& doc, Printer* printer) { doc.root->Accept(&xml_visitor); } +struct DumpOverlayableEntry { + std::string overlayable_section; + std::string policy_subsection; + std::string resource_name; +}; + +void Debug::DumpOverlayable(const ResourceTable& table, text::Printer* printer) { + std::vector items; + for (const auto& package : table.packages) { + for (const auto& type : package->types) { + for (const auto& entry : type->entries) { + if (entry->overlayable_item) { + const auto& overlayable_item = entry->overlayable_item.value(); + const auto overlayable_section = StringPrintf(R"(name="%s" actor="%s")", + overlayable_item.overlayable->name.c_str(), + overlayable_item.overlayable->actor.c_str()); + const auto policy_subsection = StringPrintf(R"(policies="%s")", + OverlayablePoliciesToString(overlayable_item.policies).c_str()); + const auto value = + StringPrintf("%s/%s", to_string(type->type).data(), entry->name.c_str()); + items.push_back(DumpOverlayableEntry{overlayable_section, policy_subsection, value}); + } + } + } + } + + std::sort(items.begin(), items.end(), + [](const DumpOverlayableEntry& a, const DumpOverlayableEntry& b) { + if (a.overlayable_section != b.overlayable_section) { + return a.overlayable_section < b.overlayable_section; + } + if (a.policy_subsection != b.policy_subsection) { + return a.policy_subsection < b.policy_subsection; + } + return a.resource_name < b.resource_name; + }); + + std::string last_overlayable_section; + std::string last_policy_subsection; + for (const auto& item : items) { + if (last_overlayable_section != item.overlayable_section) { + printer->Println(item.overlayable_section); + last_overlayable_section = item.overlayable_section; + } + if (last_policy_subsection != item.policy_subsection) { + printer->Indent(); + printer->Println(item.policy_subsection); + last_policy_subsection = item.policy_subsection; + printer->Undent(); + } + printer->Indent(); + printer->Indent(); + printer->Println(item.resource_name); + printer->Undent(); + printer->Undent(); + } +} + } // namespace aapt diff --git a/tools/aapt2/Debug.h b/tools/aapt2/Debug.h index a43197cacf7b..9443d606d7e5 100644 --- a/tools/aapt2/Debug.h +++ b/tools/aapt2/Debug.h @@ -39,6 +39,7 @@ struct Debug { static void DumpHex(const void* data, size_t len); static void DumpXml(const xml::XmlResource& doc, text::Printer* printer); static void DumpResStringPool(const android::ResStringPool* pool, text::Printer* printer); + static void DumpOverlayable(const ResourceTable& table, text::Printer* printer); }; } // namespace aapt diff --git a/tools/aapt2/cmd/Dump.cpp b/tools/aapt2/cmd/Dump.cpp index 429aff1ff594..3982d12f6036 100644 --- a/tools/aapt2/cmd/Dump.cpp +++ b/tools/aapt2/cmd/Dump.cpp @@ -394,6 +394,17 @@ int DumpXmlTreeCommand::Dump(LoadedApk* apk) { return 0; } +int DumpOverlayableCommand::Dump(LoadedApk* apk) { + ResourceTable* table = apk->GetResourceTable(); + if (!table) { + GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table"); + return 1; + } + + Debug::DumpOverlayable(*table, GetPrinter()); + return 0; +} + const char DumpBadgerCommand::kBadgerData[2925] = { 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, diff --git a/tools/aapt2/cmd/Dump.h b/tools/aapt2/cmd/Dump.h index 7ded9bcf8470..cd51f7a7718c 100644 --- a/tools/aapt2/cmd/Dump.h +++ b/tools/aapt2/cmd/Dump.h @@ -240,6 +240,16 @@ class DumpXmlTreeCommand : public DumpApkCommand { std::vector files_; }; +class DumpOverlayableCommand : public DumpApkCommand { + public: + explicit DumpOverlayableCommand(text::Printer* printer, IDiagnostics* diag) + : DumpApkCommand("overlayable", printer, diag) { + SetDescription("Print the resources of an APK."); + } + + int Dump(LoadedApk* apk) override; +}; + /** The default dump command. Performs no action because a subcommand is required. */ class DumpCommand : public Command { public: @@ -255,8 +265,8 @@ class DumpCommand : public Command { AddOptionalSubcommand(util::make_unique(printer, diag_)); AddOptionalSubcommand(util::make_unique(printer, diag_)); AddOptionalSubcommand(util::make_unique(printer, diag_)); + AddOptionalSubcommand(util::make_unique(printer, diag_)); AddOptionalSubcommand(util::make_unique(printer), /* hidden */ true); - // TODO(b/120609160): Add aapt2 overlayable dump command } int Action(const std::vector& args) override { -- cgit v1.2.3-59-g8ed1b From 62ac8b56a9f7cf75f3f0677ec37d8acb8def475c Mon Sep 17 00:00:00 2001 From: Winson Date: Wed, 4 Dec 2019 08:36:48 -0800 Subject: Refactor overlayable policy To make it easier to add the actor policy in a follow up CL, move most of the policy handling to a central location. The strings and transformation between strings and flags is now handled in libidmap2policies, with libandroidfw containing the single source of policy flags. This also extracts all the test resource IDs into an R.h so they can be swapped without having to edit a dozen files each time. Bug: 130563563 Test: m aapt2_tests idmapt2_tests and run from host test output Test: atest libandroidfw_tests Change-Id: Ie533c9cebf938215df7586f00c38763ae467e606 --- cmds/idmap2/Android.bp | 64 ++++-- cmds/idmap2/idmap2/Create.cpp | 16 +- cmds/idmap2/idmap2/CreateMultiple.cpp | 11 +- cmds/idmap2/idmap2/Scan.cpp | 18 +- cmds/idmap2/idmap2d/Idmap2Service.cpp | 4 +- cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl | 8 - .../idmap2d/aidl/android/os/OverlayablePolicy.aidl | 31 +++ cmds/idmap2/include/idmap2/Idmap.h | 1 - cmds/idmap2/include/idmap2/Policies.h | 48 ----- cmds/idmap2/include/idmap2/PolicyUtils.h | 41 ++++ cmds/idmap2/include/idmap2/ResourceMapping.h | 2 + cmds/idmap2/libidmap2/Policies.cpp | 88 -------- cmds/idmap2/libidmap2/PolicyUtils.cpp | 61 ++++++ cmds/idmap2/libidmap2/ResourceMapping.cpp | 10 +- .../libidmap2_policies/include/idmap2/Policies.h | 51 +++++ cmds/idmap2/tests/Idmap2BinaryTests.cpp | 15 +- cmds/idmap2/tests/IdmapTests.cpp | 60 +++--- cmds/idmap2/tests/PoliciesTests.cpp | 66 +++--- cmds/idmap2/tests/PrettyPrintVisitorTests.cpp | 12 +- cmds/idmap2/tests/R.h | 94 +++++++++ cmds/idmap2/tests/RawPrintVisitorTests.cpp | 16 +- cmds/idmap2/tests/ResourceMappingTests.cpp | 225 +++++++++++---------- cmds/idmap2/tests/TestConstants.h | 30 +++ libs/androidfw/Android.bp | 1 - libs/androidfw/include/androidfw/ResourceTypes.h | 41 +++- libs/androidfw/tests/LoadedArsc_test.cpp | 14 +- services/core/Android.bp | 2 + .../java/com/android/server/om/IdmapManager.java | 16 +- tools/aapt2/Android.bp | 1 + tools/aapt2/Debug.cpp | 31 ++- tools/aapt2/ResourceParser.cpp | 31 ++- tools/aapt2/ResourceParser_test.cpp | 28 +-- tools/aapt2/ResourceTable.h | 32 +-- tools/aapt2/ResourceTable_test.cpp | 20 +- tools/aapt2/format/binary/BinaryResourceParser.cpp | 31 +-- tools/aapt2/format/binary/TableFlattener.cpp | 32 +-- tools/aapt2/format/binary/TableFlattener_test.cpp | 66 +++--- tools/aapt2/format/proto/ProtoDeserialize.cpp | 16 +- tools/aapt2/format/proto/ProtoSerialize.cpp | 16 +- tools/aapt2/format/proto/ProtoSerialize_test.cpp | 38 ++-- tools/aapt2/link/TableMerger_test.cpp | 34 ++-- 41 files changed, 818 insertions(+), 604 deletions(-) create mode 100644 cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl delete mode 100644 cmds/idmap2/include/idmap2/Policies.h create mode 100644 cmds/idmap2/include/idmap2/PolicyUtils.h delete mode 100644 cmds/idmap2/libidmap2/Policies.cpp create mode 100644 cmds/idmap2/libidmap2/PolicyUtils.cpp create mode 100644 cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h create mode 100644 cmds/idmap2/tests/R.h create mode 100644 cmds/idmap2/tests/TestConstants.h (limited to 'tools/aapt2/Debug.cpp') diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp index 66f5c3908e4b..645dc935fc07 100644 --- a/cmds/idmap2/Android.bp +++ b/cmds/idmap2/Android.bp @@ -36,18 +36,7 @@ cc_library { ], host_supported: true, srcs: [ - "libidmap2/BinaryStreamVisitor.cpp", - "libidmap2/CommandLineOptions.cpp", - "libidmap2/FileUtils.cpp", - "libidmap2/Idmap.cpp", - "libidmap2/Policies.cpp", - "libidmap2/PrettyPrintVisitor.cpp", - "libidmap2/RawPrintVisitor.cpp", - "libidmap2/ResourceMapping.cpp", - "libidmap2/ResourceUtils.cpp", - "libidmap2/Result.cpp", - "libidmap2/XmlParser.cpp", - "libidmap2/ZipFile.cpp", + "libidmap2/**/*.cpp", ], export_include_dirs: ["include"], target: { @@ -61,6 +50,7 @@ cc_library { "libcutils", "libutils", "libziparchive", + "libidmap2_policies", ], }, host: { @@ -73,6 +63,37 @@ cc_library { "libcutils", "libutils", "libziparchive", + "libidmap2_policies", + ], + }, + }, +} + +cc_library { + name: "libidmap2_policies", + defaults: [ + "idmap2_defaults", + ], + host_supported: true, + export_include_dirs: ["libidmap2_policies/include"], + target: { + windows: { + enabled: true, + }, + android: { + static: { + enabled: false, + }, + shared_libs: [ + "libandroidfw", + ], + }, + host: { + shared: { + enabled: false, + }, + static_libs: [ + "libandroidfw", ], }, }, @@ -118,6 +139,7 @@ cc_test { "libutils", "libz", "libziparchive", + "libidmap2_policies", ], }, host: { @@ -129,6 +151,7 @@ cc_test { "liblog", "libutils", "libziparchive", + "libidmap2_policies", ], shared_libs: [ "libz", @@ -162,6 +185,7 @@ cc_binary { "libidmap2", "libutils", "libziparchive", + "libidmap2_policies", ], }, host: { @@ -173,12 +197,14 @@ cc_binary { "liblog", "libutils", "libziparchive", + "libidmap2_policies", ], shared_libs: [ "libz", ], }, }, + } cc_binary { @@ -199,6 +225,7 @@ cc_binary { "libidmap2", "libutils", "libziparchive", + "libidmap2_policies", ], static_libs: [ "libidmap2daidl", @@ -231,3 +258,16 @@ filegroup { ], path: "idmap2d/aidl", } + +aidl_interface { + name: "overlayable_policy_aidl", + srcs: [":overlayable_policy_aidl_files"], +} + +filegroup { + name: "overlayable_policy_aidl_files", + srcs: [ + "idmap2d/aidl/android/os/OverlayablePolicy.aidl", + ], + path: "idmap2d/aidl", +} diff --git a/cmds/idmap2/idmap2/Create.cpp b/cmds/idmap2/idmap2/Create.cpp index 3ff6d3514331..9682b6ead293 100644 --- a/cmds/idmap2/idmap2/Create.cpp +++ b/cmds/idmap2/idmap2/Create.cpp @@ -20,15 +20,14 @@ #include #include #include -#include -#include #include +#include "androidfw/ResourceTypes.h" #include "idmap2/BinaryStreamVisitor.h" #include "idmap2/CommandLineOptions.h" #include "idmap2/FileUtils.h" #include "idmap2/Idmap.h" -#include "idmap2/Policies.h" +#include "idmap2/PolicyUtils.h" #include "idmap2/SysTrace.h" using android::ApkAssets; @@ -36,14 +35,15 @@ using android::idmap2::BinaryStreamVisitor; using android::idmap2::CommandLineOptions; using android::idmap2::Error; using android::idmap2::Idmap; -using android::idmap2::PoliciesToBitmask; -using android::idmap2::PolicyBitmask; -using android::idmap2::PolicyFlags; using android::idmap2::Result; using android::idmap2::Unit; using android::idmap2::utils::kIdmapFilePermissionMask; +using android::idmap2::utils::PoliciesToBitmaskResult; using android::idmap2::utils::UidHasWriteAccessToPath; +using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + Result Create(const std::vector& args) { SYSTRACE << "Create " << args; std::string target_apk_path; @@ -78,7 +78,7 @@ Result Create(const std::vector& args) { } PolicyBitmask fulfilled_policies = 0; - auto conv_result = PoliciesToBitmask(policies); + auto conv_result = PoliciesToBitmaskResult(policies); if (conv_result) { fulfilled_policies |= *conv_result; } else { @@ -86,7 +86,7 @@ Result Create(const std::vector& args) { } if (fulfilled_policies == 0) { - fulfilled_policies |= PolicyFlags::POLICY_PUBLIC; + fulfilled_policies |= PolicyFlags::PUBLIC; } const std::unique_ptr target_apk = ApkAssets::Load(target_apk_path); diff --git a/cmds/idmap2/idmap2/CreateMultiple.cpp b/cmds/idmap2/idmap2/CreateMultiple.cpp index d4e888fd3119..ba4ca62826b6 100644 --- a/cmds/idmap2/idmap2/CreateMultiple.cpp +++ b/cmds/idmap2/idmap2/CreateMultiple.cpp @@ -20,8 +20,6 @@ #include #include #include -#include -#include #include #include "android-base/stringprintf.h" @@ -30,6 +28,7 @@ #include "idmap2/FileUtils.h" #include "idmap2/Idmap.h" #include "idmap2/Policies.h" +#include "idmap2/PolicyUtils.h" #include "idmap2/SysTrace.h" #include "Commands.h" @@ -39,13 +38,11 @@ using android::idmap2::BinaryStreamVisitor; using android::idmap2::CommandLineOptions; using android::idmap2::Error; using android::idmap2::Idmap; -using android::idmap2::PoliciesToBitmask; -using android::idmap2::PolicyBitmask; -using android::idmap2::PolicyFlags; using android::idmap2::Result; using android::idmap2::Unit; using android::idmap2::utils::kIdmapCacheDir; using android::idmap2::utils::kIdmapFilePermissionMask; +using android::idmap2::utils::PoliciesToBitmaskResult; using android::idmap2::utils::UidHasWriteAccessToPath; Result CreateMultiple(const std::vector& args) { @@ -81,7 +78,7 @@ Result CreateMultiple(const std::vector& args) { } PolicyBitmask fulfilled_policies = 0; - auto conv_result = PoliciesToBitmask(policies); + auto conv_result = PoliciesToBitmaskResult(policies); if (conv_result) { fulfilled_policies |= *conv_result; } else { @@ -89,7 +86,7 @@ Result CreateMultiple(const std::vector& args) { } if (fulfilled_policies == 0) { - fulfilled_policies |= PolicyFlags::POLICY_PUBLIC; + fulfilled_policies |= PolicyFlags::PUBLIC; } const std::unique_ptr target_apk = ApkAssets::Load(target_apk_path); diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp index b4fdd0b8a94d..da0453216f03 100644 --- a/cmds/idmap2/idmap2/Scan.cpp +++ b/cmds/idmap2/idmap2/Scan.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -34,25 +33,24 @@ #include "idmap2/Result.h" #include "idmap2/SysTrace.h" #include "idmap2/XmlParser.h" -#include "idmap2/ZipFile.h" using android::idmap2::CommandLineOptions; using android::idmap2::Error; using android::idmap2::Idmap; -using android::idmap2::kPolicyOdm; -using android::idmap2::kPolicyOem; -using android::idmap2::kPolicyProduct; -using android::idmap2::kPolicyPublic; -using android::idmap2::kPolicySystem; -using android::idmap2::kPolicyVendor; -using android::idmap2::PolicyBitmask; -using android::idmap2::PolicyFlags; using android::idmap2::Result; using android::idmap2::Unit; +using android::idmap2::policy::kPolicyOdm; +using android::idmap2::policy::kPolicyOem; +using android::idmap2::policy::kPolicyProduct; +using android::idmap2::policy::kPolicyPublic; +using android::idmap2::policy::kPolicySystem; +using android::idmap2::policy::kPolicyVendor; using android::idmap2::utils::ExtractOverlayManifestInfo; using android::idmap2::utils::FindFiles; using android::idmap2::utils::OverlayManifestInfo; +using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; + namespace { struct InputOverlay { diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index 4aabf8399a25..f84e4b5f2575 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -33,7 +33,6 @@ #include "idmap2/BinaryStreamVisitor.h" #include "idmap2/FileUtils.h" #include "idmap2/Idmap.h" -#include "idmap2/Policies.h" #include "idmap2/SysTrace.h" #include "utils/String8.h" @@ -42,11 +41,12 @@ using android::binder::Status; using android::idmap2::BinaryStreamVisitor; using android::idmap2::Idmap; using android::idmap2::IdmapHeader; -using android::idmap2::PolicyBitmask; using android::idmap2::utils::kIdmapCacheDir; using android::idmap2::utils::kIdmapFilePermissionMask; using android::idmap2::utils::UidHasWriteAccessToPath; +using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; + namespace { Status ok() { diff --git a/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl b/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl index cd474c0fe056..f4cf65134023 100644 --- a/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl +++ b/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl @@ -20,14 +20,6 @@ package android.os; * @hide */ interface IIdmap2 { - const int POLICY_PUBLIC = 0x00000001; - const int POLICY_SYSTEM_PARTITION = 0x00000002; - const int POLICY_VENDOR_PARTITION = 0x00000004; - const int POLICY_PRODUCT_PARTITION = 0x00000008; - const int POLICY_SIGNATURE = 0x00000010; - const int POLICY_ODM_PARTITION = 0x00000020; - const int POLICY_OEM_PARTITION = 0x00000040; - @utf8InCpp String getIdmapPath(@utf8InCpp String overlayApkPath, int userId); boolean removeIdmap(@utf8InCpp String overlayApkPath, int userId); boolean verifyIdmap(@utf8InCpp String overlayApkPath, int fulfilledPolicies, diff --git a/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl b/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl new file mode 100644 index 000000000000..85b5eff46efa --- /dev/null +++ b/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl @@ -0,0 +1,31 @@ +/* + * 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. + */ + +package android.os; + +/** + * @see ResourcesTypes.h ResTable_overlayable_policy_header::PolicyFlags + * @hide + */ +interface OverlayablePolicy { + const int PUBLIC = 0x00000001; + const int SYSTEM_PARTITION = 0x00000002; + const int VENDOR_PARTITION = 0x00000004; + const int PRODUCT_PARTITION = 0x00000008; + const int SIGNATURE = 0x00000010; + const int ODM_PARTITION = 0x00000020; + const int OEM_PARTITION = 0x00000040; +} diff --git a/cmds/idmap2/include/idmap2/Idmap.h b/cmds/idmap2/include/idmap2/Idmap.h index d4a0c3221c20..2e4836e297ec 100644 --- a/cmds/idmap2/include/idmap2/Idmap.h +++ b/cmds/idmap2/include/idmap2/Idmap.h @@ -73,7 +73,6 @@ #include "androidfw/ApkAssets.h" #include "androidfw/ResourceTypes.h" #include "androidfw/StringPiece.h" -#include "idmap2/Policies.h" #include "idmap2/ResourceMapping.h" namespace android::idmap2 { diff --git a/cmds/idmap2/include/idmap2/Policies.h b/cmds/idmap2/include/idmap2/Policies.h deleted file mode 100644 index 87edd3506d33..000000000000 --- a/cmds/idmap2/include/idmap2/Policies.h +++ /dev/null @@ -1,48 +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. - */ - -#include -#include - -#include "Result.h" -#include "androidfw/ResourceTypes.h" -#include "androidfw/StringPiece.h" - -#ifndef IDMAP2_INCLUDE_IDMAP2_POLICIES_H_ -#define IDMAP2_INCLUDE_IDMAP2_POLICIES_H_ - -namespace android::idmap2 { - -constexpr const char* kPolicyOdm = "odm"; -constexpr const char* kPolicyOem = "oem"; -constexpr const char* kPolicyProduct = "product"; -constexpr const char* kPolicyPublic = "public"; -constexpr const char* kPolicySignature = "signature"; -constexpr const char* kPolicySystem = "system"; -constexpr const char* kPolicyVendor = "vendor"; - -using PolicyFlags = ResTable_overlayable_policy_header::PolicyFlags; -using PolicyBitmask = uint32_t; - -// Parses the string representations of policies into a bitmask. -Result PoliciesToBitmask(const std::vector& policies); - -// Retrieves the string representations of policies in the bitmask. -std::vector BitmaskToPolicies(const PolicyBitmask& bitmask); - -} // namespace android::idmap2 - -#endif // IDMAP2_INCLUDE_IDMAP2_POLICIES_H_ diff --git a/cmds/idmap2/include/idmap2/PolicyUtils.h b/cmds/idmap2/include/idmap2/PolicyUtils.h new file mode 100644 index 000000000000..b95b8b420658 --- /dev/null +++ b/cmds/idmap2/include/idmap2/PolicyUtils.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 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. + */ + +#ifndef IDMAP2_INCLUDE_IDMAP2_POLICYUTILS_H_ +#define IDMAP2_INCLUDE_IDMAP2_POLICYUTILS_H_ + +#include +#include + +#include "androidfw/ResourceTypes.h" +#include "idmap2/Policies.h" +#include "idmap2/Result.h" + +using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; + +namespace android::idmap2::utils { + +// Returns a Result object containing a policy flag bitmask built from a list of policy strings. +// On error will contain a human readable message listing the invalid policies. +Result PoliciesToBitmaskResult(const std::vector& policies); + +// Converts a bitmask of policy flags into a list of their string representation as would be written +// into XML +std::vector BitmaskToPolicies(const PolicyBitmask& bitmask); + +} // namespace android::idmap2::utils + +#endif // IDMAP2_INCLUDE_IDMAP2_POLICYUTILS_H_ diff --git a/cmds/idmap2/include/idmap2/ResourceMapping.h b/cmds/idmap2/include/idmap2/ResourceMapping.h index 86dfab20e448..5869409e7db9 100644 --- a/cmds/idmap2/include/idmap2/ResourceMapping.h +++ b/cmds/idmap2/include/idmap2/ResourceMapping.h @@ -30,6 +30,8 @@ using android::idmap2::utils::OverlayManifestInfo; +using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; + namespace android::idmap2 { struct TargetValue { diff --git a/cmds/idmap2/libidmap2/Policies.cpp b/cmds/idmap2/libidmap2/Policies.cpp deleted file mode 100644 index 495fe615a91f..000000000000 --- a/cmds/idmap2/libidmap2/Policies.cpp +++ /dev/null @@ -1,88 +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. - */ - -#include "idmap2/Policies.h" - -#include -#include -#include -#include - -#include "androidfw/ResourceTypes.h" -#include "idmap2/Idmap.h" -#include "idmap2/Result.h" - -namespace android::idmap2 { - -Result PoliciesToBitmask(const std::vector& policies) { - static const std::unordered_map kStringToFlag = { - {kPolicyOdm, PolicyFlags::POLICY_ODM_PARTITION}, - {kPolicyOem, PolicyFlags::POLICY_OEM_PARTITION}, - {kPolicyPublic, PolicyFlags::POLICY_PUBLIC}, - {kPolicyProduct, PolicyFlags::POLICY_PRODUCT_PARTITION}, - {kPolicySignature, PolicyFlags::POLICY_SIGNATURE}, - {kPolicySystem, PolicyFlags::POLICY_SYSTEM_PARTITION}, - {kPolicyVendor, PolicyFlags::POLICY_VENDOR_PARTITION}, - }; - - PolicyBitmask bitmask = 0; - for (const std::string& policy : policies) { - const auto iter = kStringToFlag.find(policy); - if (iter != kStringToFlag.end()) { - bitmask |= iter->second; - } else { - return Error("unknown policy \"%s\"", policy.c_str()); - } - } - - return Result(bitmask); -} - -std::vector BitmaskToPolicies(const PolicyBitmask& bitmask) { - std::vector policies; - - if ((bitmask & PolicyFlags::POLICY_ODM_PARTITION) != 0) { - policies.emplace_back(kPolicyOdm); - } - - if ((bitmask & PolicyFlags::POLICY_OEM_PARTITION) != 0) { - policies.emplace_back(kPolicyOem); - } - - if ((bitmask & PolicyFlags::POLICY_PUBLIC) != 0) { - policies.emplace_back(kPolicyPublic); - } - - if ((bitmask & PolicyFlags::POLICY_PRODUCT_PARTITION) != 0) { - policies.emplace_back(kPolicyProduct); - } - - if ((bitmask & PolicyFlags::POLICY_SIGNATURE) != 0) { - policies.emplace_back(kPolicySignature); - } - - if ((bitmask & PolicyFlags::POLICY_SYSTEM_PARTITION) != 0) { - policies.emplace_back(kPolicySystem); - } - - if ((bitmask & PolicyFlags::POLICY_VENDOR_PARTITION) != 0) { - policies.emplace_back(kPolicyVendor); - } - - return policies; -} - -} // namespace android::idmap2 diff --git a/cmds/idmap2/libidmap2/PolicyUtils.cpp b/cmds/idmap2/libidmap2/PolicyUtils.cpp new file mode 100644 index 000000000000..fc5182af61c1 --- /dev/null +++ b/cmds/idmap2/libidmap2/PolicyUtils.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2020 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. + */ + +#include "include/idmap2/PolicyUtils.h" + +#include + +#include "android-base/strings.h" +#include "idmap2/Policies.h" + +using android::idmap2::policy::kPolicyStringToFlag; + +namespace android::idmap2::utils { + +Result PoliciesToBitmaskResult(const std::vector& policies) { + std::vector unknown_policies; + PolicyBitmask bitmask = 0; + for (const std::string& policy : policies) { + const auto result = std::find_if(kPolicyStringToFlag.begin(), kPolicyStringToFlag.end(), + [policy](const auto& it) { return policy == it.first; }); + if (result != kPolicyStringToFlag.end()) { + bitmask |= result->second; + } else { + unknown_policies.emplace_back(policy.empty() ? "empty" : policy); + } + } + + if (unknown_policies.empty()) { + return Result(bitmask); + } + + auto prefix = unknown_policies.size() == 1 ? "policy" : "policies"; + return Error("unknown %s: \"%s\"", prefix, android::base::Join(unknown_policies, ",").c_str()); +} + +std::vector BitmaskToPolicies(const PolicyBitmask& bitmask) { + std::vector policies; + + for (const auto& policy : kPolicyStringToFlag) { + if ((bitmask & policy.second) != 0) { + policies.emplace_back(policy.first.to_string()); + } + } + + return policies; +} + +} // namespace android::idmap2::utils diff --git a/cmds/idmap2/libidmap2/ResourceMapping.cpp b/cmds/idmap2/libidmap2/ResourceMapping.cpp index 43cfec3f9cf9..f82c8f1af713 100644 --- a/cmds/idmap2/libidmap2/ResourceMapping.cpp +++ b/cmds/idmap2/libidmap2/ResourceMapping.cpp @@ -24,11 +24,16 @@ #include #include "android-base/stringprintf.h" +#include "androidfw/ResourceTypes.h" +#include "idmap2/PolicyUtils.h" #include "idmap2/ResourceUtils.h" using android::base::StringPrintf; +using android::idmap2::utils::BitmaskToPolicies; using android::idmap2::utils::IsReference; using android::idmap2::utils::ResToTypeEntryName; +using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; namespace android::idmap2 { @@ -55,9 +60,8 @@ Result CheckOverlayable(const LoadedPackage& target_package, const PolicyBitmask& fulfilled_policies, const ResourceId& target_resource) { static constexpr const PolicyBitmask sDefaultPolicies = - PolicyFlags::POLICY_ODM_PARTITION | PolicyFlags::POLICY_OEM_PARTITION | - PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION | - PolicyFlags::POLICY_PRODUCT_PARTITION | PolicyFlags::POLICY_SIGNATURE; + PolicyFlags::ODM_PARTITION | PolicyFlags::OEM_PARTITION | PolicyFlags::SYSTEM_PARTITION | + PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE; // If the resource does not have an overlayable definition, allow the resource to be overlaid if // the overlay is preinstalled or signed with the same signature as the target. diff --git a/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h b/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h new file mode 100644 index 000000000000..9f9b836e31d5 --- /dev/null +++ b/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h @@ -0,0 +1,51 @@ +/* + * 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. + */ + +#ifndef IDMAP2_INCLUDE_IDMAP2_POLICIES_H_ +#define IDMAP2_INCLUDE_IDMAP2_POLICIES_H_ + +#include +#include +#include + +#include "androidfw/ResourceTypes.h" +#include "androidfw/StringPiece.h" + +using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + +namespace android::idmap2::policy { + +constexpr const char* kPolicyOdm = "odm"; +constexpr const char* kPolicyOem = "oem"; +constexpr const char* kPolicyProduct = "product"; +constexpr const char* kPolicyPublic = "public"; +constexpr const char* kPolicySignature = "signature"; +constexpr const char* kPolicySystem = "system"; +constexpr const char* kPolicyVendor = "vendor"; + +inline static const std::array, 7> kPolicyStringToFlag = { + std::pair{kPolicyOdm, PolicyFlags::ODM_PARTITION}, + {kPolicyOem, PolicyFlags::OEM_PARTITION}, + {kPolicyProduct, PolicyFlags::PRODUCT_PARTITION}, + {kPolicyPublic, PolicyFlags::PUBLIC}, + {kPolicySignature, PolicyFlags::SIGNATURE}, + {kPolicySystem, PolicyFlags::SYSTEM_PARTITION}, + {kPolicyVendor, PolicyFlags::VENDOR_PARTITION}, +}; +} // namespace android::idmap2::policy + +#endif // IDMAP2_INCLUDE_IDMAP2_POLICIES_H_ diff --git a/cmds/idmap2/tests/Idmap2BinaryTests.cpp b/cmds/idmap2/tests/Idmap2BinaryTests.cpp index b535f30de1f5..d896cf9c11ba 100644 --- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp +++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp @@ -34,6 +34,7 @@ #include #include +#include "R.h" #include "TestHelpers.h" #include "androidfw/PosixUtils.h" #include "gmock/gmock.h" @@ -127,10 +128,14 @@ TEST_F(Idmap2BinaryTests, Dump) { // clang-format on ASSERT_THAT(result, NotNull()); ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr; - ASSERT_NE(result->stdout.find("0x7f010000 -> 0x7f010000 integer/int1"), std::string::npos); - ASSERT_NE(result->stdout.find("0x7f02000c -> 0x7f020000 string/str1"), std::string::npos); - ASSERT_NE(result->stdout.find("0x7f02000e -> 0x7f020001 string/str3"), std::string::npos); - ASSERT_NE(result->stdout.find("0x7f02000f -> 0x7f020002 string/str4"), std::string::npos); + ASSERT_NE(result->stdout.find(R::target::integer::literal::int1 + " -> 0x7f010000 integer/int1"), + std::string::npos); + ASSERT_NE(result->stdout.find(R::target::string::literal::str1 + " -> 0x7f020000 string/str1"), + std::string::npos); + ASSERT_NE(result->stdout.find(R::target::string::literal::str3 + " -> 0x7f020001 string/str3"), + std::string::npos); + ASSERT_NE(result->stdout.find(R::target::string::literal::str4 + " -> 0x7f020002 string/str4"), + std::string::npos); // clang-format off result = ExecuteBinary({"idmap2", @@ -297,7 +302,7 @@ TEST_F(Idmap2BinaryTests, Lookup) { "lookup", "--idmap-path", GetIdmapPath(), "--config", "", - "--resid", "0x7f02000c"}); // string/str1 + "--resid", R::target::string::literal::str1}); // clang-format on ASSERT_THAT(result, NotNull()); ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr; diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp index a2c156063757..76c6eaf75adc 100644 --- a/cmds/idmap2/tests/IdmapTests.cpp +++ b/cmds/idmap2/tests/IdmapTests.cpp @@ -22,6 +22,8 @@ #include #include +#include "R.h" +#include "TestConstants.h" #include "TestHelpers.h" #include "android-base/macros.h" #include "androidfw/ApkAssets.h" @@ -36,6 +38,8 @@ using android::Res_value; using ::testing::IsNull; using ::testing::NotNull; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + namespace android::idmap2 { #define ASSERT_TARGET_ENTRY(entry, target_resid, type, value) \ @@ -168,7 +172,7 @@ TEST(IdmapTests, CreateIdmapHeaderFromApkAssets) { std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - auto idmap_result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::POLICY_PUBLIC, + auto idmap_result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, /* enforce_overlayable */ true); ASSERT_TRUE(idmap_result) << idmap_result.GetErrorMessage(); auto& idmap = *idmap_result; @@ -177,8 +181,8 @@ TEST(IdmapTests, CreateIdmapHeaderFromApkAssets) { ASSERT_THAT(idmap->GetHeader(), NotNull()); ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U); ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x03U); - ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x76a20829); - ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0xc054fb26); + ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), android::idmap2::TestConstants::TARGET_CRC); + ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), android::idmap2::TestConstants::OVERLAY_CRC); ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), target_apk_path); ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path); } @@ -220,7 +224,7 @@ TEST(IdmapTests, CreateIdmapDataFromApkAssets) { std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - auto idmap_result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::POLICY_PUBLIC, + auto idmap_result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, /* enforce_overlayable */ true); ASSERT_TRUE(idmap_result) << idmap_result.GetErrorMessage(); auto& idmap = *idmap_result; @@ -234,17 +238,21 @@ TEST(IdmapTests, CreateIdmapDataFromApkAssets) { const auto& target_entries = data->GetTargetEntries(); ASSERT_EQ(target_entries.size(), 4U); - ASSERT_TARGET_ENTRY(target_entries[0], 0x7f010000, Res_value::TYPE_DYNAMIC_REFERENCE, 0x7f010000); - ASSERT_TARGET_ENTRY(target_entries[1], 0x7f02000c, Res_value::TYPE_DYNAMIC_REFERENCE, 0x7f020000); - ASSERT_TARGET_ENTRY(target_entries[2], 0x7f02000e, Res_value::TYPE_DYNAMIC_REFERENCE, 0x7f020001); - ASSERT_TARGET_ENTRY(target_entries[3], 0x7f02000f, Res_value::TYPE_DYNAMIC_REFERENCE, 0x7f020002); + ASSERT_TARGET_ENTRY(target_entries[0], R::target::integer::int1, + Res_value::TYPE_DYNAMIC_REFERENCE, R::overlay::integer::int1); + ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str1, Res_value::TYPE_DYNAMIC_REFERENCE, + R::overlay::string::str1); + ASSERT_TARGET_ENTRY(target_entries[2], R::target::string::str3, Res_value::TYPE_DYNAMIC_REFERENCE, + R::overlay::string::str3); + ASSERT_TARGET_ENTRY(target_entries[3], R::target::string::str4, Res_value::TYPE_DYNAMIC_REFERENCE, + R::overlay::string::str4); const auto& overlay_entries = data->GetOverlayEntries(); ASSERT_EQ(target_entries.size(), 4U); - ASSERT_OVERLAY_ENTRY(overlay_entries[0], 0x7f010000, 0x7f010000); - ASSERT_OVERLAY_ENTRY(overlay_entries[1], 0x7f020000, 0x7f02000c); - ASSERT_OVERLAY_ENTRY(overlay_entries[2], 0x7f020001, 0x7f02000e); - ASSERT_OVERLAY_ENTRY(overlay_entries[3], 0x7f020002, 0x7f02000f); + ASSERT_OVERLAY_ENTRY(overlay_entries[0], R::overlay::integer::int1, R::target::integer::int1); + ASSERT_OVERLAY_ENTRY(overlay_entries[1], R::overlay::string::str1, R::target::string::str1); + ASSERT_OVERLAY_ENTRY(overlay_entries[2], R::overlay::string::str3, R::target::string::str3); + ASSERT_OVERLAY_ENTRY(overlay_entries[3], R::overlay::string::str4, R::target::string::str4); } TEST(IdmapTests, CreateIdmapDataFromApkAssetsSharedLibOverlay) { @@ -257,7 +265,7 @@ TEST(IdmapTests, CreateIdmapDataFromApkAssetsSharedLibOverlay) { std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - auto idmap_result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::POLICY_PUBLIC, + auto idmap_result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, /* enforce_overlayable */ true); ASSERT_TRUE(idmap_result) << idmap_result.GetErrorMessage(); auto& idmap = *idmap_result; @@ -290,7 +298,7 @@ TEST(IdmapTests, CreateIdmapDataDoNotRewriteNonOverlayResourceId) { info.target_name = "TestResources"; info.resource_mapping = 0x7f030001; // xml/overlays_different_packages auto idmap_data = TestIdmapDataFromApkAssets("/target/target.apk", "/overlay/overlay.apk", info, - PolicyFlags::POLICY_PUBLIC, + PolicyFlags::PUBLIC, /* enforce_overlayable */ false); ASSERT_TRUE(idmap_data) << idmap_data.GetErrorMessage(); @@ -298,14 +306,14 @@ TEST(IdmapTests, CreateIdmapDataDoNotRewriteNonOverlayResourceId) { const auto& target_entries = data->GetTargetEntries(); ASSERT_EQ(target_entries.size(), 2U); - ASSERT_TARGET_ENTRY(target_entries[0], 0x7f02000c, Res_value::TYPE_REFERENCE, - 0x0104000a); // string/str1 -> android:string/ok - ASSERT_TARGET_ENTRY(target_entries[1], 0x7f02000e, Res_value::TYPE_DYNAMIC_REFERENCE, - 0x7f020001); // string/str3 -> string/str4 + ASSERT_TARGET_ENTRY(target_entries[0], R::target::string::str1, Res_value::TYPE_REFERENCE, + 0x0104000a); // -> android:string/ok + ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str3, Res_value::TYPE_DYNAMIC_REFERENCE, + R::overlay::string::str3); const auto& overlay_entries = data->GetOverlayEntries(); ASSERT_EQ(overlay_entries.size(), 1U); - ASSERT_OVERLAY_ENTRY(overlay_entries[0], 0x7f020001, 0x7f02000e); // string/str3 <- string/str4 + ASSERT_OVERLAY_ENTRY(overlay_entries[0], R::overlay::string::str3, R::target::string::str3); } TEST(IdmapTests, CreateIdmapDataInlineResources) { @@ -314,7 +322,7 @@ TEST(IdmapTests, CreateIdmapDataInlineResources) { info.target_name = "TestResources"; info.resource_mapping = 0x7f030002; // xml/overlays_inline auto idmap_data = TestIdmapDataFromApkAssets("/target/target.apk", "/overlay/overlay.apk", info, - PolicyFlags::POLICY_PUBLIC, + PolicyFlags::PUBLIC, /* enforce_overlayable */ false); ASSERT_TRUE(idmap_data) << idmap_data.GetErrorMessage(); @@ -323,10 +331,10 @@ TEST(IdmapTests, CreateIdmapDataInlineResources) { constexpr size_t overlay_string_pool_size = 8U; const auto& target_entries = data->GetTargetEntries(); ASSERT_EQ(target_entries.size(), 2U); - ASSERT_TARGET_ENTRY(target_entries[0], 0x7f010000, Res_value::TYPE_INT_DEC, - 73U); // integer/int1 -> 73 - ASSERT_TARGET_ENTRY(target_entries[1], 0x7f02000c, Res_value::TYPE_STRING, - overlay_string_pool_size + 0U); // string/str1 -> "Hello World" + ASSERT_TARGET_ENTRY(target_entries[0], R::target::integer::int1, Res_value::TYPE_INT_DEC, + 73U); // -> 73 + ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str1, Res_value::TYPE_STRING, + overlay_string_pool_size + 0U); // -> "Hello World" const auto& overlay_entries = data->GetOverlayEntries(); ASSERT_EQ(overlay_entries.size(), 0U); @@ -346,7 +354,7 @@ TEST(IdmapTests, FailToCreateIdmapFromApkAssetsIfPathTooLong) { std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - const auto result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::POLICY_PUBLIC, + const auto result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, /* enforce_overlayable */ true); ASSERT_FALSE(result); } @@ -362,7 +370,7 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - auto result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::POLICY_PUBLIC, + auto result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, /* enforce_overlayable */ true); ASSERT_TRUE(result); const auto idmap = std::move(*result); diff --git a/cmds/idmap2/tests/PoliciesTests.cpp b/cmds/idmap2/tests/PoliciesTests.cpp index eca74045f428..4b395c7912d1 100644 --- a/cmds/idmap2/tests/PoliciesTests.cpp +++ b/cmds/idmap2/tests/PoliciesTests.cpp @@ -17,74 +17,78 @@ #include #include "TestHelpers.h" +#include "androidfw/ResourceTypes.h" #include "gtest/gtest.h" -#include "idmap2/Policies.h" +#include "idmap2/PolicyUtils.h" -using android::idmap2::PolicyBitmask; -using android::idmap2::PolicyFlags; +using android::idmap2::utils::BitmaskToPolicies; +using android::idmap2::utils::PoliciesToBitmaskResult; + +using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; namespace android::idmap2 { -TEST(PoliciesTests, PoliciesToBitmasks) { - const auto bitmask1 = PoliciesToBitmask({"system"}); +TEST(PoliciesTests, PoliciesToBitmaskResults) { + const auto bitmask1 = PoliciesToBitmaskResult({"system"}); ASSERT_TRUE(bitmask1); - ASSERT_EQ(*bitmask1, PolicyFlags::POLICY_SYSTEM_PARTITION); + ASSERT_EQ(*bitmask1, PolicyFlags::SYSTEM_PARTITION); - const auto bitmask2 = PoliciesToBitmask({"system", "vendor"}); + const auto bitmask2 = PoliciesToBitmaskResult({"system", "vendor"}); ASSERT_TRUE(bitmask2); - ASSERT_EQ(*bitmask2, PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION); + ASSERT_EQ(*bitmask2, PolicyFlags::SYSTEM_PARTITION | PolicyFlags::VENDOR_PARTITION); - const auto bitmask3 = PoliciesToBitmask({"vendor", "system"}); + const auto bitmask3 = PoliciesToBitmaskResult({"vendor", "system"}); ASSERT_TRUE(bitmask3); - ASSERT_EQ(*bitmask3, PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION); + ASSERT_EQ(*bitmask3, PolicyFlags::SYSTEM_PARTITION | PolicyFlags::VENDOR_PARTITION); - const auto bitmask4 = PoliciesToBitmask({"odm", "oem", "public", "product", "system", "vendor"}); + const auto bitmask4 = + PoliciesToBitmaskResult({"odm", "oem", "public", "product", "system", "vendor"}); ASSERT_TRUE(bitmask4); - ASSERT_EQ(*bitmask4, PolicyFlags::POLICY_ODM_PARTITION | PolicyFlags::POLICY_OEM_PARTITION | - PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_PRODUCT_PARTITION | - PolicyFlags::POLICY_SYSTEM_PARTITION | - PolicyFlags::POLICY_VENDOR_PARTITION); + ASSERT_EQ(*bitmask4, PolicyFlags::ODM_PARTITION | PolicyFlags::OEM_PARTITION | + PolicyFlags::PUBLIC | PolicyFlags::PRODUCT_PARTITION | + PolicyFlags::SYSTEM_PARTITION | PolicyFlags::VENDOR_PARTITION); - const auto bitmask5 = PoliciesToBitmask({"system", "system", "system"}); + const auto bitmask5 = PoliciesToBitmaskResult({"system", "system", "system"}); ASSERT_TRUE(bitmask5); - ASSERT_EQ(*bitmask5, PolicyFlags::POLICY_SYSTEM_PARTITION); + ASSERT_EQ(*bitmask5, PolicyFlags::SYSTEM_PARTITION); - const auto bitmask6 = PoliciesToBitmask({""}); + const auto bitmask6 = PoliciesToBitmaskResult({""}); ASSERT_FALSE(bitmask6); - const auto bitmask7 = PoliciesToBitmask({"foo"}); + const auto bitmask7 = PoliciesToBitmaskResult({"foo"}); ASSERT_FALSE(bitmask7); - const auto bitmask8 = PoliciesToBitmask({"system", "foo"}); + const auto bitmask8 = PoliciesToBitmaskResult({"system", "foo"}); ASSERT_FALSE(bitmask8); - const auto bitmask9 = PoliciesToBitmask({"system", ""}); + const auto bitmask9 = PoliciesToBitmaskResult({"system", ""}); ASSERT_FALSE(bitmask9); - const auto bitmask10 = PoliciesToBitmask({"system "}); + const auto bitmask10 = PoliciesToBitmaskResult({"system "}); ASSERT_FALSE(bitmask10); } TEST(PoliciesTests, BitmaskToPolicies) { - const auto policies1 = BitmaskToPolicies(PolicyFlags::POLICY_PUBLIC); + const auto policies1 = BitmaskToPolicies(PolicyFlags::PUBLIC); ASSERT_EQ(1, policies1.size()); ASSERT_EQ(policies1[0], "public"); - const auto policies2 = BitmaskToPolicies(PolicyFlags::POLICY_SYSTEM_PARTITION | - PolicyFlags::POLICY_VENDOR_PARTITION); + const auto policies2 = + BitmaskToPolicies(PolicyFlags::SYSTEM_PARTITION | PolicyFlags::VENDOR_PARTITION); ASSERT_EQ(2, policies2.size()); ASSERT_EQ(policies2[0], "system"); ASSERT_EQ(policies2[1], "vendor"); - const auto policies3 = BitmaskToPolicies( - PolicyFlags::POLICY_ODM_PARTITION | PolicyFlags::POLICY_OEM_PARTITION | - PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_PRODUCT_PARTITION | - PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION); + const auto policies3 = + BitmaskToPolicies(PolicyFlags::ODM_PARTITION | PolicyFlags::OEM_PARTITION | + PolicyFlags::PUBLIC | PolicyFlags::PRODUCT_PARTITION | + PolicyFlags::SYSTEM_PARTITION | PolicyFlags::VENDOR_PARTITION); ASSERT_EQ(2, policies2.size()); ASSERT_EQ(policies3[0], "odm"); ASSERT_EQ(policies3[1], "oem"); - ASSERT_EQ(policies3[2], "public"); - ASSERT_EQ(policies3[3], "product"); + ASSERT_EQ(policies3[2], "product"); + ASSERT_EQ(policies3[3], "public"); ASSERT_EQ(policies3[4], "system"); ASSERT_EQ(policies3[5], "vendor"); } diff --git a/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp b/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp index 1d34e42e188d..9a10079772bf 100644 --- a/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp +++ b/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp @@ -18,19 +18,22 @@ #include #include +#include "R.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/Policies.h" #include "idmap2/PrettyPrintVisitor.h" using ::testing::NotNull; using android::ApkAssets; -using android::idmap2::PolicyBitmask; + +using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; namespace android::idmap2 { @@ -43,7 +46,7 @@ TEST(PrettyPrintVisitorTests, CreatePrettyPrintVisitor) { std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - const auto idmap = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::POLICY_PUBLIC, + const auto idmap = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, /* enforce_overlayable */ true); ASSERT_TRUE(idmap); @@ -53,7 +56,8 @@ TEST(PrettyPrintVisitorTests, CreatePrettyPrintVisitor) { ASSERT_NE(stream.str().find("target apk path : "), std::string::npos); ASSERT_NE(stream.str().find("overlay apk path : "), std::string::npos); - ASSERT_NE(stream.str().find("0x7f010000 -> 0x7f010000 integer/int1\n"), std::string::npos); + ASSERT_NE(stream.str().find(R::target::integer::literal::int1 + " -> 0x7f010000 integer/int1\n"), + std::string::npos); } TEST(PrettyPrintVisitorTests, CreatePrettyPrintVisitorWithoutAccessToApks) { diff --git a/cmds/idmap2/tests/R.h b/cmds/idmap2/tests/R.h new file mode 100644 index 000000000000..b2a589144c77 --- /dev/null +++ b/cmds/idmap2/tests/R.h @@ -0,0 +1,94 @@ +/* + * 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. + */ + +#ifndef IDMAP2_TESTS_R_H +#define IDMAP2_TESTS_R_H + +#include + +namespace android::idmap2 { + +static std::string hexify(ResourceId id) { + std::stringstream stream; + stream << std::hex << static_cast(id); + return stream.str(); +} + +// clang-format off +namespace R::target { + namespace integer { + constexpr ResourceId int1 = 0x7f010000; + + namespace literal { + inline const std::string int1 = hexify(R::target::integer::int1); + } + } + + namespace string { + constexpr ResourceId not_overlayable = 0x7f020003; + constexpr ResourceId other = 0x7f020004; + constexpr ResourceId policy_odm = 0x7f020005; + constexpr ResourceId policy_oem = 0x7f020006; + constexpr ResourceId policy_product = 0x7f020007; + constexpr ResourceId policy_public = 0x7f020008; + constexpr ResourceId policy_signature = 0x7f020009; + constexpr ResourceId policy_system = 0x7f02000a; + constexpr ResourceId policy_system_vendor = 0x7f02000b; + constexpr ResourceId str1 = 0x7f02000c; + constexpr ResourceId str3 = 0x7f02000e; + constexpr ResourceId str4 = 0x7f02000f; + + namespace literal { + 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 R::overlay { + namespace integer { + constexpr ResourceId int1 = 0x7f010000; + } + namespace string { + constexpr ResourceId str1 = 0x7f020000; + constexpr ResourceId str3 = 0x7f020001; + constexpr ResourceId str4 = 0x7f020002; + } +} + +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_odm = 0x7f010002; + constexpr ResourceId policy_oem = 0x7f010003; + constexpr ResourceId policy_product = 0x7f010004; + constexpr ResourceId policy_public = 0x7f010005; + constexpr ResourceId policy_signature = 0x7f010006; + constexpr ResourceId policy_system = 0x7f010007; + constexpr ResourceId policy_system_vendor = 0x7f010008; +}; +// clang-format on + +} // namespace android::idmap2 + +#endif // IDMAP2_TESTS_R_H diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp index b22fdafb09bb..5c5c81edee90 100644 --- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp +++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp @@ -20,14 +20,20 @@ #include #include +#include "TestConstants.h" #include "TestHelpers.h" +#include "android-base/stringprintf.h" +#include "androidfw/ResourceTypes.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "idmap2/Idmap.h" #include "idmap2/RawPrintVisitor.h" +using android::base::StringPrintf; using ::testing::NotNull; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + namespace android::idmap2 { #define ASSERT_CONTAINS_REGEX(pattern, str) \ @@ -48,7 +54,7 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) { std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - const auto idmap = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::POLICY_PUBLIC, + const auto idmap = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::PUBLIC, /* enforce_overlayable */ true); ASSERT_TRUE(idmap); @@ -59,8 +65,12 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) { #define ADDRESS "[0-9a-f]{8}: " ASSERT_CONTAINS_REGEX(ADDRESS "504d4449 magic\n", stream.str()); ASSERT_CONTAINS_REGEX(ADDRESS "00000003 version\n", stream.str()); - ASSERT_CONTAINS_REGEX(ADDRESS "76a20829 target crc\n", stream.str()); - ASSERT_CONTAINS_REGEX(ADDRESS "c054fb26 overlay crc\n", stream.str()); + ASSERT_CONTAINS_REGEX( + StringPrintf(ADDRESS "%s target crc\n", android::idmap2::TestConstants::TARGET_CRC_STRING), + stream.str()); + ASSERT_CONTAINS_REGEX( + StringPrintf(ADDRESS "%s overlay crc\n", android::idmap2::TestConstants::OVERLAY_CRC_STRING), + 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()); diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp index 39c4937b0930..8d0e6609ac40 100644 --- a/cmds/idmap2/tests/ResourceMappingTests.cpp +++ b/cmds/idmap2/tests/ResourceMappingTests.cpp @@ -22,7 +22,9 @@ #include #include +#include "R.h" #include "TestHelpers.h" +#include "androidfw/ResourceTypes.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "idmap2/LogInfo.h" @@ -31,6 +33,8 @@ using android::Res_value; using android::idmap2::utils::ExtractOverlayManifestInfo; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + namespace android::idmap2 { #define ASSERT_RESULT(r) \ @@ -106,20 +110,20 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsLegacy) { info.target_name = "TestResources"; info.resource_mapping = 0U; // no xml auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", info, - PolicyFlags::POLICY_PUBLIC, + PolicyFlags::PUBLIC, /* enforce_overlayable */ false); ASSERT_TRUE(resources) << resources.GetErrorMessage(); auto& res = *resources; ASSERT_EQ(res.GetTargetToOverlayMap().size(), 4U); - ASSERT_RESULT(MappingExists(res, 0x7f010000, Res_value::TYPE_REFERENCE, 0x7f010000, - false /* rewrite */)); // integer/int1 - ASSERT_RESULT(MappingExists(res, 0x7f02000c, Res_value::TYPE_REFERENCE, 0x7f020000, - false /* rewrite */)); // string/str1 - ASSERT_RESULT(MappingExists(res, 0x7f02000e, Res_value::TYPE_REFERENCE, 0x7f020001, - false /* rewrite */)); // string/str3 - ASSERT_RESULT(MappingExists(res, 0x7f02000f, Res_value::TYPE_REFERENCE, 0x7f020002, - false /* rewrite */)); // string/str4 + ASSERT_RESULT(MappingExists(res, R::target::integer::int1, Res_value::TYPE_REFERENCE, + R::overlay::integer::int1, false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::str1, Res_value::TYPE_REFERENCE, + R::overlay::string::str1, false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::str3, Res_value::TYPE_REFERENCE, + R::overlay::string::str3, false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::str4, Res_value::TYPE_REFERENCE, + R::overlay::string::str4, false /* rewrite */)); } TEST(ResourceMappingTests, ResourcesFromApkAssetsNonMatchingNames) { @@ -128,18 +132,18 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsNonMatchingNames) { info.target_name = "TestResources"; info.resource_mapping = 0x7f030003; // xml/overlays_swap auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", info, - PolicyFlags::POLICY_PUBLIC, + PolicyFlags::PUBLIC, /* enforce_overlayable */ false); ASSERT_TRUE(resources) << resources.GetErrorMessage(); auto& res = *resources; ASSERT_EQ(res.GetTargetToOverlayMap().size(), 3U); - ASSERT_RESULT(MappingExists(res, 0x7f02000c, Res_value::TYPE_DYNAMIC_REFERENCE, 0x7f020002, - true /* rewrite */)); // string/str1 -> string/str4 - ASSERT_RESULT(MappingExists(res, 0x7f02000e, Res_value::TYPE_DYNAMIC_REFERENCE, 0x7f020000, - true /* rewrite */)); // string/str3 -> string/str1 - ASSERT_RESULT(MappingExists(res, 0x7f02000f, Res_value::TYPE_DYNAMIC_REFERENCE, 0x7f020001, - true /* rewrite */)); // string/str4 -> string/str3 + ASSERT_RESULT(MappingExists(res, R::target::string::str1, Res_value::TYPE_DYNAMIC_REFERENCE, + R::overlay::string::str4, true /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::str3, Res_value::TYPE_DYNAMIC_REFERENCE, + R::overlay::string::str1, true /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::str4, Res_value::TYPE_DYNAMIC_REFERENCE, + R::overlay::string::str3, true /* rewrite */)); } TEST(ResourceMappingTests, DoNotRewriteNonOverlayResourceId) { @@ -148,17 +152,17 @@ TEST(ResourceMappingTests, DoNotRewriteNonOverlayResourceId) { info.target_name = "TestResources"; info.resource_mapping = 0x7f030001; // xml/overlays_different_packages auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", info, - PolicyFlags::POLICY_PUBLIC, + PolicyFlags::PUBLIC, /* enforce_overlayable */ false); ASSERT_TRUE(resources) << resources.GetErrorMessage(); auto& res = *resources; ASSERT_EQ(res.GetTargetToOverlayMap().size(), 2U); ASSERT_EQ(res.GetOverlayToTargetMap().size(), 1U); - ASSERT_RESULT(MappingExists(res, 0x7f02000c, Res_value::TYPE_REFERENCE, 0x0104000a, - false /* rewrite */)); // string/str1 -> android:string/ok - ASSERT_RESULT(MappingExists(res, 0x7f02000e, Res_value::TYPE_DYNAMIC_REFERENCE, 0x7f020001, - true /* rewrite */)); // string/str3 -> string/str4 + ASSERT_RESULT(MappingExists(res, R::target::string::str1, Res_value::TYPE_REFERENCE, 0x0104000a, + false /* rewrite */)); // -> android:string/ok + ASSERT_RESULT(MappingExists(res, R::target::string::str3, Res_value::TYPE_DYNAMIC_REFERENCE, + 0x7f020001, true /* rewrite */)); } TEST(ResourceMappingTests, InlineResources) { @@ -167,7 +171,7 @@ TEST(ResourceMappingTests, InlineResources) { info.target_name = "TestResources"; info.resource_mapping = 0x7f030002; // xml/overlays_inline auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", info, - PolicyFlags::POLICY_PUBLIC, + PolicyFlags::PUBLIC, /* enforce_overlayable */ false); constexpr size_t overlay_string_pool_size = 8U; @@ -175,108 +179,117 @@ TEST(ResourceMappingTests, InlineResources) { auto& res = *resources; ASSERT_EQ(res.GetTargetToOverlayMap().size(), 2U); ASSERT_EQ(res.GetOverlayToTargetMap().size(), 0U); - ASSERT_RESULT(MappingExists(res, 0x7f02000c, Res_value::TYPE_STRING, + ASSERT_RESULT(MappingExists(res, R::target::string::str1, Res_value::TYPE_STRING, overlay_string_pool_size + 0U, - false /* rewrite */)); // string/str1 -> "Hello World" - ASSERT_RESULT(MappingExists(res, 0x7f010000, Res_value::TYPE_INT_DEC, 73U, - false /* rewrite */)); // string/str1 -> "Hello World" + false /* rewrite */)); // -> "Hello World" + ASSERT_RESULT(MappingExists(res, R::target::integer::int1, Res_value::TYPE_INT_DEC, 73U, + false /* rewrite */)); // -> 73 } TEST(ResourceMappingTests, CreateIdmapFromApkAssetsPolicySystemPublic) { auto resources = TestGetResourceMapping("/target/target.apk", "/system-overlay/system-overlay.apk", - PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC, + 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, 0x7f020008, Res_value::TYPE_REFERENCE, 0x7f010000, - false /* rewrite */)); // string/policy_public - ASSERT_RESULT(MappingExists(res, 0x7f02000a, Res_value::TYPE_REFERENCE, 0x7f010001, - false /* rewrite */)); // string/policy_system - ASSERT_RESULT(MappingExists(res, 0x7f02000b, Res_value::TYPE_REFERENCE, 0x7f010002, - false /* rewrite */)); // string/policy_system_vendor + ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE, + R::system_overlay::string::policy_public, false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, Res_value::TYPE_REFERENCE, + R::system_overlay::string::policy_system, false /* rewrite */)); + ASSERT_RESULT( + MappingExists(res, R::target::string::policy_system_vendor, Res_value::TYPE_REFERENCE, + R::system_overlay::string::policy_system_vendor, false /* rewrite */)); } // 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", - PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC, - /* enforce_overlayable */ true); + auto resources = TestGetResourceMapping("/target/target.apk", + "/system-overlay-invalid/system-overlay-invalid.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, 0x7f020008, Res_value::TYPE_REFERENCE, 0x7f010005, - false /* rewrite */)); // string/policy_public - ASSERT_RESULT(MappingExists(res, 0x7f02000a, Res_value::TYPE_REFERENCE, 0x7f010007, - false /* rewrite */)); // string/policy_system - ASSERT_RESULT(MappingExists(res, 0x7f02000b, Res_value::TYPE_REFERENCE, 0x7f010008, - false /* rewrite */)); // string/policy_system_vendor + ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_public, + false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_system, + false /* rewrite */)); + ASSERT_RESULT( + MappingExists(res, R::target::string::policy_system_vendor, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_system_vendor, false /* rewrite */)); } // 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", - PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC, - /* enforce_overlayable */ false); + auto resources = TestGetResourceMapping("/target/target.apk", + "/system-overlay-invalid/system-overlay-invalid.apk", + PolicyFlags::SYSTEM_PARTITION | PolicyFlags::PUBLIC, + /* enforce_overlayable */ false); ASSERT_TRUE(resources) << resources.GetErrorMessage(); auto& res = *resources; ASSERT_EQ(res.GetTargetToOverlayMap().size(), 9U); - ASSERT_RESULT(MappingExists(res, 0x7f020003, Res_value::TYPE_REFERENCE, 0x7f010000, - false /* rewrite */)); // string/not_overlayable - ASSERT_RESULT(MappingExists(res, 0x7f020004, Res_value::TYPE_REFERENCE, 0x7f010001, - false /* rewrite */)); // string/other - ASSERT_RESULT(MappingExists(res, 0x7f020005, Res_value::TYPE_REFERENCE, 0x7f010002, - false /* rewrite */)); // string/policy_odm - ASSERT_RESULT(MappingExists(res, 0x7f020006, Res_value::TYPE_REFERENCE, 0x7f010003, - false /* rewrite */)); // string/policy_oem - ASSERT_RESULT(MappingExists(res, 0x7f020007, Res_value::TYPE_REFERENCE, 0x7f010004, - false /* rewrite */)); // string/policy_product - ASSERT_RESULT(MappingExists(res, 0x7f020008, Res_value::TYPE_REFERENCE, 0x7f010005, - false /* rewrite */)); // string/policy_public - ASSERT_RESULT(MappingExists(res, 0x7f020009, Res_value::TYPE_REFERENCE, 0x7f010006, - false /* rewrite */)); // string/policy_signature - ASSERT_RESULT(MappingExists(res, 0x7f02000a, Res_value::TYPE_REFERENCE, 0x7f010007, - false /* rewrite */)); // string/policy_system - ASSERT_RESULT(MappingExists(res, 0x7f02000b, Res_value::TYPE_REFERENCE, 0x7f010008, - false /* rewrite */)); // string/policy_system_vendor + ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::not_overlayable, + false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::other, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::other, false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_odm, false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_oem, false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_product, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_product, + false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_public, + false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_signature, + false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_system, + false /* rewrite */)); + ASSERT_RESULT( + MappingExists(res, R::target::string::policy_system_vendor, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_system_vendor, false /* rewrite */)); } // Overlays that do not target an tag can overlay resources defined within any // tag. TEST(ResourceMappingTests, ResourcesFromApkAssetsNoDefinedOverlayableAndNoTargetName) { auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay-no-name.apk", - PolicyFlags::POLICY_PUBLIC, + PolicyFlags::PUBLIC, /* enforce_overlayable */ false); ASSERT_TRUE(resources) << resources.GetErrorMessage(); auto& res = *resources; ASSERT_EQ(res.GetTargetToOverlayMap().size(), 4U); - ASSERT_RESULT(MappingExists(res, 0x7f010000, Res_value::TYPE_REFERENCE, 0x7f010000, - false /* rewrite */)); // integer/int1 - ASSERT_RESULT(MappingExists(res, 0x7f02000c, Res_value::TYPE_REFERENCE, 0x7f020000, - false /* rewrite */)); // string/str1 - ASSERT_RESULT(MappingExists(res, 0x7f02000e, Res_value::TYPE_REFERENCE, 0x7f020001, - false /* rewrite */)); // string/str3 - ASSERT_RESULT(MappingExists(res, 0x7f02000f, Res_value::TYPE_REFERENCE, 0x7f020002, - false /* rewrite */)); // string/str4 + ASSERT_RESULT(MappingExists(res, R::target::integer::int1, Res_value::TYPE_REFERENCE, + R::overlay::integer::int1, false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::str1, Res_value::TYPE_REFERENCE, + R::overlay::string::str1, false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::str3, Res_value::TYPE_REFERENCE, + R::overlay::string::str3, false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::str4, Res_value::TYPE_REFERENCE, + R::overlay::string::str4, false /* rewrite */)); } // 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::POLICY_PUBLIC, - /* enforce_overlayable */ true); + auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk", + "/overlay/overlay-no-name.apk", PolicyFlags::PUBLIC, + /* enforce_overlayable */ true); ASSERT_TRUE(resources) << resources.GetErrorMessage(); ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 0U); @@ -294,32 +307,40 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) { ASSERT_TRUE(resources) << resources.GetErrorMessage(); auto& res = *resources; ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 9U); - ASSERT_RESULT(MappingExists(res, 0x7f020003, Res_value::TYPE_REFERENCE, 0x7f010000, - false /* rewrite */)); // string/not_overlayable - ASSERT_RESULT(MappingExists(res, 0x7f020004, Res_value::TYPE_REFERENCE, 0x7f010001, - false /* rewrite */)); // string/other - ASSERT_RESULT(MappingExists(res, 0x7f020005, Res_value::TYPE_REFERENCE, 0x7f010002, - false /* rewrite */)); // string/policy_odm - ASSERT_RESULT(MappingExists(res, 0x7f020006, Res_value::TYPE_REFERENCE, 0x7f010003, - false /* rewrite */)); // string/policy_oem - ASSERT_RESULT(MappingExists(res, 0x7f020007, Res_value::TYPE_REFERENCE, 0x7f010004, - false /* rewrite */)); // string/policy_product - ASSERT_RESULT(MappingExists(res, 0x7f020008, Res_value::TYPE_REFERENCE, 0x7f010005, - false /* rewrite */)); // string/policy_public - ASSERT_RESULT(MappingExists(res, 0x7f020009, Res_value::TYPE_REFERENCE, 0x7f010006, - false /* rewrite */)); // string/policy_signature - ASSERT_RESULT(MappingExists(res, 0x7f02000a, Res_value::TYPE_REFERENCE, 0x7f010007, - false /* rewrite */)); // string/policy_system - ASSERT_RESULT(MappingExists(res, 0x7f02000b, Res_value::TYPE_REFERENCE, 0x7f010008, - false /* rewrite */)); // string/policy_system_vendor + ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::not_overlayable, + false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::other, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::other, false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_odm, + false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_oem, + false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_product, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_product, + false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_public, + false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_signature, + false /* rewrite */)); + ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_system, + false /* rewrite */)); + ASSERT_RESULT(MappingExists( + res, R::target::string::policy_system_vendor, Res_value::TYPE_REFERENCE, + R::system_overlay_invalid::string::policy_system_vendor, false /* rewrite */)); }; - CheckEntries(PolicyFlags::POLICY_SIGNATURE); - CheckEntries(PolicyFlags::POLICY_PRODUCT_PARTITION); - CheckEntries(PolicyFlags::POLICY_SYSTEM_PARTITION); - CheckEntries(PolicyFlags::POLICY_VENDOR_PARTITION); - CheckEntries(PolicyFlags::POLICY_ODM_PARTITION); - CheckEntries(PolicyFlags::POLICY_OEM_PARTITION); + CheckEntries(PolicyFlags::SIGNATURE); + CheckEntries(PolicyFlags::PRODUCT_PARTITION); + CheckEntries(PolicyFlags::SYSTEM_PARTITION); + CheckEntries(PolicyFlags::VENDOR_PARTITION); + CheckEntries(PolicyFlags::ODM_PARTITION); + CheckEntries(PolicyFlags::OEM_PARTITION); } } // namespace android::idmap2 diff --git a/cmds/idmap2/tests/TestConstants.h b/cmds/idmap2/tests/TestConstants.h new file mode 100644 index 000000000000..c874dc93ce79 --- /dev/null +++ b/cmds/idmap2/tests/TestConstants.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 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. + */ + +#ifndef IDMAP2_TESTS_TESTCONSTANTS_H +#define IDMAP2_TESTS_TESTCONSTANTS_H + +namespace android::idmap2::TestConstants { + +constexpr const auto TARGET_CRC = 0x76a20829; +constexpr const auto TARGET_CRC_STRING = "76a20829"; + +constexpr const auto OVERLAY_CRC = 0xc054fb26; +constexpr const auto OVERLAY_CRC_STRING = "c054fb26"; + +} // namespace android::idmap2::TestConstants + +#endif // IDMAP2_TESTS_TESTCONSTANTS_H diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp index 3f2f3495ae8f..f87f98a59a12 100644 --- a/libs/androidfw/Android.bp +++ b/libs/androidfw/Android.bp @@ -191,4 +191,3 @@ cc_benchmark { shared_libs: common_test_libs, data: ["tests/data/**/*.apk"], } - diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h index 35cebd425dc7..d15a3a27cbb1 100644 --- a/libs/androidfw/include/androidfw/ResourceTypes.h +++ b/libs/androidfw/include/androidfw/ResourceTypes.h @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -34,6 +35,7 @@ #include +#include #include namespace android { @@ -1676,42 +1678,61 @@ struct ResTable_overlayable_header */ struct ResTable_overlayable_policy_header { - struct ResChunk_header header; - + /** + * Flags for a bitmask for all possible overlayable policy options. + * + * Any changes to this set should also update aidl/android/os/OverlayablePolicy.aidl + * and proto/OverlayablePolicy.proto. + */ enum PolicyFlags : uint32_t { + // Base + NONE = 0x00000000, + // Any overlay can overlay these resources. - POLICY_PUBLIC = 0x00000001, + PUBLIC = 0x00000001, // The overlay must reside of the system partition or must have existed on the system partition // before an upgrade to overlay these resources. - POLICY_SYSTEM_PARTITION = 0x00000002, + SYSTEM_PARTITION = 0x00000002, // The overlay must reside of the vendor partition or must have existed on the vendor partition // before an upgrade to overlay these resources. - POLICY_VENDOR_PARTITION = 0x00000004, + VENDOR_PARTITION = 0x00000004, // The overlay must reside of the product partition or must have existed on the product // partition before an upgrade to overlay these resources. - POLICY_PRODUCT_PARTITION = 0x00000008, + PRODUCT_PARTITION = 0x00000008, // The overlay must be signed with the same signature as the actor of the target resource, // which can be separate or the same as the target package with the resource. - POLICY_SIGNATURE = 0x00000010, + SIGNATURE = 0x00000010, // The overlay must reside of the odm partition or must have existed on the odm // partition before an upgrade to overlay these resources. - POLICY_ODM_PARTITION = 0x00000020, + ODM_PARTITION = 0x00000020, // The overlay must reside of the oem partition or must have existed on the oem // partition before an upgrade to overlay these resources. - POLICY_OEM_PARTITION = 0x00000040, + OEM_PARTITION = 0x00000040, }; - uint32_t policy_flags; + + using PolicyBitmask = uint32_t; + + struct ResChunk_header header; + + PolicyFlags policy_flags; // The number of ResTable_ref that follow this header. uint32_t entry_count; }; +inline ResTable_overlayable_policy_header::PolicyFlags& operator |=( + ResTable_overlayable_policy_header::PolicyFlags& first, + ResTable_overlayable_policy_header::PolicyFlags second) { + first = static_cast(first | second); + return first; +} + #pragma pack(push, 1) struct Idmap_header { // Always 0x504D4449 ('IDMP') diff --git a/libs/androidfw/tests/LoadedArsc_test.cpp b/libs/androidfw/tests/LoadedArsc_test.cpp index 8615069e98dd..2d69dfe4f429 100644 --- a/libs/androidfw/tests/LoadedArsc_test.cpp +++ b/libs/androidfw/tests/LoadedArsc_test.cpp @@ -41,6 +41,8 @@ using ::testing::NotNull; using ::testing::SizeIs; using ::testing::StrEq; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + namespace android { TEST(LoadedArscTest, LoadSinglePackageArsc) { @@ -240,29 +242,29 @@ TEST(LoadedArscTest, LoadOverlayable) { ASSERT_THAT(info, NotNull()); EXPECT_THAT(info->name, Eq("OverlayableResources1")); EXPECT_THAT(info->actor, Eq("overlay://theme")); - EXPECT_THAT(info->policy_flags, Eq(ResTable_overlayable_policy_header::POLICY_PUBLIC)); + EXPECT_THAT(info->policy_flags, Eq(PolicyFlags::PUBLIC)); info = package->GetOverlayableInfo(overlayable::R::string::overlayable2); ASSERT_THAT(info, NotNull()); EXPECT_THAT(info->name, Eq("OverlayableResources1")); EXPECT_THAT(info->actor, Eq("overlay://theme")); EXPECT_THAT(info->policy_flags, - Eq(ResTable_overlayable_policy_header::POLICY_SYSTEM_PARTITION - | ResTable_overlayable_policy_header::POLICY_PRODUCT_PARTITION)); + Eq(PolicyFlags::SYSTEM_PARTITION + | PolicyFlags::PRODUCT_PARTITION)); info = package->GetOverlayableInfo(overlayable::R::string::overlayable3); ASSERT_THAT(info, NotNull()); EXPECT_THAT(info->name, Eq("OverlayableResources2")); EXPECT_THAT(info->actor, Eq("overlay://com.android.overlayable")); EXPECT_THAT(info->policy_flags, - Eq(ResTable_overlayable_policy_header::POLICY_VENDOR_PARTITION - | ResTable_overlayable_policy_header::POLICY_PRODUCT_PARTITION)); + Eq(PolicyFlags::VENDOR_PARTITION + | PolicyFlags::PRODUCT_PARTITION)); info = package->GetOverlayableInfo(overlayable::R::string::overlayable4); EXPECT_THAT(info->name, Eq("OverlayableResources1")); EXPECT_THAT(info->actor, Eq("overlay://theme")); ASSERT_THAT(info, NotNull()); - EXPECT_THAT(info->policy_flags, Eq(ResTable_overlayable_policy_header::POLICY_PUBLIC)); + EXPECT_THAT(info->policy_flags, Eq(PolicyFlags::PUBLIC)); } TEST(LoadedArscTest, ResourceIdentifierIterator) { diff --git a/services/core/Android.bp b/services/core/Android.bp index 3180ceb8f8e1..84ce34b4676f 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -127,6 +127,8 @@ java_library_static { "android.hidl.manager-V1.2-java", "dnsresolver_aidl_interface-V2-java", "netd_event_listener_interface-java", + "ike-stubs", + "overlayable_policy_aidl-java", ], plugins: [ diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java index f3c912817d05..48a1afd2be59 100644 --- a/services/core/java/com/android/server/om/IdmapManager.java +++ b/services/core/java/com/android/server/om/IdmapManager.java @@ -24,7 +24,7 @@ import android.content.om.OverlayInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.os.Build.VERSION_CODES; -import android.os.IIdmap2; +import android.os.OverlayablePolicy; import android.os.SystemProperties; import android.os.UserHandle; import android.util.Slog; @@ -148,38 +148,38 @@ class IdmapManager { private int calculateFulfilledPolicies(@NonNull final PackageInfo targetPackage, @NonNull final PackageInfo overlayPackage, int userId) { final ApplicationInfo ai = overlayPackage.applicationInfo; - int fulfilledPolicies = IIdmap2.POLICY_PUBLIC; + int fulfilledPolicies = OverlayablePolicy.PUBLIC; // Overlay matches target signature if (mPackageManager.signaturesMatching(targetPackage.packageName, overlayPackage.packageName, userId)) { - fulfilledPolicies |= IIdmap2.POLICY_SIGNATURE; + fulfilledPolicies |= OverlayablePolicy.SIGNATURE; } // Vendor partition (/vendor) if (ai.isVendor()) { - return fulfilledPolicies | IIdmap2.POLICY_VENDOR_PARTITION; + return fulfilledPolicies | OverlayablePolicy.VENDOR_PARTITION; } // Product partition (/product) if (ai.isProduct()) { - return fulfilledPolicies | IIdmap2.POLICY_PRODUCT_PARTITION; + return fulfilledPolicies | OverlayablePolicy.PRODUCT_PARTITION; } // Odm partition (/odm) if (ai.isOdm()) { - return fulfilledPolicies | IIdmap2.POLICY_ODM_PARTITION; + return fulfilledPolicies | OverlayablePolicy.ODM_PARTITION; } // Oem partition (/oem) if (ai.isOem()) { - return fulfilledPolicies | IIdmap2.POLICY_OEM_PARTITION; + return fulfilledPolicies | OverlayablePolicy.OEM_PARTITION; } // System_ext partition (/system_ext) is considered as system // Check this last since every partition except for data is scanned as system in the PMS. if (ai.isSystemApp() || ai.isSystemExt()) { - return fulfilledPolicies | IIdmap2.POLICY_SYSTEM_PARTITION; + return fulfilledPolicies | OverlayablePolicy.SYSTEM_PARTITION; } return fulfilledPolicies; diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp index 6f442300bce7..c1d05e47bc19 100644 --- a/tools/aapt2/Android.bp +++ b/tools/aapt2/Android.bp @@ -59,6 +59,7 @@ cc_defaults { "libprotobuf-cpp-full", "libz", "libbuildversion", + "libidmap2_policies", ], stl: "libc++_static", group_static_libs: true, diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp index 137fbd671865..1eb7d95f381a 100644 --- a/tools/aapt2/Debug.cpp +++ b/tools/aapt2/Debug.cpp @@ -32,10 +32,16 @@ #include "text/Printer.h" #include "util/Util.h" +#include "idmap2/Policies.h" + using ::aapt::text::Printer; using ::android::StringPiece; using ::android::base::StringPrintf; +using android::idmap2::policy::kPolicyStringToFlag; + +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + namespace aapt { namespace { @@ -246,32 +252,25 @@ class ValueBodyPrinter : public ConstValueVisitor { Printer* printer_; }; -std::string OverlayablePoliciesToString(OverlayableItem::PolicyFlags policies) { - static const std::map kFlagToString = { - {OverlayableItem::kPublic, "public"}, - {OverlayableItem::kSystem, "system"}, - {OverlayableItem::kVendor, "vendor"}, - {OverlayableItem::kProduct, "product"}, - {OverlayableItem::kSignature, "signature"}, - {OverlayableItem::kOdm, "odm"}, - {OverlayableItem::kOem, "oem"}, - }; +std::string OverlayablePoliciesToString(PolicyFlags policies) { std::string str; - for (auto const& policy : kFlagToString) { - if ((policies & policy.first) != policy.first) { + + uint32_t remaining = policies; + for (auto const& policy : kPolicyStringToFlag) { + if ((policies & policy.second) != policy.second) { continue; } if (!str.empty()) { str.append("|"); } - str.append(policy.second); - policies &= ~policy.first; + str.append(policy.first.data()); + remaining &= ~policy.second; } - if (policies != 0) { + if (remaining != 0) { if (!str.empty()) { str.append("|"); } - str.append(StringPrintf("0x%08x", policies)); + str.append(StringPrintf("0x%08x", remaining)); } return !str.empty() ? str : "none"; } diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index 74e2a0987c3f..234cbc4b37e0 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -32,11 +32,15 @@ #include "util/Util.h" #include "xml/XmlPullParser.h" +#include "idmap2/Policies.h" + using ::aapt::ResourceUtils::StringBuilder; using ::aapt::text::Utf8Iterator; using ::android::ConfigDescription; using ::android::StringPiece; +using android::idmap2::policy::kPolicyStringToFlag; + namespace aapt { constexpr const char* sXliffNamespaceUri = "urn:oasis:names:tc:xliff:document:1.2"; @@ -1063,7 +1067,7 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource bool error = false; std::string comment; - OverlayableItem::PolicyFlags current_policies = OverlayableItem::Policy::kNone; + PolicyFlags current_policies = PolicyFlags::NONE; const size_t start_depth = parser->depth(); while (xml::XmlPullParser::IsGoodEvent(parser->Next())) { xml::XmlPullParser::Event event = parser->event(); @@ -1073,7 +1077,7 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource } else if (event == xml::XmlPullParser::Event::kEndElement && parser->depth() == start_depth + 1) { // Clear the current policies when exiting the tags - current_policies = OverlayableItem::Policy::kNone; + current_policies = PolicyFlags::NONE; continue; } else if (event == xml::XmlPullParser::Event::kComment) { // Retrieve the comment of individual tags @@ -1088,7 +1092,7 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource const std::string& element_name = parser->element_name(); const std::string& element_namespace = parser->element_namespace(); if (element_namespace.empty() && element_name == "item") { - if (current_policies == OverlayableItem::Policy::kNone) { + if (current_policies == PolicyFlags::NONE) { diag_->Error(DiagMessage(element_source) << " within an must be inside a block"); error = true; @@ -1133,7 +1137,7 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource out_resource->child_resources.push_back(std::move(child_resource)); } else if (element_namespace.empty() && element_name == "policy") { - if (current_policies != OverlayableItem::Policy::kNone) { + if (current_policies != PolicyFlags::NONE) { // If the policy list is not empty, then we are currently inside a policy element diag_->Error(DiagMessage(element_source) << " blocks cannot be recursively nested"); error = true; @@ -1141,21 +1145,14 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource } else if (Maybe maybe_type = xml::FindNonEmptyAttribute(parser, "type")) { // Parse the polices separated by vertical bar characters to allow for specifying multiple // policies. Items within the policy tag will have the specified policy. - static const auto kPolicyMap = - ImmutableMap::CreatePreSorted({ - {"odm", OverlayableItem::Policy::kOdm}, - {"oem", OverlayableItem::Policy::kOem}, - {"product", OverlayableItem::Policy::kProduct}, - {"public", OverlayableItem::Policy::kPublic}, - {"signature", OverlayableItem::Policy::kSignature}, - {"system", OverlayableItem::Policy::kSystem}, - {"vendor", OverlayableItem::Policy::kVendor}, - }); - for (const StringPiece& part : util::Tokenize(maybe_type.value(), '|')) { StringPiece trimmed_part = util::TrimWhitespace(part); - const auto policy = kPolicyMap.find(trimmed_part); - if (policy == kPolicyMap.end()) { + const auto policy = std::find_if(kPolicyStringToFlag.begin(), + kPolicyStringToFlag.end(), + [trimmed_part](const auto& it) { + return trimmed_part == it.first; + }); + if (policy == kPolicyStringToFlag.end()) { diag_->Error(DiagMessage(element_source) << " has unsupported type '" << trimmed_part << "'"); error = true; diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp index 24531bc16445..77e7fc55a229 100644 --- a/tools/aapt2/ResourceParser_test.cpp +++ b/tools/aapt2/ResourceParser_test.cpp @@ -41,6 +41,8 @@ using ::testing::Pointee; using ::testing::SizeIs; using ::testing::StrEq; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + namespace aapt { constexpr const char* kXmlPreamble = "\n"; @@ -959,7 +961,7 @@ TEST_F(ResourceParserTest, ParseOverlayable) { OverlayableItem& result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); EXPECT_THAT(result_overlayable_item.overlayable->actor, Eq("overlay://theme")); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kSignature)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::SIGNATURE)); search_result = table_.FindResource(test::ParseNameOrDie("drawable/bar")); ASSERT_TRUE(search_result); @@ -968,7 +970,7 @@ TEST_F(ResourceParserTest, ParseOverlayable) { result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); EXPECT_THAT(result_overlayable_item.overlayable->actor, Eq("overlay://theme")); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kSignature)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::SIGNATURE)); } TEST_F(ResourceParserTest, ParseOverlayableRequiresName) { @@ -1014,7 +1016,7 @@ TEST_F(ResourceParserTest, ParseOverlayablePolicy) { ASSERT_TRUE(search_result.value().entry->overlayable_item); OverlayableItem result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kProduct)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::PRODUCT_PARTITION)); search_result = table_.FindResource(test::ParseNameOrDie("string/fiz")); ASSERT_TRUE(search_result); @@ -1022,7 +1024,7 @@ TEST_F(ResourceParserTest, ParseOverlayablePolicy) { ASSERT_TRUE(search_result.value().entry->overlayable_item); result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kSystem)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::SYSTEM_PARTITION)); search_result = table_.FindResource(test::ParseNameOrDie("string/fuz")); ASSERT_TRUE(search_result); @@ -1030,7 +1032,7 @@ TEST_F(ResourceParserTest, ParseOverlayablePolicy) { ASSERT_TRUE(search_result.value().entry->overlayable_item); result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kVendor)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::VENDOR_PARTITION)); search_result = table_.FindResource(test::ParseNameOrDie("string/faz")); ASSERT_TRUE(search_result); @@ -1038,7 +1040,7 @@ TEST_F(ResourceParserTest, ParseOverlayablePolicy) { ASSERT_TRUE(search_result.value().entry->overlayable_item); result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kPublic)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::PUBLIC)); search_result = table_.FindResource(test::ParseNameOrDie("string/foz")); ASSERT_TRUE(search_result); @@ -1046,7 +1048,7 @@ TEST_F(ResourceParserTest, ParseOverlayablePolicy) { ASSERT_TRUE(search_result.value().entry->overlayable_item); result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kSignature)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::SIGNATURE)); search_result = table_.FindResource(test::ParseNameOrDie("string/biz")); ASSERT_TRUE(search_result); @@ -1054,7 +1056,7 @@ TEST_F(ResourceParserTest, ParseOverlayablePolicy) { ASSERT_TRUE(search_result.value().entry->overlayable_item); result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kOdm)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::ODM_PARTITION)); search_result = table_.FindResource(test::ParseNameOrDie("string/buz")); ASSERT_TRUE(search_result); @@ -1062,7 +1064,7 @@ TEST_F(ResourceParserTest, ParseOverlayablePolicy) { ASSERT_TRUE(search_result.value().entry->overlayable_item); result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kOem)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::OEM_PARTITION)); } TEST_F(ResourceParserTest, ParseOverlayableNoPolicyError) { @@ -1125,8 +1127,8 @@ TEST_F(ResourceParserTest, ParseOverlayableMultiplePolicy) { ASSERT_TRUE(search_result.value().entry->overlayable_item); OverlayableItem result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kVendor - | OverlayableItem::Policy::kPublic)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::VENDOR_PARTITION + | PolicyFlags::PUBLIC)); search_result = table_.FindResource(test::ParseNameOrDie("string/bar")); ASSERT_TRUE(search_result); @@ -1134,8 +1136,8 @@ TEST_F(ResourceParserTest, ParseOverlayableMultiplePolicy) { ASSERT_TRUE(search_result.value().entry->overlayable_item); result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kProduct - | OverlayableItem::Policy::kSystem)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::PRODUCT_PARTITION + | PolicyFlags::SYSTEM_PARTITION)); } TEST_F(ResourceParserTest, DuplicateOverlayableIsError) { diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h index 30ba1aed25f8..93a7a314d6ba 100644 --- a/tools/aapt2/ResourceTable.h +++ b/tools/aapt2/ResourceTable.h @@ -36,6 +36,8 @@ #include #include +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + namespace aapt { // The Public status of a resource. @@ -75,36 +77,8 @@ struct Overlayable { struct OverlayableItem { explicit OverlayableItem(const std::shared_ptr& overlayable) : overlayable(overlayable) {} - - // Represents the types overlays that are allowed to overlay the resource. - typedef uint32_t PolicyFlags; - enum Policy : uint32_t { - kNone = 0x00000000, - - // The resource can be overlaid by any overlay. - kPublic = 0x00000001, - - // The resource can be overlaid by any overlay on the system partition. - kSystem = 0x00000002, - - // The resource can be overlaid by any overlay on the vendor partition. - kVendor = 0x00000004, - - // The resource can be overlaid by any overlay on the product partition. - kProduct = 0x00000008, - - // The resource can be overlaid by any overlay signed with the same signature as its actor. - kSignature = 0x00000010, - - // The resource can be overlaid by any overlay on the odm partition. - kOdm = 0x00000020, - - // The resource can be overlaid by any overlay on the oem partition. - kOem = 0x00000040, - }; - std::shared_ptr overlayable; - PolicyFlags policies = Policy::kNone; + PolicyFlags policies = PolicyFlags::NONE; std::string comment; Source source; }; diff --git a/tools/aapt2/ResourceTable_test.cpp b/tools/aapt2/ResourceTable_test.cpp index b97dc6b205ca..9271a7e6bae1 100644 --- a/tools/aapt2/ResourceTable_test.cpp +++ b/tools/aapt2/ResourceTable_test.cpp @@ -30,6 +30,8 @@ using ::testing::Eq; using ::testing::NotNull; using ::testing::StrEq; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + namespace aapt { TEST(ResourceTableTest, FailToAddResourceWithBadName) { @@ -247,8 +249,8 @@ TEST(ResourceTableTest, SetOverlayable) { auto overlayable = std::make_shared("Name", "overlay://theme", Source("res/values/overlayable.xml", 40)); OverlayableItem overlayable_item(overlayable); - overlayable_item.policies |= OverlayableItem::Policy::kProduct; - overlayable_item.policies |= OverlayableItem::Policy::kVendor; + overlayable_item.policies |= PolicyFlags::PRODUCT_PARTITION; + overlayable_item.policies |= PolicyFlags::VENDOR_PARTITION; overlayable_item.comment = "comment"; overlayable_item.source = Source("res/values/overlayable.xml", 42); @@ -264,8 +266,8 @@ TEST(ResourceTableTest, SetOverlayable) { EXPECT_THAT(result_overlayable_item.overlayable->actor, Eq("overlay://theme")); EXPECT_THAT(result_overlayable_item.overlayable->source.path, Eq("res/values/overlayable.xml")); EXPECT_THAT(result_overlayable_item.overlayable->source.line, 40); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kProduct - | OverlayableItem::Policy::kVendor)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::PRODUCT_PARTITION + | PolicyFlags::VENDOR_PARTITION)); ASSERT_THAT(result_overlayable_item.comment, StrEq("comment")); EXPECT_THAT(result_overlayable_item.source.path, Eq("res/values/overlayable.xml")); EXPECT_THAT(result_overlayable_item.source.line, 42); @@ -277,17 +279,17 @@ TEST(ResourceTableTest, SetMultipleOverlayableResources) { const ResourceName foo = test::ParseNameOrDie("android:string/foo"); auto group = std::make_shared("Name", "overlay://theme"); OverlayableItem overlayable(group); - overlayable.policies = OverlayableItem::Policy::kProduct; + overlayable.policies = PolicyFlags::PRODUCT_PARTITION; ASSERT_TRUE(table.SetOverlayable(foo, overlayable, test::GetDiagnostics())); const ResourceName bar = test::ParseNameOrDie("android:string/bar"); OverlayableItem overlayable2(group); - overlayable2.policies = OverlayableItem::Policy::kProduct; + overlayable2.policies = PolicyFlags::PRODUCT_PARTITION; ASSERT_TRUE(table.SetOverlayable(bar, overlayable2, test::GetDiagnostics())); const ResourceName baz = test::ParseNameOrDie("android:string/baz"); OverlayableItem overlayable3(group); - overlayable3.policies = OverlayableItem::Policy::kVendor; + overlayable3.policies = PolicyFlags::VENDOR_PARTITION; ASSERT_TRUE(table.SetOverlayable(baz, overlayable3, test::GetDiagnostics())); } @@ -296,12 +298,12 @@ TEST(ResourceTableTest, SetOverlayableDifferentResourcesDifferentName) { const ResourceName foo = test::ParseNameOrDie("android:string/foo"); OverlayableItem overlayable_item(std::make_shared("Name", "overlay://theme")); - overlayable_item.policies = OverlayableItem::Policy::kProduct; + overlayable_item.policies = PolicyFlags::PRODUCT_PARTITION; ASSERT_TRUE(table.SetOverlayable(foo, overlayable_item, test::GetDiagnostics())); const ResourceName bar = test::ParseNameOrDie("android:string/bar"); OverlayableItem overlayable_item2(std::make_shared("Name2", "overlay://theme")); - overlayable_item2.policies = OverlayableItem::Policy::kProduct; + overlayable_item2.policies = PolicyFlags::PRODUCT_PARTITION; ASSERT_TRUE(table.SetOverlayable(bar, overlayable_item2, test::GetDiagnostics())); } diff --git a/tools/aapt2/format/binary/BinaryResourceParser.cpp b/tools/aapt2/format/binary/BinaryResourceParser.cpp index fcd6aaafba7a..f362744c0942 100644 --- a/tools/aapt2/format/binary/BinaryResourceParser.cpp +++ b/tools/aapt2/format/binary/BinaryResourceParser.cpp @@ -455,35 +455,6 @@ bool BinaryResourceParser::ParseOverlayable(const ResChunk_header* chunk) { const ResTable_overlayable_policy_header* policy_header = ConvertTo(parser.chunk()); - OverlayableItem::PolicyFlags policies = OverlayableItem::Policy::kNone; - if (policy_header->policy_flags & ResTable_overlayable_policy_header::POLICY_PUBLIC) { - policies |= OverlayableItem::Policy::kPublic; - } - if (policy_header->policy_flags - & ResTable_overlayable_policy_header::POLICY_SYSTEM_PARTITION) { - policies |= OverlayableItem::Policy::kSystem; - } - if (policy_header->policy_flags - & ResTable_overlayable_policy_header::POLICY_VENDOR_PARTITION) { - policies |= OverlayableItem::Policy::kVendor; - } - if (policy_header->policy_flags - & ResTable_overlayable_policy_header::POLICY_PRODUCT_PARTITION) { - policies |= OverlayableItem::Policy::kProduct; - } - if (policy_header->policy_flags - & ResTable_overlayable_policy_header::POLICY_SIGNATURE) { - policies |= OverlayableItem::Policy::kSignature; - } - if (policy_header->policy_flags - & ResTable_overlayable_policy_header::POLICY_ODM_PARTITION) { - policies |= OverlayableItem::Policy::kOdm; - } - if (policy_header->policy_flags - & ResTable_overlayable_policy_header::POLICY_OEM_PARTITION) { - policies |= OverlayableItem::Policy::kOem; - } - const ResTable_ref* const ref_begin = reinterpret_cast( ((uint8_t *)policy_header) + util::DeviceToHost32(policy_header->header.headerSize)); const ResTable_ref* const ref_end = ref_begin @@ -501,7 +472,7 @@ bool BinaryResourceParser::ParseOverlayable(const ResChunk_header* chunk) { } OverlayableItem overlayable_item(overlayable); - overlayable_item.policies = policies; + overlayable_item.policies = policy_header->policy_flags; if (!table_->SetOverlayable(iter->second, overlayable_item, diag_)) { return false; } diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp index cbce8a59bae3..4784ecf3d12c 100644 --- a/tools/aapt2/format/binary/TableFlattener.cpp +++ b/tools/aapt2/format/binary/TableFlattener.cpp @@ -233,7 +233,7 @@ class MapFlattenVisitor : public ValueVisitor { struct OverlayableChunk { std::string actor; Source source; - std::map> policy_ids; + std::map> policy_ids; }; class PackageFlattener { @@ -493,35 +493,12 @@ class PackageFlattener { return false; } - uint32_t policy_flags = 0; - if (item.policies & OverlayableItem::Policy::kPublic) { - policy_flags |= ResTable_overlayable_policy_header::POLICY_PUBLIC; - } - if (item.policies & OverlayableItem::Policy::kSystem) { - policy_flags |= ResTable_overlayable_policy_header::POLICY_SYSTEM_PARTITION; - } - if (item.policies & OverlayableItem::Policy::kVendor) { - policy_flags |= ResTable_overlayable_policy_header::POLICY_VENDOR_PARTITION; - } - if (item.policies & OverlayableItem::Policy::kProduct) { - policy_flags |= ResTable_overlayable_policy_header::POLICY_PRODUCT_PARTITION; - } - if (item.policies & OverlayableItem::Policy::kSignature) { - policy_flags |= ResTable_overlayable_policy_header::POLICY_SIGNATURE; - } - if (item.policies & OverlayableItem::Policy::kOdm) { - policy_flags |= ResTable_overlayable_policy_header::POLICY_ODM_PARTITION; - } - if (item.policies & OverlayableItem::Policy::kOem) { - policy_flags |= ResTable_overlayable_policy_header::POLICY_OEM_PARTITION; - } - - auto policy = overlayable_chunk->policy_ids.find(policy_flags); + auto policy = overlayable_chunk->policy_ids.find(item.policies); if (policy != overlayable_chunk->policy_ids.end()) { policy->second.insert(id); } else { overlayable_chunk->policy_ids.insert( - std::make_pair(policy_flags, std::set{id})); + std::make_pair(item.policies, std::set{id})); } } } @@ -559,7 +536,8 @@ class PackageFlattener { ChunkWriter policy_writer(buffer); auto* policy_type = policy_writer.StartChunk( RES_TABLE_OVERLAYABLE_POLICY_TYPE); - policy_type->policy_flags = util::HostToDevice32(static_cast(policy_ids.first)); + policy_type->policy_flags = + static_cast(util::HostToDevice32(static_cast(policy_ids.first))); policy_type->entry_count = util::HostToDevice32(static_cast( policy_ids.second.size())); // Write the ids after the policy header diff --git a/tools/aapt2/format/binary/TableFlattener_test.cpp b/tools/aapt2/format/binary/TableFlattener_test.cpp index af2293f0f82b..e1e0f17c8dbb 100644 --- a/tools/aapt2/format/binary/TableFlattener_test.cpp +++ b/tools/aapt2/format/binary/TableFlattener_test.cpp @@ -32,6 +32,8 @@ using ::testing::Gt; using ::testing::IsNull; using ::testing::NotNull; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + namespace aapt { class TableFlattenerTest : public ::testing::Test { @@ -671,9 +673,9 @@ TEST_F(TableFlattenerTest, ObfuscatingResourceNamesWithNameCollapseExemptionsSuc TEST_F(TableFlattenerTest, FlattenOverlayable) { OverlayableItem overlayable_item(std::make_shared("TestName", "overlay://theme")); - overlayable_item.policies |= OverlayableItem::Policy::kProduct; - overlayable_item.policies |= OverlayableItem::Policy::kSystem; - overlayable_item.policies |= OverlayableItem::Policy::kVendor; + overlayable_item.policies |= PolicyFlags::PRODUCT_PARTITION; + overlayable_item.policies |= PolicyFlags::SYSTEM_PARTITION; + overlayable_item.policies |= PolicyFlags::VENDOR_PARTITION; std::string name = "com.app.test:integer/overlayable"; std::unique_ptr table = @@ -691,27 +693,27 @@ TEST_F(TableFlattenerTest, FlattenOverlayable) { ASSERT_THAT(search_result.value().entry, NotNull()); ASSERT_TRUE(search_result.value().entry->overlayable_item); OverlayableItem& result_overlayable_item = search_result.value().entry->overlayable_item.value(); - EXPECT_EQ(result_overlayable_item.policies, OverlayableItem::Policy::kSystem - | OverlayableItem::Policy::kVendor - | OverlayableItem::Policy::kProduct); + EXPECT_EQ(result_overlayable_item.policies, PolicyFlags::SYSTEM_PARTITION + | PolicyFlags::VENDOR_PARTITION + | PolicyFlags::PRODUCT_PARTITION); } TEST_F(TableFlattenerTest, FlattenMultipleOverlayablePolicies) { auto overlayable = std::make_shared("TestName", "overlay://theme"); std::string name_zero = "com.app.test:integer/overlayable_zero_item"; OverlayableItem overlayable_item_zero(overlayable); - overlayable_item_zero.policies |= OverlayableItem::Policy::kProduct; - overlayable_item_zero.policies |= OverlayableItem::Policy::kSystem; + overlayable_item_zero.policies |= PolicyFlags::PRODUCT_PARTITION; + overlayable_item_zero.policies |= PolicyFlags::SYSTEM_PARTITION; std::string name_one = "com.app.test:integer/overlayable_one_item"; OverlayableItem overlayable_item_one(overlayable); - overlayable_item_one.policies |= OverlayableItem::Policy::kPublic; + overlayable_item_one.policies |= PolicyFlags::PUBLIC; std::string name_two = "com.app.test:integer/overlayable_two_item"; OverlayableItem overlayable_item_two(overlayable); - overlayable_item_two.policies |= OverlayableItem::Policy::kProduct; - overlayable_item_two.policies |= OverlayableItem::Policy::kSystem; - overlayable_item_two.policies |= OverlayableItem::Policy::kVendor; + overlayable_item_two.policies |= PolicyFlags::PRODUCT_PARTITION; + overlayable_item_two.policies |= PolicyFlags::SYSTEM_PARTITION; + overlayable_item_two.policies |= PolicyFlags::VENDOR_PARTITION; std::unique_ptr table = test::ResourceTableBuilder() @@ -732,47 +734,47 @@ TEST_F(TableFlattenerTest, FlattenMultipleOverlayablePolicies) { ASSERT_THAT(search_result.value().entry, NotNull()); ASSERT_TRUE(search_result.value().entry->overlayable_item); OverlayableItem& overlayable_item = search_result.value().entry->overlayable_item.value(); - EXPECT_EQ(overlayable_item.policies, OverlayableItem::Policy::kSystem - | OverlayableItem::Policy::kProduct); + EXPECT_EQ(overlayable_item.policies, PolicyFlags::SYSTEM_PARTITION + | PolicyFlags::PRODUCT_PARTITION); search_result = output_table.FindResource(test::ParseNameOrDie(name_one)); ASSERT_TRUE(search_result); ASSERT_THAT(search_result.value().entry, NotNull()); ASSERT_TRUE(search_result.value().entry->overlayable_item); overlayable_item = search_result.value().entry->overlayable_item.value(); - EXPECT_EQ(overlayable_item.policies, OverlayableItem::Policy::kPublic); + EXPECT_EQ(overlayable_item.policies, PolicyFlags::PUBLIC); search_result = output_table.FindResource(test::ParseNameOrDie(name_two)); ASSERT_TRUE(search_result); ASSERT_THAT(search_result.value().entry, NotNull()); ASSERT_TRUE(search_result.value().entry->overlayable_item); overlayable_item = search_result.value().entry->overlayable_item.value(); - EXPECT_EQ(overlayable_item.policies, OverlayableItem::Policy::kSystem - | OverlayableItem::Policy::kProduct - | OverlayableItem::Policy::kVendor); + EXPECT_EQ(overlayable_item.policies, PolicyFlags::SYSTEM_PARTITION + | PolicyFlags::PRODUCT_PARTITION + | PolicyFlags::VENDOR_PARTITION); } TEST_F(TableFlattenerTest, FlattenMultipleOverlayable) { auto group = std::make_shared("TestName", "overlay://theme"); std::string name_zero = "com.app.test:integer/overlayable_zero"; OverlayableItem overlayable_item_zero(group); - overlayable_item_zero.policies |= OverlayableItem::Policy::kProduct; - overlayable_item_zero.policies |= OverlayableItem::Policy::kSystem; + overlayable_item_zero.policies |= PolicyFlags::PRODUCT_PARTITION; + overlayable_item_zero.policies |= PolicyFlags::SYSTEM_PARTITION; auto group_one = std::make_shared("OtherName", "overlay://customization"); std::string name_one = "com.app.test:integer/overlayable_one"; OverlayableItem overlayable_item_one(group_one); - overlayable_item_one.policies |= OverlayableItem::Policy::kPublic; + overlayable_item_one.policies |= PolicyFlags::PUBLIC; std::string name_two = "com.app.test:integer/overlayable_two"; OverlayableItem overlayable_item_two(group); - overlayable_item_two.policies |= OverlayableItem::Policy::kOdm; - overlayable_item_two.policies |= OverlayableItem::Policy::kOem; - overlayable_item_two.policies |= OverlayableItem::Policy::kVendor; + overlayable_item_two.policies |= PolicyFlags::ODM_PARTITION; + overlayable_item_two.policies |= PolicyFlags::OEM_PARTITION; + overlayable_item_two.policies |= PolicyFlags::VENDOR_PARTITION; std::string name_three = "com.app.test:integer/overlayable_three"; OverlayableItem overlayable_item_three(group_one); - overlayable_item_three.policies |= OverlayableItem::Policy::kSignature; + overlayable_item_three.policies |= PolicyFlags::SIGNATURE; std::unique_ptr table = test::ResourceTableBuilder() @@ -796,8 +798,8 @@ TEST_F(TableFlattenerTest, FlattenMultipleOverlayable) { OverlayableItem& result_overlayable = search_result.value().entry->overlayable_item.value(); EXPECT_EQ(result_overlayable.overlayable->name, "TestName"); EXPECT_EQ(result_overlayable.overlayable->actor, "overlay://theme"); - EXPECT_EQ(result_overlayable.policies, OverlayableItem::Policy::kSystem - | OverlayableItem::Policy::kProduct); + EXPECT_EQ(result_overlayable.policies, PolicyFlags::SYSTEM_PARTITION + | PolicyFlags::PRODUCT_PARTITION); search_result = output_table.FindResource(test::ParseNameOrDie(name_one)); ASSERT_TRUE(search_result); @@ -806,7 +808,7 @@ TEST_F(TableFlattenerTest, FlattenMultipleOverlayable) { result_overlayable = search_result.value().entry->overlayable_item.value(); EXPECT_EQ(result_overlayable.overlayable->name, "OtherName"); EXPECT_EQ(result_overlayable.overlayable->actor, "overlay://customization"); - EXPECT_EQ(result_overlayable.policies, OverlayableItem::Policy::kPublic); + EXPECT_EQ(result_overlayable.policies, PolicyFlags::PUBLIC); search_result = output_table.FindResource(test::ParseNameOrDie(name_two)); ASSERT_TRUE(search_result); @@ -815,9 +817,9 @@ TEST_F(TableFlattenerTest, FlattenMultipleOverlayable) { result_overlayable = search_result.value().entry->overlayable_item.value(); EXPECT_EQ(result_overlayable.overlayable->name, "TestName"); EXPECT_EQ(result_overlayable.overlayable->actor, "overlay://theme"); - EXPECT_EQ(result_overlayable.policies, OverlayableItem::Policy::kOdm - | OverlayableItem::Policy::kOem - | OverlayableItem::Policy::kVendor); + EXPECT_EQ(result_overlayable.policies, PolicyFlags::ODM_PARTITION + | PolicyFlags::OEM_PARTITION + | PolicyFlags::VENDOR_PARTITION); search_result = output_table.FindResource(test::ParseNameOrDie(name_three)); ASSERT_TRUE(search_result); @@ -826,7 +828,7 @@ TEST_F(TableFlattenerTest, FlattenMultipleOverlayable) { result_overlayable = search_result.value().entry->overlayable_item.value(); EXPECT_EQ(result_overlayable.overlayable->name, "OtherName"); EXPECT_EQ(result_overlayable.overlayable->actor, "overlay://customization"); - EXPECT_EQ(result_overlayable.policies, OverlayableItem::Policy::kSignature); + EXPECT_EQ(result_overlayable.policies, PolicyFlags::SIGNATURE); } TEST_F(TableFlattenerTest, FlattenOverlayableNoPolicyFails) { diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp index 4cd6e930915d..db8e093594a0 100644 --- a/tools/aapt2/format/proto/ProtoDeserialize.cpp +++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp @@ -30,6 +30,8 @@ using ::android::ConfigDescription; using ::android::LocaleValue; using ::android::ResStringPool; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + namespace aapt { namespace { @@ -379,25 +381,25 @@ bool DeserializeOverlayableItemFromPb(const pb::OverlayableItem& pb_overlayable, for (const int policy : pb_overlayable.policy()) { switch (policy) { case pb::OverlayableItem::PUBLIC: - out_overlayable->policies |= OverlayableItem::Policy::kPublic; + out_overlayable->policies |= PolicyFlags::PUBLIC; break; case pb::OverlayableItem::SYSTEM: - out_overlayable->policies |= OverlayableItem::Policy::kSystem; + out_overlayable->policies |= PolicyFlags::SYSTEM_PARTITION; break; case pb::OverlayableItem::VENDOR: - out_overlayable->policies |= OverlayableItem::Policy::kVendor; + out_overlayable->policies |= PolicyFlags::VENDOR_PARTITION; break; case pb::OverlayableItem::PRODUCT: - out_overlayable->policies |= OverlayableItem::Policy::kProduct; + out_overlayable->policies |= PolicyFlags::PRODUCT_PARTITION; break; case pb::OverlayableItem::SIGNATURE: - out_overlayable->policies |= OverlayableItem::Policy::kSignature; + out_overlayable->policies |= PolicyFlags::SIGNATURE; break; case pb::OverlayableItem::ODM: - out_overlayable->policies |= OverlayableItem::Policy::kOdm; + out_overlayable->policies |= PolicyFlags::ODM_PARTITION; break; case pb::OverlayableItem::OEM: - out_overlayable->policies |= OverlayableItem::Policy::kOem; + out_overlayable->policies |= PolicyFlags::OEM_PARTITION; break; default: *out_error = "unknown overlayable policy"; diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp index d9f6c193fc2f..6bc4524d3d5c 100644 --- a/tools/aapt2/format/proto/ProtoSerialize.cpp +++ b/tools/aapt2/format/proto/ProtoSerialize.cpp @@ -21,6 +21,8 @@ using android::ConfigDescription; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + namespace aapt { void SerializeStringPoolToPb(const StringPool& pool, pb::StringPool* out_pb_pool, IDiagnostics* diag) { @@ -299,25 +301,25 @@ static void SerializeOverlayableItemToPb(const OverlayableItem& overlayable_item pb::OverlayableItem* pb_overlayable_item = pb_entry->mutable_overlayable_item(); pb_overlayable_item->set_overlayable_idx(i); - if (overlayable_item.policies & OverlayableItem::Policy::kPublic) { + if (overlayable_item.policies & PolicyFlags::PUBLIC) { pb_overlayable_item->add_policy(pb::OverlayableItem::PUBLIC); } - if (overlayable_item.policies & OverlayableItem::Policy::kProduct) { + if (overlayable_item.policies & PolicyFlags::PRODUCT_PARTITION) { pb_overlayable_item->add_policy(pb::OverlayableItem::PRODUCT); } - if (overlayable_item.policies & OverlayableItem::Policy::kSystem) { + if (overlayable_item.policies & PolicyFlags::SYSTEM_PARTITION) { pb_overlayable_item->add_policy(pb::OverlayableItem::SYSTEM); } - if (overlayable_item.policies & OverlayableItem::Policy::kVendor) { + if (overlayable_item.policies & PolicyFlags::VENDOR_PARTITION) { pb_overlayable_item->add_policy(pb::OverlayableItem::VENDOR); } - if (overlayable_item.policies & OverlayableItem::Policy::kSignature) { + if (overlayable_item.policies & PolicyFlags::SIGNATURE) { pb_overlayable_item->add_policy(pb::OverlayableItem::SIGNATURE); } - if (overlayable_item.policies & OverlayableItem::Policy::kOdm) { + if (overlayable_item.policies & PolicyFlags::ODM_PARTITION) { pb_overlayable_item->add_policy(pb::OverlayableItem::ODM); } - if (overlayable_item.policies & OverlayableItem::Policy::kOem) { + if (overlayable_item.policies & PolicyFlags::OEM_PARTITION) { pb_overlayable_item->add_policy(pb::OverlayableItem::OEM); } diff --git a/tools/aapt2/format/proto/ProtoSerialize_test.cpp b/tools/aapt2/format/proto/ProtoSerialize_test.cpp index 61a8335e17a7..cdc86597b2f3 100644 --- a/tools/aapt2/format/proto/ProtoSerialize_test.cpp +++ b/tools/aapt2/format/proto/ProtoSerialize_test.cpp @@ -28,6 +28,8 @@ using ::testing::NotNull; using ::testing::SizeIs; using ::testing::StrEq; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + namespace aapt { class MockFileCollection : public io::IFileCollection { @@ -171,7 +173,7 @@ TEST(ProtoSerializeTest, SerializeSinglePackage) { EXPECT_THAT(result_overlayable_item.overlayable->actor, Eq("overlay://theme")); EXPECT_THAT(result_overlayable_item.overlayable->source.path, Eq("res/values/overlayable.xml")); EXPECT_THAT(result_overlayable_item.overlayable->source.line, Eq(40)); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kNone)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::NONE)); EXPECT_THAT(result_overlayable_item.source.path, Eq("res/values/overlayable.xml")); EXPECT_THAT(result_overlayable_item.source.line, Eq(42)); } @@ -516,23 +518,23 @@ TEST(ProtoSerializeTest, SerializeDeserializeConfiguration) { TEST(ProtoSerializeTest, SerializeAndDeserializeOverlayable) { OverlayableItem overlayable_item_foo(std::make_shared( "CustomizableResources", "overlay://customization")); - overlayable_item_foo.policies |= OverlayableItem::Policy::kSystem; - overlayable_item_foo.policies |= OverlayableItem::Policy::kProduct; + overlayable_item_foo.policies |= PolicyFlags::SYSTEM_PARTITION; + overlayable_item_foo.policies |= PolicyFlags::PRODUCT_PARTITION; OverlayableItem overlayable_item_bar(std::make_shared( "TaskBar", "overlay://theme")); - overlayable_item_bar.policies |= OverlayableItem::Policy::kPublic; - overlayable_item_bar.policies |= OverlayableItem::Policy::kVendor; + overlayable_item_bar.policies |= PolicyFlags::PUBLIC; + overlayable_item_bar.policies |= PolicyFlags::VENDOR_PARTITION; OverlayableItem overlayable_item_baz(std::make_shared( "FontPack", "overlay://theme")); - overlayable_item_baz.policies |= OverlayableItem::Policy::kPublic; + overlayable_item_baz.policies |= PolicyFlags::PUBLIC; OverlayableItem overlayable_item_boz(std::make_shared( "IconPack", "overlay://theme")); - overlayable_item_boz.policies |= OverlayableItem::Policy::kSignature; - overlayable_item_boz.policies |= OverlayableItem::Policy::kOdm; - overlayable_item_boz.policies |= OverlayableItem::Policy::kOem; + overlayable_item_boz.policies |= PolicyFlags::SIGNATURE; + overlayable_item_boz.policies |= PolicyFlags::ODM_PARTITION; + overlayable_item_boz.policies |= PolicyFlags::OEM_PARTITION; OverlayableItem overlayable_item_biz(std::make_shared( "Other", "overlay://customization")); @@ -565,8 +567,8 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeOverlayable) { OverlayableItem& overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(overlayable_item.overlayable->name, Eq("CustomizableResources")); EXPECT_THAT(overlayable_item.overlayable->actor, Eq("overlay://customization")); - EXPECT_THAT(overlayable_item.policies, Eq(OverlayableItem::Policy::kSystem - | OverlayableItem::Policy::kProduct)); + EXPECT_THAT(overlayable_item.policies, Eq(PolicyFlags::SYSTEM_PARTITION + | PolicyFlags::PRODUCT_PARTITION)); search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/bar")); ASSERT_TRUE(search_result); @@ -574,8 +576,8 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeOverlayable) { overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(overlayable_item.overlayable->name, Eq("TaskBar")); EXPECT_THAT(overlayable_item.overlayable->actor, Eq("overlay://theme")); - EXPECT_THAT(overlayable_item.policies, Eq(OverlayableItem::Policy::kPublic - | OverlayableItem::Policy::kVendor)); + EXPECT_THAT(overlayable_item.policies, Eq(PolicyFlags::PUBLIC + | PolicyFlags::VENDOR_PARTITION)); search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/baz")); ASSERT_TRUE(search_result); @@ -583,7 +585,7 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeOverlayable) { overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(overlayable_item.overlayable->name, Eq("FontPack")); EXPECT_THAT(overlayable_item.overlayable->actor, Eq("overlay://theme")); - EXPECT_THAT(overlayable_item.policies, Eq(OverlayableItem::Policy::kPublic)); + EXPECT_THAT(overlayable_item.policies, Eq(PolicyFlags::PUBLIC)); search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/boz")); ASSERT_TRUE(search_result); @@ -591,16 +593,16 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeOverlayable) { overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(overlayable_item.overlayable->name, Eq("IconPack")); EXPECT_THAT(overlayable_item.overlayable->actor, Eq("overlay://theme")); - EXPECT_THAT(overlayable_item.policies, Eq(OverlayableItem::Policy::kSignature - | OverlayableItem::Policy::kOdm - | OverlayableItem::Policy::kOem)); + EXPECT_THAT(overlayable_item.policies, Eq(PolicyFlags::SIGNATURE + | PolicyFlags::ODM_PARTITION + | PolicyFlags::OEM_PARTITION)); search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/biz")); ASSERT_TRUE(search_result); ASSERT_TRUE(search_result.value().entry->overlayable_item); overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(overlayable_item.overlayable->name, Eq("Other")); - EXPECT_THAT(overlayable_item.policies, Eq(OverlayableItem::Policy::kNone)); + EXPECT_THAT(overlayable_item.policies, Eq(PolicyFlags::NONE)); EXPECT_THAT(overlayable_item.comment, Eq("comment")); search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/fiz")); diff --git a/tools/aapt2/link/TableMerger_test.cpp b/tools/aapt2/link/TableMerger_test.cpp index 0be4ccf9ae85..69cf5ee7002b 100644 --- a/tools/aapt2/link/TableMerger_test.cpp +++ b/tools/aapt2/link/TableMerger_test.cpp @@ -29,6 +29,8 @@ using ::testing::Pointee; using ::testing::StrEq; using ::testing::UnorderedElementsAreArray; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; + namespace aapt { struct TableMergerTest : public ::testing::Test { @@ -487,8 +489,8 @@ TEST_F(TableMergerTest, SetOverlayable) { auto overlayable = std::make_shared("CustomizableResources", "overlay://customization"); OverlayableItem overlayable_item(overlayable); - overlayable_item.policies |= OverlayableItem::Policy::kProduct; - overlayable_item.policies |= OverlayableItem::Policy::kVendor; + overlayable_item.policies |= PolicyFlags::PRODUCT_PARTITION; + overlayable_item.policies |= PolicyFlags::VENDOR_PARTITION; std::unique_ptr table_a = test::ResourceTableBuilder() @@ -516,8 +518,8 @@ TEST_F(TableMergerTest, SetOverlayable) { OverlayableItem& result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("CustomizableResources")); EXPECT_THAT(result_overlayable_item.overlayable->actor, Eq("overlay://customization")); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kProduct - | OverlayableItem::Policy::kVendor)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::PRODUCT_PARTITION + | PolicyFlags::VENDOR_PARTITION)); } TEST_F(TableMergerTest, SetOverlayableLater) { @@ -530,8 +532,8 @@ TEST_F(TableMergerTest, SetOverlayableLater) { .Build(); OverlayableItem overlayable_item(overlayable); - overlayable_item.policies |= OverlayableItem::Policy::kPublic; - overlayable_item.policies |= OverlayableItem::Policy::kSystem; + overlayable_item.policies |= PolicyFlags::PUBLIC; + overlayable_item.policies |= PolicyFlags::SYSTEM_PARTITION; std::unique_ptr table_b = test::ResourceTableBuilder() .SetPackageId("com.app.a", 0x7f) @@ -552,15 +554,15 @@ TEST_F(TableMergerTest, SetOverlayableLater) { OverlayableItem& result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("CustomizableResources")); EXPECT_THAT(result_overlayable_item.overlayable->actor, Eq("overlay://customization")); - EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kPublic - | OverlayableItem::Policy::kSystem)); + EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::PUBLIC + | PolicyFlags::SYSTEM_PARTITION)); } TEST_F(TableMergerTest, SameResourceDifferentNameFail) { auto overlayable_first = std::make_shared("CustomizableResources", "overlay://customization"); OverlayableItem overlayable_item_first(overlayable_first); - overlayable_item_first.policies |= OverlayableItem::Policy::kProduct; + overlayable_item_first.policies |= PolicyFlags::PRODUCT_PARTITION; std::unique_ptr table_a = test::ResourceTableBuilder() .SetPackageId("com.app.a", 0x7f) @@ -570,7 +572,7 @@ TEST_F(TableMergerTest, SameResourceDifferentNameFail) { auto overlayable_second = std::make_shared("ThemeResources", "overlay://customization"); OverlayableItem overlayable_item_second(overlayable_second); - overlayable_item_second.policies |= OverlayableItem::Policy::kProduct; + overlayable_item_second.policies |= PolicyFlags::PRODUCT_PARTITION; std::unique_ptr table_b = test::ResourceTableBuilder() .SetPackageId("com.app.a", 0x7f) @@ -589,7 +591,7 @@ TEST_F(TableMergerTest, SameResourceDifferentActorFail) { auto overlayable_first = std::make_shared("CustomizableResources", "overlay://customization"); OverlayableItem overlayable_item_first(overlayable_first); - overlayable_item_first.policies |= OverlayableItem::Policy::kProduct; + overlayable_item_first.policies |= PolicyFlags::PRODUCT_PARTITION; std::unique_ptr table_a = test::ResourceTableBuilder() .SetPackageId("com.app.a", 0x7f) @@ -599,7 +601,7 @@ TEST_F(TableMergerTest, SameResourceDifferentActorFail) { auto overlayable_second = std::make_shared("CustomizableResources", "overlay://theme"); OverlayableItem overlayable_item_second(overlayable_second); - overlayable_item_second.policies |= OverlayableItem::Policy::kProduct; + overlayable_item_second.policies |= PolicyFlags::PRODUCT_PARTITION; std::unique_ptr table_b = test::ResourceTableBuilder() .SetPackageId("com.app.a", 0x7f) @@ -618,7 +620,7 @@ TEST_F(TableMergerTest, SameResourceDifferentPoliciesFail) { auto overlayable_first = std::make_shared("CustomizableResources", "overlay://customization"); OverlayableItem overlayable_item_first(overlayable_first); - overlayable_item_first.policies |= OverlayableItem::Policy::kProduct; + overlayable_item_first.policies |= PolicyFlags::PRODUCT_PARTITION; std::unique_ptr table_a = test::ResourceTableBuilder() .SetPackageId("com.app.a", 0x7f) @@ -628,7 +630,7 @@ TEST_F(TableMergerTest, SameResourceDifferentPoliciesFail) { auto overlayable_second = std::make_shared("CustomizableResources", "overlay://customization"); OverlayableItem overlayable_item_second(overlayable_second); - overlayable_item_second.policies |= OverlayableItem::Policy::kSignature; + overlayable_item_second.policies |= PolicyFlags::SIGNATURE; std::unique_ptr table_b = test::ResourceTableBuilder() .SetPackageId("com.app.a", 0x7f) @@ -648,7 +650,7 @@ TEST_F(TableMergerTest, SameResourceSameOverlayable) { "overlay://customization"); OverlayableItem overlayable_item_first(overlayable); - overlayable_item_first.policies |= OverlayableItem::Policy::kProduct; + overlayable_item_first.policies |= PolicyFlags::PRODUCT_PARTITION; std::unique_ptr table_a = test::ResourceTableBuilder() .SetPackageId("com.app.a", 0x7f) @@ -656,7 +658,7 @@ TEST_F(TableMergerTest, SameResourceSameOverlayable) { .Build(); OverlayableItem overlayable_item_second(overlayable); - overlayable_item_second.policies |= OverlayableItem::Policy::kProduct; + overlayable_item_second.policies |= PolicyFlags::PRODUCT_PARTITION; std::unique_ptr table_b = test::ResourceTableBuilder() .SetPackageId("com.app.a", 0x7f) -- cgit v1.2.3-59-g8ed1b From a707013b78cea3586fdadf9a2f04932e823d7504 Mon Sep 17 00:00:00 2001 From: Ryan Mitchell Date: Wed, 13 May 2020 14:17:52 -0700 Subject: Add policies and enforce overlayable to header If the fulfilled policies change without the contents of the target and overlay APKs changing, the idmap for the overlay should be regenerated. This change adds fulfilled policies and enforce overlayable to the idmap header so that idmap2d can determine if the polices or enforce overlayable changed from what was used to generate the idmap. Bug: 119328308 Test: idmap2_tests Test: atest RegenerateIdmapTest Change-Id: I96f970e82b5243be01b205ac2cb6ab249c6100bc --- cmds/idmap2/Android.bp | 2 +- cmds/idmap2/idmap2/CommandUtils.cpp | 49 ++++++++++ cmds/idmap2/idmap2/CommandUtils.h | 28 ++++++ cmds/idmap2/idmap2/Commands.h | 1 - cmds/idmap2/idmap2/CreateMultiple.cpp | 4 +- cmds/idmap2/idmap2/Main.cpp | 5 +- cmds/idmap2/idmap2/Scan.cpp | 14 ++- cmds/idmap2/idmap2/Verify.cpp | 59 ------------ cmds/idmap2/idmap2d/Idmap2Service.cpp | 75 ++++++++++------ cmds/idmap2/include/idmap2/Idmap.h | 17 +++- cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp | 2 + cmds/idmap2/libidmap2/Idmap.cpp | 64 +++++++++---- cmds/idmap2/libidmap2/RawPrintVisitor.cpp | 8 +- cmds/idmap2/libidmap2/ResourceMapping.cpp | 7 -- .../libidmap2_policies/include/idmap2/Policies.h | 26 ++++++ cmds/idmap2/tests/BinaryStreamVisitorTests.cpp | 5 ++ cmds/idmap2/tests/IdmapTests.cpp | 74 +++++++++++---- cmds/idmap2/tests/RawPrintVisitorTests.cpp | 41 +++++---- cmds/idmap2/tests/TestHelpers.h | 52 ++++++----- core/tests/overlaytests/remount/Android.bp | 1 + .../remounted/PackagedUpgradedTest.java | 69 -------------- .../overlaytest/remounted/RegenerateIdmapTest.java | 99 +++++++++++++++++++++ .../remount/test-apps/Overlay/Android.bp | 6 ++ .../test-apps/Overlay/res/values/values.xml | 1 + .../remount/test-apps/Target/Android.bp | 2 + .../test-apps/Target/res/values/overlayable.xml | 3 + .../remount/test-apps/Target/res/values/values.xml | 2 + .../remount/test-apps/certs/Android.bp | 19 ++++ .../test-apps/certs/rro-remounted-test-a.pk8 | Bin 0 -> 1218 bytes .../test-apps/certs/rro-remounted-test-a.x509.pem | 19 ++++ libs/androidfw/include/androidfw/ResourceTypes.h | 5 +- libs/androidfw/tests/data/overlay/overlay.apk | Bin 2988 -> 2992 bytes libs/androidfw/tests/data/overlay/overlay.idmap | Bin 1137 -> 1090 bytes tools/aapt2/Debug.cpp | 25 +----- 34 files changed, 509 insertions(+), 275 deletions(-) create mode 100644 cmds/idmap2/idmap2/CommandUtils.cpp create mode 100644 cmds/idmap2/idmap2/CommandUtils.h delete mode 100644 cmds/idmap2/idmap2/Verify.cpp delete mode 100644 core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/PackagedUpgradedTest.java create mode 100644 core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/RegenerateIdmapTest.java create mode 100644 core/tests/overlaytests/remount/test-apps/certs/Android.bp create mode 100644 core/tests/overlaytests/remount/test-apps/certs/rro-remounted-test-a.pk8 create mode 100644 core/tests/overlaytests/remount/test-apps/certs/rro-remounted-test-a.x509.pem (limited to 'tools/aapt2/Debug.cpp') diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp index ef5c4cec9166..fb5830506925 100644 --- a/cmds/idmap2/Android.bp +++ b/cmds/idmap2/Android.bp @@ -168,13 +168,13 @@ cc_binary { ], host_supported: true, srcs: [ + "idmap2/CommandUtils.cpp", "idmap2/Create.cpp", "idmap2/CreateMultiple.cpp", "idmap2/Dump.cpp", "idmap2/Lookup.cpp", "idmap2/Main.cpp", "idmap2/Scan.cpp", - "idmap2/Verify.cpp", ], target: { android: { diff --git a/cmds/idmap2/idmap2/CommandUtils.cpp b/cmds/idmap2/idmap2/CommandUtils.cpp new file mode 100644 index 000000000000..e058cd6e7e70 --- /dev/null +++ b/cmds/idmap2/idmap2/CommandUtils.cpp @@ -0,0 +1,49 @@ +/* + * 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. + */ + +#include +#include +#include +#include + +#include "idmap2/Idmap.h" +#include "idmap2/Result.h" +#include "idmap2/SysTrace.h" + +using android::idmap2::Error; +using android::idmap2::IdmapHeader; +using android::idmap2::Result; +using android::idmap2::Unit; + +Result Verify(const std::string& idmap_path, const std::string& target_path, + const std::string& overlay_path, uint32_t fulfilled_policies, + bool enforce_overlayable) { + SYSTRACE << "Verify " << idmap_path; + std::ifstream fin(idmap_path); + const std::unique_ptr header = IdmapHeader::FromBinaryStream(fin); + fin.close(); + if (!header) { + return Error("failed to parse idmap header"); + } + + const auto header_ok = header->IsUpToDate(target_path.c_str(), overlay_path.c_str(), + fulfilled_policies, enforce_overlayable); + if (!header_ok) { + return Error(header_ok.GetError(), "idmap not up to date"); + } + + return Unit{}; +} diff --git a/cmds/idmap2/idmap2/CommandUtils.h b/cmds/idmap2/idmap2/CommandUtils.h new file mode 100644 index 000000000000..99605de30988 --- /dev/null +++ b/cmds/idmap2/idmap2/CommandUtils.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2020 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. + */ + +#ifndef IDMAP2_IDMAP2_COMMAND_UTILS_H_ +#define IDMAP2_IDMAP2_COMMAND_UTILS_H_ + +#include "idmap2/Result.h" + +android::idmap2::Result Verify(const std::string& idmap_path, + const std::string& target_path, + const std::string& overlay_path, + uint32_t fulfilled_policies, + bool enforce_overlayable); + +#endif // IDMAP2_IDMAP2_COMMAND_UTILS_H_ diff --git a/cmds/idmap2/idmap2/Commands.h b/cmds/idmap2/idmap2/Commands.h index e626738a2895..69eea8d262d2 100644 --- a/cmds/idmap2/idmap2/Commands.h +++ b/cmds/idmap2/idmap2/Commands.h @@ -27,6 +27,5 @@ android::idmap2::Result CreateMultiple(const std::vector< android::idmap2::Result Dump(const std::vector& args); android::idmap2::Result Lookup(const std::vector& args); android::idmap2::Result Scan(const std::vector& args); -android::idmap2::Result Verify(const std::vector& args); #endif // IDMAP2_IDMAP2_COMMANDS_H_ diff --git a/cmds/idmap2/idmap2/CreateMultiple.cpp b/cmds/idmap2/idmap2/CreateMultiple.cpp index 4b70acc2969c..abdfaf4dccab 100644 --- a/cmds/idmap2/idmap2/CreateMultiple.cpp +++ b/cmds/idmap2/idmap2/CreateMultiple.cpp @@ -26,6 +26,7 @@ #include "android-base/stringprintf.h" #include "idmap2/BinaryStreamVisitor.h" #include "idmap2/CommandLineOptions.h" +#include "idmap2/CommandUtils.h" #include "idmap2/FileUtils.h" #include "idmap2/Idmap.h" #include "idmap2/Policies.h" @@ -103,7 +104,8 @@ Result CreateMultiple(const std::vector& args) { continue; } - if (!Verify(std::vector({"--idmap-path", idmap_path}))) { + if (!Verify(idmap_path, target_apk_path, overlay_apk_path, fulfilled_policies, + !ignore_overlayable)) { const std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); if (!overlay_apk) { LOG(WARNING) << "failed to load apk " << overlay_apk_path.c_str(); diff --git a/cmds/idmap2/idmap2/Main.cpp b/cmds/idmap2/idmap2/Main.cpp index a07e793d9f47..fb093f0f22a4 100644 --- a/cmds/idmap2/idmap2/Main.cpp +++ b/cmds/idmap2/idmap2/Main.cpp @@ -53,9 +53,8 @@ void PrintUsage(const NameToFunctionMap& commands, std::ostream& out) { int main(int argc, char** argv) { SYSTRACE << "main"; const NameToFunctionMap commands = { - {"create", Create}, {"create-multiple", CreateMultiple}, - {"dump", Dump}, {"lookup", Lookup}, - {"scan", Scan}, {"verify", Verify}, + {"create", Create}, {"create-multiple", CreateMultiple}, {"dump", Dump}, {"lookup", Lookup}, + {"scan", Scan}, }; if (argc <= 1) { PrintUsage(commands, std::cerr); diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp index da0453216f03..36250450cc74 100644 --- a/cmds/idmap2/idmap2/Scan.cpp +++ b/cmds/idmap2/idmap2/Scan.cpp @@ -27,8 +27,11 @@ #include "Commands.h" #include "android-base/properties.h" #include "idmap2/CommandLineOptions.h" +#include "idmap2/CommandUtils.h" #include "idmap2/FileUtils.h" #include "idmap2/Idmap.h" +#include "idmap2/Policies.h" +#include "idmap2/PolicyUtils.h" #include "idmap2/ResourceUtils.h" #include "idmap2/Result.h" #include "idmap2/SysTrace.h" @@ -48,6 +51,7 @@ using android::idmap2::policy::kPolicyVendor; using android::idmap2::utils::ExtractOverlayManifestInfo; using android::idmap2::utils::FindFiles; using android::idmap2::utils::OverlayManifestInfo; +using android::idmap2::utils::PoliciesToBitmaskResult; using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; @@ -215,7 +219,15 @@ Result Scan(const std::vector& args) { std::stringstream stream; for (const auto& overlay : interesting_apks) { - if (!Verify(std::vector({"--idmap-path", overlay.idmap_path}))) { + const auto policy_bitmask = PoliciesToBitmaskResult(overlay.policies); + if (!policy_bitmask) { + LOG(WARNING) << "failed to create idmap for overlay apk path \"" << overlay.apk_path + << "\": " << policy_bitmask.GetErrorMessage(); + continue; + } + + if (!Verify(overlay.idmap_path, target_apk_path, overlay.apk_path, *policy_bitmask, + !overlay.ignore_overlayable)) { std::vector create_args = {"--target-apk-path", target_apk_path, "--overlay-apk-path", overlay.apk_path, "--idmap-path", overlay.idmap_path}; diff --git a/cmds/idmap2/idmap2/Verify.cpp b/cmds/idmap2/idmap2/Verify.cpp deleted file mode 100644 index 9cb67b33e6cf..000000000000 --- a/cmds/idmap2/idmap2/Verify.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - */ - -#include -#include -#include -#include - -#include "idmap2/CommandLineOptions.h" -#include "idmap2/Idmap.h" -#include "idmap2/Result.h" -#include "idmap2/SysTrace.h" - -using android::idmap2::CommandLineOptions; -using android::idmap2::Error; -using android::idmap2::IdmapHeader; -using android::idmap2::Result; -using android::idmap2::Unit; - -Result Verify(const std::vector& args) { - SYSTRACE << "Verify " << args; - std::string idmap_path; - - const CommandLineOptions opts = - CommandLineOptions("idmap2 verify") - .MandatoryOption("--idmap-path", "input: path to idmap file to verify", &idmap_path); - - const auto opts_ok = opts.Parse(args); - if (!opts_ok) { - return opts_ok.GetError(); - } - - std::ifstream fin(idmap_path); - const std::unique_ptr header = IdmapHeader::FromBinaryStream(fin); - fin.close(); - if (!header) { - return Error("failed to parse idmap header"); - } - - const auto header_ok = header->IsUpToDate(); - if (!header_ok) { - return Error(header_ok.GetError(), "idmap not up to date"); - } - - return Unit{}; -} diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index a93184ff4787..908d96612269 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -33,16 +33,19 @@ #include "idmap2/BinaryStreamVisitor.h" #include "idmap2/FileUtils.h" #include "idmap2/Idmap.h" +#include "idmap2/Result.h" #include "idmap2/SysTrace.h" #include "idmap2/ZipFile.h" #include "utils/String8.h" using android::IPCThreadState; +using android::base::StringPrintf; using android::binder::Status; using android::idmap2::BinaryStreamVisitor; using android::idmap2::GetPackageCrc; using android::idmap2::Idmap; using android::idmap2::IdmapHeader; +using android::idmap2::ZipFile; using android::idmap2::utils::kIdmapCacheDir; using android::idmap2::utils::kIdmapFilePermissionMask; using android::idmap2::utils::UidHasWriteAccessToPath; @@ -66,6 +69,21 @@ PolicyBitmask ConvertAidlArgToPolicyBitmask(int32_t arg) { return static_cast(arg); } +Status GetCrc(const std::string& apk_path, uint32_t* out_crc) { + const auto overlay_zip = ZipFile::Open(apk_path); + if (!overlay_zip) { + return error(StringPrintf("failed to open apk %s", apk_path.c_str())); + } + + const auto crc = GetPackageCrc(*overlay_zip); + if (!crc) { + return error(crc.GetErrorMessage()); + } + + *out_crc = *crc; + return ok(); +} + } // namespace namespace android::os { @@ -98,10 +116,9 @@ Status Idmap2Service::removeIdmap(const std::string& overlay_apk_path, } Status Idmap2Service::verifyIdmap(const std::string& target_apk_path, - const std::string& overlay_apk_path, - int32_t fulfilled_policies ATTRIBUTE_UNUSED, - bool enforce_overlayable ATTRIBUTE_UNUSED, - int32_t user_id ATTRIBUTE_UNUSED, bool* _aidl_return) { + const std::string& overlay_apk_path, int32_t fulfilled_policies, + bool enforce_overlayable, int32_t user_id ATTRIBUTE_UNUSED, + bool* _aidl_return) { SYSTRACE << "Idmap2Service::verifyIdmap " << overlay_apk_path; assert(_aidl_return); const std::string idmap_path = Idmap::CanonicalIdmapPathFor(kIdmapCacheDir, overlay_apk_path); @@ -113,34 +130,38 @@ Status Idmap2Service::verifyIdmap(const std::string& target_apk_path, return error("failed to parse idmap header"); } - if (strcmp(header->GetTargetPath().data(), target_apk_path.data()) != 0) { - *_aidl_return = false; - return ok(); - } - - if (target_apk_path != kFrameworkPath) { - *_aidl_return = (bool) header->IsUpToDate(); + uint32_t target_crc; + if (target_apk_path == kFrameworkPath && android_crc_) { + target_crc = *android_crc_; } else { - if (!android_crc_) { - // Loading the framework zip can take several milliseconds. Cache the crc of the framework - // resource APK to reduce repeated work during boot. - const auto target_zip = idmap2::ZipFile::Open(target_apk_path); - if (!target_zip) { - return error(base::StringPrintf("failed to open target %s", target_apk_path.c_str())); - } - - const auto target_crc = GetPackageCrc(*target_zip); - if (!target_crc) { - return error(target_crc.GetErrorMessage()); - } - - android_crc_ = *target_crc; + auto target_crc_status = GetCrc(target_apk_path, &target_crc); + if (!target_crc_status.isOk()) { + *_aidl_return = false; + return target_crc_status; + } + + // Loading the framework zip can take several milliseconds. Cache the crc of the framework + // resource APK to reduce repeated work during boot. + if (target_apk_path == kFrameworkPath) { + android_crc_ = target_crc; } + } - *_aidl_return = (bool) header->IsUpToDate(android_crc_.value()); + uint32_t overlay_crc; + auto overlay_crc_status = GetCrc(overlay_apk_path, &overlay_crc); + if (!overlay_crc_status.isOk()) { + *_aidl_return = false; + return overlay_crc_status; + } + + auto up_to_date = + header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), target_crc, overlay_crc, + fulfilled_policies, enforce_overlayable); + if (!up_to_date) { + *_aidl_return = false; + return error(up_to_date.GetErrorMessage()); } - // TODO(b/119328308): Check that the set of fulfilled policies of the overlay has not changed return ok(); } diff --git a/cmds/idmap2/include/idmap2/Idmap.h b/cmds/idmap2/include/idmap2/Idmap.h index 77a7b30a230e..8f25b8d6a734 100644 --- a/cmds/idmap2/include/idmap2/Idmap.h +++ b/cmds/idmap2/include/idmap2/Idmap.h @@ -117,6 +117,14 @@ class IdmapHeader { return overlay_crc_; } + inline uint32_t GetFulfilledPolicies() const { + return fulfilled_policies_; + } + + bool GetEnforceOverlayable() const { + return enforce_overlayable_; + } + inline StringPiece GetTargetPath() const { return StringPiece(target_path_); } @@ -132,8 +140,11 @@ class IdmapHeader { // Invariant: anytime the idmap data encoding is changed, the idmap version // field *must* be incremented. Because of this, we know that if the idmap // header is up-to-date the entire file is up-to-date. - Result IsUpToDate() const; - Result IsUpToDate(uint32_t target_crc_) const; + Result IsUpToDate(const char* target_path, const char* overlay_path, + uint32_t fulfilled_policies, bool enforce_overlayable) const; + Result IsUpToDate(const char* target_path, const char* overlay_path, uint32_t target_crc, + uint32_t overlay_crc, uint32_t fulfilled_policies, + bool enforce_overlayable) const; void accept(Visitor* v) const; @@ -145,6 +156,8 @@ class IdmapHeader { uint32_t version_; uint32_t target_crc_; uint32_t overlay_crc_; + uint32_t fulfilled_policies_; + bool enforce_overlayable_; char target_path_[kIdmapStringLength]; char overlay_path_[kIdmapStringLength]; std::string debug_info_; diff --git a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp index 362dcb36007a..255212ad4c66 100644 --- a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp +++ b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp @@ -66,6 +66,8 @@ void BinaryStreamVisitor::visit(const IdmapHeader& header) { Write32(header.GetVersion()); Write32(header.GetTargetCrc()); Write32(header.GetOverlayCrc()); + Write32(header.GetFulfilledPolicies()); + Write8(static_cast(header.GetEnforceOverlayable())); WriteString256(header.GetTargetPath()); WriteString256(header.GetOverlayPath()); WriteString(header.GetDebugInfo()); diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp index 706b842b3b47..0bea21735b24 100644 --- a/cmds/idmap2/libidmap2/Idmap.cpp +++ b/cmds/idmap2/libidmap2/Idmap.cpp @@ -112,14 +112,18 @@ Result GetPackageCrc(const ZipFile& zip) { std::unique_ptr IdmapHeader::FromBinaryStream(std::istream& stream) { std::unique_ptr idmap_header(new IdmapHeader()); - + uint8_t enforce_overlayable; if (!Read32(stream, &idmap_header->magic_) || !Read32(stream, &idmap_header->version_) || !Read32(stream, &idmap_header->target_crc_) || !Read32(stream, &idmap_header->overlay_crc_) || + !Read32(stream, &idmap_header->fulfilled_policies_) || + !Read8(stream, &enforce_overlayable) || !ReadString256(stream, idmap_header->target_path_) || !ReadString256(stream, idmap_header->overlay_path_)) { return nullptr; } + idmap_header->enforce_overlayable_ = static_cast(enforce_overlayable); + auto debug_str = ReadString(stream); if (!debug_str) { return nullptr; @@ -129,21 +133,35 @@ std::unique_ptr IdmapHeader::FromBinaryStream(std::istream& s return std::move(idmap_header); } -Result IdmapHeader::IsUpToDate() const { - const std::unique_ptr target_zip = ZipFile::Open(target_path_); +Result IdmapHeader::IsUpToDate(const char* target_path, const char* overlay_path, + uint32_t fulfilled_policies, bool enforce_overlayable) const { + const std::unique_ptr target_zip = ZipFile::Open(target_path); if (!target_zip) { - return Error("failed to open target %s", GetTargetPath().to_string().c_str()); + return Error("failed to open target %s", target_path); } - Result target_crc = GetPackageCrc(*target_zip); + const Result target_crc = GetPackageCrc(*target_zip); if (!target_crc) { return Error("failed to get target crc"); } - return IsUpToDate(*target_crc); + const std::unique_ptr overlay_zip = ZipFile::Open(overlay_path); + if (!overlay_zip) { + return Error("failed to overlay target %s", overlay_path); + } + + const Result overlay_crc = GetPackageCrc(*overlay_zip); + if (!overlay_crc) { + return Error("failed to get overlay crc"); + } + + return IsUpToDate(target_path, overlay_path, *target_crc, *overlay_crc, fulfilled_policies, + enforce_overlayable); } -Result IdmapHeader::IsUpToDate(uint32_t target_crc) const { +Result IdmapHeader::IsUpToDate(const char* target_path, const char* overlay_path, + uint32_t target_crc, uint32_t overlay_crc, + uint32_t fulfilled_policies, bool enforce_overlayable) const { if (magic_ != kIdmapMagic) { return Error("bad magic: actual 0x%08x, expected 0x%08x", magic_, kIdmapMagic); } @@ -157,19 +175,30 @@ Result IdmapHeader::IsUpToDate(uint32_t target_crc) const { target_crc); } - const std::unique_ptr overlay_zip = ZipFile::Open(overlay_path_); - if (!overlay_zip) { - return Error("failed to open overlay %s", GetOverlayPath().to_string().c_str()); + if (overlay_crc_ != overlay_crc) { + return Error("bad overlay crc: idmap version 0x%08x, file system version 0x%08x", overlay_crc_, + overlay_crc); } - Result overlay_crc = GetPackageCrc(*overlay_zip); - if (!overlay_crc) { - return Error("failed to get overlay crc"); + if (fulfilled_policies_ != fulfilled_policies) { + return Error("bad fulfilled policies: idmap version 0x%08x, file system version 0x%08x", + fulfilled_policies, fulfilled_policies_); } - if (overlay_crc_ != *overlay_crc) { - return Error("bad overlay crc: idmap version 0x%08x, file system version 0x%08x", overlay_crc_, - *overlay_crc); + if (enforce_overlayable != enforce_overlayable_) { + return Error("bad enforce overlayable: idmap version %s, file system version %s", + enforce_overlayable ? "true" : "false", + enforce_overlayable_ ? "true" : "false"); + } + + if (strcmp(target_path, target_path_) != 0) { + return Error("bad target path: idmap version %s, file system version %s", target_path, + target_path_); + } + + if (strcmp(overlay_path, overlay_path_) != 0) { + return Error("bad overlay path: idmap version %s, file system version %s", overlay_path, + overlay_path_); } return Unit{}; @@ -320,6 +349,9 @@ Result> Idmap::FromApkAssets(const ApkAssets& targe } header->overlay_crc_ = *crc; + header->fulfilled_policies_ = fulfilled_policies; + header->enforce_overlayable_ = enforce_overlayable; + if (target_apk_path.size() > sizeof(header->target_path_)) { return Error("target apk path \"%s\" longer than maximum size %zu", target_apk_path.c_str(), sizeof(header->target_path_)); diff --git a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp index 751c60c4add4..3f62a2ae2029 100644 --- a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp +++ b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp @@ -23,10 +23,12 @@ #include "android-base/macros.h" #include "android-base/stringprintf.h" #include "androidfw/ApkAssets.h" +#include "idmap2/PolicyUtils.h" #include "idmap2/ResourceUtils.h" #include "idmap2/Result.h" using android::ApkAssets; +using android::idmap2::policy::PoliciesToDebugString; namespace { @@ -39,9 +41,6 @@ size_t StringSizeWhenEncoded(const std::string& s) { namespace android::idmap2 { -// verbatim copy fomr PrettyPrintVisitor.cpp, move to common utils -#define RESID(pkg, type, entry) (((pkg) << 24) | ((type) << 16) | (entry)) - void RawPrintVisitor::visit(const Idmap& idmap ATTRIBUTE_UNUSED) { } @@ -50,6 +49,9 @@ void RawPrintVisitor::visit(const IdmapHeader& header) { print(header.GetVersion(), "version"); print(header.GetTargetCrc(), "target crc"); print(header.GetOverlayCrc(), "overlay crc"); + print(header.GetFulfilledPolicies(), "fulfilled policies: %s", + PoliciesToDebugString(header.GetFulfilledPolicies()).c_str()); + print(static_cast(header.GetEnforceOverlayable()), "enforce overlayable"); print(header.GetTargetPath().to_string(), kIdmapStringLength, "target path"); print(header.GetOverlayPath().to_string(), kIdmapStringLength, "overlay path"); print("...", StringSizeWhenEncoded(header.GetDebugInfo()), "debug info"); diff --git a/cmds/idmap2/libidmap2/ResourceMapping.cpp b/cmds/idmap2/libidmap2/ResourceMapping.cpp index f82c8f1af713..34589a1c39dc 100644 --- a/cmds/idmap2/libidmap2/ResourceMapping.cpp +++ b/cmds/idmap2/libidmap2/ResourceMapping.cpp @@ -291,13 +291,6 @@ Result ResourceMapping::FromApkAssets(const ApkAssets& target_a const PolicyBitmask& fulfilled_policies, bool enforce_overlayable, LogInfo& log_info) { - if (enforce_overlayable) { - log_info.Info(LogMessage() << "fulfilled_policies=" - << ConcatPolicies(BitmaskToPolicies(fulfilled_policies)) - << " enforce_overlayable=" - << (enforce_overlayable ? "true" : "false")); - } - AssetManager2 target_asset_manager; if (!target_asset_manager.SetApkAssets({&target_apk_assets}, true /* invalidate_caches */, false /* filter_incompatible_configs*/)) { diff --git a/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h b/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h index 4973b7638d10..5bd353af4ad3 100644 --- a/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h +++ b/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h @@ -21,9 +21,12 @@ #include #include +#include "android-base/stringprintf.h" #include "androidfw/ResourceTypes.h" #include "androidfw/StringPiece.h" +using android::base::StringPrintf; + using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; @@ -48,6 +51,29 @@ inline static const std::array, 8> kPolicySt {kPolicySystem, PolicyFlags::SYSTEM_PARTITION}, {kPolicyVendor, PolicyFlags::VENDOR_PARTITION}, }; + +inline static std::string PoliciesToDebugString(PolicyBitmask policies) { + std::string str; + uint32_t remaining = policies; + for (auto const& policy : kPolicyStringToFlag) { + if ((policies & policy.second) != policy.second) { + continue; + } + if (!str.empty()) { + str.append("|"); + } + str.append(policy.first.data()); + remaining &= ~policy.second; + } + if (remaining != 0) { + if (!str.empty()) { + str.append("|"); + } + str.append(StringPrintf("0x%08x", remaining)); + } + return !str.empty() ? str : "none"; +} + } // namespace android::idmap2::policy #endif // IDMAP2_INCLUDE_IDMAP2_POLICIES_H_ diff --git a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp index db4778c8ee09..5fea7bcdaac5 100644 --- a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp +++ b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp @@ -48,6 +48,11 @@ TEST(BinaryStreamVisitorTests, CreateBinaryStreamViaBinaryStreamVisitor) { ASSERT_TRUE(result2); const auto idmap2 = std::move(*result2); + ASSERT_EQ(idmap1->GetHeader()->GetFulfilledPolicies(), + idmap2->GetHeader()->GetFulfilledPolicies()); + ASSERT_EQ(idmap1->GetHeader()->GetEnforceOverlayable(), + idmap2->GetHeader()->GetEnforceOverlayable()); + ASSERT_EQ(idmap1->GetHeader()->GetTargetPath(), idmap2->GetHeader()->GetTargetPath()); ASSERT_EQ(idmap1->GetHeader()->GetTargetCrc(), idmap2->GetHeader()->GetTargetCrc()); ASSERT_EQ(idmap1->GetHeader()->GetTargetPath(), idmap2->GetHeader()->GetTargetPath()); ASSERT_EQ(idmap1->GetData().size(), 1U); diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp index 87da36c01192..6fab5e0f8ae1 100644 --- a/cmds/idmap2/tests/IdmapTests.cpp +++ b/cmds/idmap2/tests/IdmapTests.cpp @@ -62,9 +62,11 @@ TEST(IdmapTests, CreateIdmapHeaderFromBinaryStream) { std::unique_ptr header = IdmapHeader::FromBinaryStream(stream); ASSERT_THAT(header, NotNull()); ASSERT_EQ(header->GetMagic(), 0x504d4449U); - ASSERT_EQ(header->GetVersion(), 0x03U); + ASSERT_EQ(header->GetVersion(), 0x04U); ASSERT_EQ(header->GetTargetCrc(), 0x1234U); ASSERT_EQ(header->GetOverlayCrc(), 0x5678U); + ASSERT_EQ(header->GetFulfilledPolicies(), 0x11); + ASSERT_EQ(header->GetEnforceOverlayable(), true); ASSERT_EQ(header->GetTargetPath().to_string(), "targetX.apk"); ASSERT_EQ(header->GetOverlayPath().to_string(), "overlayX.apk"); ASSERT_EQ(header->GetDebugInfo(), "debug"); @@ -73,7 +75,7 @@ TEST(IdmapTests, CreateIdmapHeaderFromBinaryStream) { TEST(IdmapTests, FailToCreateIdmapHeaderFromBinaryStreamIfPathTooLong) { std::string raw(reinterpret_cast(idmap_raw_data), idmap_raw_data_len); // overwrite the target path string, including the terminating null, with '.' - for (size_t i = 0x10; i < 0x110; i++) { + for (size_t i = 0x15; i < 0x115; i++) { raw[i] = '.'; } std::istringstream stream(raw); @@ -82,7 +84,7 @@ TEST(IdmapTests, FailToCreateIdmapHeaderFromBinaryStreamIfPathTooLong) { } TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) { - const size_t offset = 0x21c; + const size_t offset = 0x221; std::string raw(reinterpret_cast(idmap_raw_data + offset), idmap_raw_data_len - offset); std::istringstream stream(raw); @@ -94,7 +96,7 @@ TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) { } TEST(IdmapTests, CreateIdmapDataFromBinaryStream) { - const size_t offset = 0x21c; + const size_t offset = 0x221; std::string raw(reinterpret_cast(idmap_raw_data + offset), idmap_raw_data_len - offset); std::istringstream stream(raw); @@ -128,9 +130,11 @@ TEST(IdmapTests, CreateIdmapFromBinaryStream) { ASSERT_THAT(idmap->GetHeader(), NotNull()); ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U); - ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x03U); + ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x04U); ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x1234U); ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x5678U); + ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), 0x11); + ASSERT_EQ(idmap->GetHeader()->GetEnforceOverlayable(), true); ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), "targetX.apk"); ASSERT_EQ(idmap->GetHeader()->GetOverlayPath().to_string(), "overlayX.apk"); @@ -180,9 +184,11 @@ TEST(IdmapTests, CreateIdmapHeaderFromApkAssets) { ASSERT_THAT(idmap->GetHeader(), NotNull()); ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U); - ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x03U); + ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x04U); ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), android::idmap2::TestConstants::TARGET_CRC); ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), android::idmap2::TestConstants::OVERLAY_CRC); + ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), PolicyFlags::PUBLIC); + ASSERT_EQ(idmap->GetHeader()->GetEnforceOverlayable(), true); ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), target_apk_path); ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path); } @@ -389,7 +395,8 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { std::unique_ptr header = IdmapHeader::FromBinaryStream(stream); ASSERT_THAT(header, NotNull()); - ASSERT_TRUE(header->IsUpToDate()); + ASSERT_TRUE(header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), + PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); // magic: bytes (0x0, 0x03) std::string bad_magic_string(stream.str()); @@ -402,7 +409,8 @@ 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()); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), + PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); // version: bytes (0x4, 0x07) std::string bad_version_string(stream.str()); @@ -415,7 +423,8 @@ 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_version_header->IsUpToDate()); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), + PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); // target crc: bytes (0x8, 0xb) std::string bad_target_crc_string(stream.str()); @@ -428,7 +437,8 @@ 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_target_crc_header->IsUpToDate()); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), + PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); // overlay crc: bytes (0xc, 0xf) std::string bad_overlay_crc_string(stream.str()); @@ -441,27 +451,55 @@ 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_overlay_crc_header->IsUpToDate()); - - // target path: bytes (0x10, 0x10f) + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), + PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + + // fulfilled policy: bytes (0x10, 0x13) + std::string bad_policy_string(stream.str()); + bad_policy_string[0x10] = '.'; + bad_policy_string[0x11] = '.'; + bad_policy_string[0x12] = '.'; + bad_policy_string[0x13] = '.'; + std::stringstream bad_policy_stream(bad_policy_string); + std::unique_ptr bad_policy_header = + IdmapHeader::FromBinaryStream(bad_policy_stream); + ASSERT_THAT(bad_policy_header, NotNull()); + ASSERT_NE(header->GetFulfilledPolicies(), bad_policy_header->GetFulfilledPolicies()); + ASSERT_FALSE(bad_policy_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), + PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + + // enforce overlayable: bytes (0x14) + std::string bad_enforce_string(stream.str()); + bad_enforce_string[0x14] = '\0'; + std::stringstream bad_enforce_stream(bad_enforce_string); + std::unique_ptr bad_enforce_header = + IdmapHeader::FromBinaryStream(bad_enforce_stream); + ASSERT_THAT(bad_enforce_header, NotNull()); + ASSERT_NE(header->GetEnforceOverlayable(), bad_enforce_header->GetEnforceOverlayable()); + ASSERT_FALSE(bad_enforce_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), + PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); + + // target path: bytes (0x15, 0x114) std::string bad_target_path_string(stream.str()); - bad_target_path_string[0x10] = '\0'; + bad_target_path_string[0x15] = '\0'; std::stringstream bad_target_path_stream(bad_target_path_string); std::unique_ptr bad_target_path_header = IdmapHeader::FromBinaryStream(bad_target_path_stream); ASSERT_THAT(bad_target_path_header, NotNull()); ASSERT_NE(header->GetTargetPath(), bad_target_path_header->GetTargetPath()); - ASSERT_FALSE(bad_target_path_header->IsUpToDate()); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), + PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); - // overlay path: bytes (0x110, 0x20f) + // overlay path: bytes (0x115, 0x214) std::string bad_overlay_path_string(stream.str()); - bad_overlay_path_string[0x110] = '\0'; + bad_overlay_path_string[0x115] = '\0'; std::stringstream bad_overlay_path_stream(bad_overlay_path_string); std::unique_ptr bad_overlay_path_header = IdmapHeader::FromBinaryStream(bad_overlay_path_stream); ASSERT_THAT(bad_overlay_path_header, NotNull()); ASSERT_NE(header->GetOverlayPath(), bad_overlay_path_header->GetOverlayPath()); - ASSERT_FALSE(bad_overlay_path_header->IsUpToDate()); + ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), + PolicyFlags::PUBLIC, /* enforce_overlayable */ true)); } class TestVisitor : public Visitor { diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp index 5c5c81edee90..b268d5add141 100644 --- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp +++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp @@ -43,6 +43,8 @@ namespace android::idmap2 { << str << "--------"; \ } while (0) +#define ADDRESS "[0-9a-f]{8}: " + TEST(RawPrintVisitorTests, CreateRawPrintVisitor) { fclose(stderr); // silence expected warnings @@ -62,15 +64,16 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) { RawPrintVisitor visitor(stream); (*idmap)->accept(&visitor); -#define ADDRESS "[0-9a-f]{8}: " ASSERT_CONTAINS_REGEX(ADDRESS "504d4449 magic\n", stream.str()); - ASSERT_CONTAINS_REGEX(ADDRESS "00000003 version\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000004 version\n", stream.str()); ASSERT_CONTAINS_REGEX( StringPrintf(ADDRESS "%s target crc\n", android::idmap2::TestConstants::TARGET_CRC_STRING), stream.str()); ASSERT_CONTAINS_REGEX( StringPrintf(ADDRESS "%s overlay crc\n", android::idmap2::TestConstants::OVERLAY_CRC_STRING), stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000001 fulfilled policies: public\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS " 01 enforce overlayable\n", stream.str()); ASSERT_CONTAINS_REGEX(ADDRESS " 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()); @@ -83,7 +86,6 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) { ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 value: integer/int1\n", stream.str()); ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 overlay id: integer/int1\n", stream.str()); ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 target id: integer/int1\n", stream.str()); -#undef ADDRESS } TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) { @@ -99,22 +101,23 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) { RawPrintVisitor visitor(stream); (*idmap)->accept(&visitor); - ASSERT_NE(stream.str().find("00000000: 504d4449 magic\n"), std::string::npos); - ASSERT_NE(stream.str().find("00000004: 00000003 version\n"), std::string::npos); - ASSERT_NE(stream.str().find("00000008: 00001234 target crc\n"), std::string::npos); - ASSERT_NE(stream.str().find("0000000c: 00005678 overlay crc\n"), std::string::npos); - ASSERT_NE(stream.str().find("0000021c: 7f target package id\n"), std::string::npos); - ASSERT_NE(stream.str().find("0000021d: 7f overlay package id\n"), std::string::npos); - ASSERT_NE(stream.str().find("0000021e: 00000003 target entry count\n"), std::string::npos); - ASSERT_NE(stream.str().find("00000222: 00000003 overlay entry count\n"), std::string::npos); - ASSERT_NE(stream.str().find("00000226: 00000000 string pool index offset\n"), std::string::npos); - ASSERT_NE(stream.str().find("0000022a: 00000000 string pool byte length\n"), std::string::npos); - ASSERT_NE(stream.str().find("0000022e: 7f020000 target id\n"), std::string::npos); - ASSERT_NE(stream.str().find("00000232: 01 type: reference\n"), std::string::npos); - ASSERT_NE(stream.str().find("00000233: 7f020000 value\n"), std::string::npos); - - ASSERT_NE(stream.str().find("00000249: 7f020000 overlay id\n"), std::string::npos); - ASSERT_NE(stream.str().find("0000024d: 7f020000 target id\n"), std::string::npos); + ASSERT_CONTAINS_REGEX(ADDRESS "504d4449 magic\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000004 version\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00001234 target crc\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00005678 overlay crc\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000011 fulfilled policies: public|signature\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS " 01 enforce overlayable\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS " 7f target package id\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS " 7f overlay package id\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000003 target entry count\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000003 overlay entry count\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000000 string pool index offset\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "00000000 string pool byte length\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f020000 target id\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS " 01 type: reference\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f020000 value\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f020000 overlay id\n", stream.str()); + ASSERT_CONTAINS_REGEX(ADDRESS "7f020000 target id\n", stream.str()); } } // namespace android::idmap2 diff --git a/cmds/idmap2/tests/TestHelpers.h b/cmds/idmap2/tests/TestHelpers.h index e899589c7e61..b599dcb0069a 100644 --- a/cmds/idmap2/tests/TestHelpers.h +++ b/cmds/idmap2/tests/TestHelpers.h @@ -30,7 +30,7 @@ const unsigned char idmap_raw_data[] = { 0x49, 0x44, 0x4d, 0x50, // 0x4: version - 0x03, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, // 0x8: target crc 0x34, 0x12, 0x00, 0x00, @@ -38,7 +38,13 @@ const unsigned char idmap_raw_data[] = { // 0xc: overlay crc 0x78, 0x56, 0x00, 0x00, - // 0x10: target path "targetX.apk" + // 0x10: fulfilled policies + 0x11, 0x00, 0x00, 0x00, + + // 0x14: enforce overlayable + 0x01, + + // 0x15: target path "targetX.apk" 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x58, 0x2e, 0x61, 0x70, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -56,7 +62,7 @@ const unsigned char idmap_raw_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // 0x110: overlay path "overlayX.apk" + // 0x115: overlay path "overlayX.apk" 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x58, 0x2e, 0x61, 0x70, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -74,7 +80,7 @@ const unsigned char idmap_raw_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // 0x210: debug string + // 0x215: debug string // string length, including terminating null 0x08, 0x00, 0x00, 0x00, @@ -82,63 +88,63 @@ const unsigned char idmap_raw_data[] = { 0x64, 0x65, 0x62, 0x75, 0x67, 0x00, 0x00, 0x00, // DATA HEADER - // 0x21c: target_package_id + // 0x221: target_package_id 0x7f, - // 0x21d: overlay_package_id + // 0x222: overlay_package_id 0x7f, - // 0x21e: target_entry_count + // 0x223: target_entry_count 0x03, 0x00, 0x00, 0x00, - // 0x222: overlay_entry_count + // 0x227: overlay_entry_count 0x03, 0x00, 0x00, 0x00, - // 0x226: string_pool_offset + // 0x22b: string_pool_offset 0x00, 0x00, 0x00, 0x00, - // 0x22a: string_pool_byte_length + // 0x22f: string_pool_byte_length 0x00, 0x00, 0x00, 0x00, // TARGET ENTRIES - // 0x22e: 0x7f020000 + // 0x233: 0x7f020000 0x00, 0x00, 0x02, 0x7f, - // 0x232: TYPE_REFERENCE + // 0x237: TYPE_REFERENCE 0x01, - // 0x233: 0x7f020000 + // 0x238: 0x7f020000 0x00, 0x00, 0x02, 0x7f, - // 0x237: 0x7f030000 + // 0x23c: 0x7f030000 0x00, 0x00, 0x03, 0x7f, - // 0x23b: TYPE_REFERENCE + // 0x240: TYPE_REFERENCE 0x01, - // 0x23c: 0x7f030000 + // 0x241: 0x7f030000 0x00, 0x00, 0x03, 0x7f, - // 0x240: 0x7f030002 + // 0x245: 0x7f030002 0x02, 0x00, 0x03, 0x7f, - // 0x244: TYPE_REFERENCE + // 0x249: TYPE_REFERENCE 0x01, - // 0x245: 0x7f030001 + // 0x24a: 0x7f030001 0x01, 0x00, 0x03, 0x7f, // OVERLAY ENTRIES - // 0x249: 0x7f020000 -> 0x7f020000 + // 0x24e: 0x7f020000 -> 0x7f020000 0x00, 0x00, 0x02, 0x7f, 0x00, 0x00, 0x02, 0x7f, - // 0x251: 0x7f030000 -> 0x7f030000 + // 0x256: 0x7f030000 -> 0x7f030000 0x00, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x03, 0x7f, - // 0x259: 0x7f030001 -> 0x7f030002 + // 0x25e: 0x7f030001 -> 0x7f030002 0x01, 0x00, 0x03, 0x7f, 0x02, 0x00, 0x03, 0x7f}; -const unsigned int idmap_raw_data_len = 0x261; +const unsigned int idmap_raw_data_len = 0x266; std::string GetTestDataPath(); diff --git a/core/tests/overlaytests/remount/Android.bp b/core/tests/overlaytests/remount/Android.bp index 5757cfe75514..4e79a4574af4 100644 --- a/core/tests/overlaytests/remount/Android.bp +++ b/core/tests/overlaytests/remount/Android.bp @@ -28,5 +28,6 @@ java_test_host { ":OverlayRemountedTest_Target", ":OverlayRemountedTest_TargetUpgrade", ":OverlayRemountedTest_Overlay", + ":OverlayRemountedTest_Overlay_SameCert", ], } diff --git a/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/PackagedUpgradedTest.java b/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/PackagedUpgradedTest.java deleted file mode 100644 index a4656403b03f..000000000000 --- a/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/PackagedUpgradedTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2020 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. - */ - -package com.android.overlaytest.remounted; - -import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DeviceJUnit4ClassRunner.class) -public class PackagedUpgradedTest extends OverlayRemountedTestBase { - private static final String TARGET_UPGRADE_APK = "OverlayRemountedTest_TargetUpgrade.apk"; - - @Test - public void testTargetUpgrade() throws Exception { - final String targetOverlaid = resourceName(TARGET_PACKAGE, "bool", "target_overlaid"); - final String targetReference = resourceName(TARGET_PACKAGE, "bool", "target_reference"); - - mPreparer.pushResourceFile(TARGET_APK, "/product/app/OverlayTarget.apk") - .reboot() - .installResourceApk(OVERLAY_APK, OVERLAY_PACKAGE) - .setOverlayEnabled(OVERLAY_PACKAGE, true); - - assertResource(targetReference, "@" + 0x7f010000 + " -> true"); - assertResource(targetOverlaid, "true"); - - mPreparer.installResourceApk(TARGET_UPGRADE_APK, TARGET_PACKAGE); - - assertResource(targetReference, "@" + 0x7f0100ff + " -> true"); - assertResource(targetOverlaid, "true"); - } - - @Test - public void testTargetRelocated() throws Exception { - final String targetOverlaid = resourceName(TARGET_PACKAGE, "bool", "target_overlaid"); - final String targetReference = resourceName(TARGET_PACKAGE, "bool", "target_reference"); - final String originalPath = "/product/app/OverlayTarget.apk"; - - mPreparer.pushResourceFile(TARGET_APK, originalPath) - .reboot() - .installResourceApk(OVERLAY_APK, OVERLAY_PACKAGE) - .setOverlayEnabled(OVERLAY_PACKAGE, true); - - assertResource(targetReference, "@" + 0x7f010000 + " -> true"); - assertResource(targetOverlaid, "true"); - - mPreparer.remount(); - getDevice().deleteFile(originalPath); - mPreparer.pushResourceFile(TARGET_UPGRADE_APK, "/product/app/OverlayTarget2.apk") - .reboot(); - - assertResource(targetReference, "@" + 0x7f0100ff + " -> true"); - assertResource(targetOverlaid, "true"); - } -} diff --git a/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/RegenerateIdmapTest.java b/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/RegenerateIdmapTest.java new file mode 100644 index 000000000000..2b68015536ed --- /dev/null +++ b/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/RegenerateIdmapTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2020 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. + */ + +package com.android.overlaytest.remounted; + +import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(DeviceJUnit4ClassRunner.class) +public class RegenerateIdmapTest extends OverlayRemountedTestBase { + private static final String OVERLAY_SIGNATURE_APK = + "OverlayRemountedTest_Overlay_SameCert.apk"; + private static final String TARGET_UPGRADE_APK = "OverlayRemountedTest_TargetUpgrade.apk"; + + @Test + public void testTargetUpgrade() throws Exception { + final String targetOverlaid = resourceName(TARGET_PACKAGE, "bool", "target_overlaid"); + final String targetReference = resourceName(TARGET_PACKAGE, "bool", "target_reference"); + + mPreparer.pushResourceFile(TARGET_APK, "/product/app/OverlayTarget.apk") + .reboot() + .installResourceApk(OVERLAY_APK, OVERLAY_PACKAGE) + .setOverlayEnabled(OVERLAY_PACKAGE, true); + + assertResource(targetReference, "@" + 0x7f010000 + " -> true"); + assertResource(targetOverlaid, "true"); + + mPreparer.installResourceApk(TARGET_UPGRADE_APK, TARGET_PACKAGE); + + assertResource(targetReference, "@" + 0x7f0100ff + " -> true"); + assertResource(targetOverlaid, "true"); + } + + @Test + public void testTargetRelocated() throws Exception { + final String targetOverlaid = resourceName(TARGET_PACKAGE, "bool", "target_overlaid"); + final String targetReference = resourceName(TARGET_PACKAGE, "bool", "target_reference"); + final String originalPath = "/product/app/OverlayTarget.apk"; + + mPreparer.pushResourceFile(TARGET_APK, originalPath) + .reboot() + .installResourceApk(OVERLAY_APK, OVERLAY_PACKAGE) + .setOverlayEnabled(OVERLAY_PACKAGE, true); + + assertResource(targetReference, "@" + 0x7f010000 + " -> true"); + assertResource(targetOverlaid, "true"); + + mPreparer.remount(); + getDevice().deleteFile(originalPath); + mPreparer.pushResourceFile(TARGET_UPGRADE_APK, "/product/app/OverlayTarget2.apk") + .reboot(); + + assertResource(targetReference, "@" + 0x7f0100ff + " -> true"); + assertResource(targetOverlaid, "true"); + } + + @Test + public void testIdmapPoliciesChanged() throws Exception { + final String targetResource = resourceName(TARGET_PACKAGE, "bool", + "signature_policy_overlaid"); + + mPreparer.pushResourceFile(TARGET_APK, "/product/app/OverlayTarget.apk") + .pushResourceFile(OVERLAY_APK, "/product/overlay/TestOverlay.apk") + .reboot() + .setOverlayEnabled(OVERLAY_PACKAGE, false); + + assertResource(targetResource, "false"); + + // The overlay is not signed with the same signature as the target. + mPreparer.setOverlayEnabled(OVERLAY_PACKAGE, true); + assertResource(targetResource, "false"); + + // Replace the overlay with a version of the overlay that is signed with the same signature + // as the target. + mPreparer.pushResourceFile(OVERLAY_SIGNATURE_APK, "/product/overlay/TestOverlay.apk") + .reboot(); + + // The idmap should have been recreated with the signature policy fulfilled. + assertResource(targetResource, "true"); + + mPreparer.setOverlayEnabled(OVERLAY_PACKAGE, false); + assertResource(targetResource, "false"); + } +} diff --git a/core/tests/overlaytests/remount/test-apps/Overlay/Android.bp b/core/tests/overlaytests/remount/test-apps/Overlay/Android.bp index a1fdbfd3542c..032a0cdcb50d 100644 --- a/core/tests/overlaytests/remount/test-apps/Overlay/Android.bp +++ b/core/tests/overlaytests/remount/test-apps/Overlay/Android.bp @@ -19,3 +19,9 @@ android_test_helper_app { "com.android.overlaytest.overlay", ], } + +android_test_helper_app { + name: "OverlayRemountedTest_Overlay_SameCert", + certificate: ":rro-remounted-test-a", + sdk_version: "current", +} \ No newline at end of file diff --git a/core/tests/overlaytests/remount/test-apps/Overlay/res/values/values.xml b/core/tests/overlaytests/remount/test-apps/Overlay/res/values/values.xml index 675e44f19f95..927d37fc60b9 100644 --- a/core/tests/overlaytests/remount/test-apps/Overlay/res/values/values.xml +++ b/core/tests/overlaytests/remount/test-apps/Overlay/res/values/values.xml @@ -17,4 +17,5 @@ true + true diff --git a/core/tests/overlaytests/remount/test-apps/Target/Android.bp b/core/tests/overlaytests/remount/test-apps/Target/Android.bp index 19947b1ea51a..e4b4eaa8d220 100644 --- a/core/tests/overlaytests/remount/test-apps/Target/Android.bp +++ b/core/tests/overlaytests/remount/test-apps/Target/Android.bp @@ -15,6 +15,7 @@ android_test_helper_app { name: "OverlayRemountedTest_Target", sdk_version: "test_current", + certificate: ":rro-remounted-test-a", apex_available: [ "com.android.overlaytest.overlaid", ], @@ -23,6 +24,7 @@ android_test_helper_app { android_test_helper_app { name: "OverlayRemountedTest_TargetUpgrade", + certificate: ":rro-remounted-test-a", resource_dirs: ["res_upgrade"], sdk_version: "test_current", } diff --git a/core/tests/overlaytests/remount/test-apps/Target/res/values/overlayable.xml b/core/tests/overlaytests/remount/test-apps/Target/res/values/overlayable.xml index 4aa5bcee8f3d..79c9a675a6dd 100644 --- a/core/tests/overlaytests/remount/test-apps/Target/res/values/overlayable.xml +++ b/core/tests/overlaytests/remount/test-apps/Target/res/values/overlayable.xml @@ -20,5 +20,8 @@ + + + diff --git a/core/tests/overlaytests/remount/test-apps/Target/res/values/values.xml b/core/tests/overlaytests/remount/test-apps/Target/res/values/values.xml index 76253a95b766..64a1683e14be 100644 --- a/core/tests/overlaytests/remount/test-apps/Target/res/values/values.xml +++ b/core/tests/overlaytests/remount/test-apps/Target/res/values/values.xml @@ -23,4 +23,6 @@ false @bool/target_overlaid + + false diff --git a/core/tests/overlaytests/remount/test-apps/certs/Android.bp b/core/tests/overlaytests/remount/test-apps/certs/Android.bp new file mode 100644 index 000000000000..06114efc1249 --- /dev/null +++ b/core/tests/overlaytests/remount/test-apps/certs/Android.bp @@ -0,0 +1,19 @@ +// Copyright (C) 2020 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. + +// development/tools/make_key rro-remounted-test-a '/CN=rro_test_a' +android_app_certificate { + name: "rro-remounted-test-a", + certificate: "rro-remounted-test-a", +} diff --git a/core/tests/overlaytests/remount/test-apps/certs/rro-remounted-test-a.pk8 b/core/tests/overlaytests/remount/test-apps/certs/rro-remounted-test-a.pk8 new file mode 100644 index 000000000000..aa6cc97d07f6 Binary files /dev/null and b/core/tests/overlaytests/remount/test-apps/certs/rro-remounted-test-a.pk8 differ diff --git a/core/tests/overlaytests/remount/test-apps/certs/rro-remounted-test-a.x509.pem b/core/tests/overlaytests/remount/test-apps/certs/rro-remounted-test-a.x509.pem new file mode 100644 index 000000000000..be491c7029fe --- /dev/null +++ b/core/tests/overlaytests/remount/test-apps/certs/rro-remounted-test-a.x509.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDCzCCAfOgAwIBAgIUfphI+C6W6V6RomsP7+CW5dO5cGcwDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKcnJvX3Rlc3RfYTAeFw0yMDA1MTQxNjM4MDBaFw00NzA5 +MzAxNjM4MDBaMBUxEzARBgNVBAMMCnJyb190ZXN0X2EwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCvXM8tcqQFwH7iQG6+8mAx2ADhwbtq+8Rcmiz7wviW +Yf/eFDRuvZ/ma6lxeVJ7mcbF7A5rinEKdgN5hlW2UlbTmuX5YOiXnX3Y2J5t+8Pi +aq787IvWxkawwkj0Oy1Hk01Z4w3HTYntYqi36bq4QyNpwh515VqgvEyCHT7IPtQi +XjfwcTW0thUlSDyDkgxq9NxNEJgaHHOamKkeMCO8CkBWkhlcPXvjcM8DPFmyzDI9 +Czv8IYFZQbcG/N2GPH9hSteMnuC+zyoMio0V/VRctQGlAA8ATsheBkng0zcNRu9Z +GIavk5AaClmBFTeQx01j3HFSO8UDdDJ5Hk8uDTqecPLpAgMBAAGjUzBRMB0GA1Ud +DgQWBBSPbIdzSkPbzltj3qIS13LNDiyIiDAfBgNVHSMEGDAWgBSPbIdzSkPbzltj +3qIS13LNDiyIiDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCH +QvvMGyMvVJaWMEJwVdUnszdXiAlUtDd/2HpdGOxW6xVVAvveP8hJ71gWFQ7Qs3Mr +3jxclbC37qVAPiQb8kkD8qUgoQYMC43asif6Jn65OU1QkDRF3bFHP+rZVSPEwtvl +YMbOzHPOLr7HESwlM7TB6EoZ4oOso++jTYI/OSif1MOKOMbOt4X/DE/PXf81ayFs +uRjpocBqnLwOourABMcaKbA92jB0LRTtgv5ngOJ3+5P1cTiHktFbnqVWa8/A3uSA +dNR5dpOUjH+nCHTwPl64b7R70PgDxnoqMs0xI7VtJovXor64OZy9P8WTdurz5V/z +k2IVSi032bf0aTxamvqV +-----END CERTIFICATE----- diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h index 2bfc7fc38d1c..21be81cb85bd 100644 --- a/libs/androidfw/include/androidfw/ResourceTypes.h +++ b/libs/androidfw/include/androidfw/ResourceTypes.h @@ -41,7 +41,7 @@ namespace android { constexpr const static uint32_t kIdmapMagic = 0x504D4449u; -constexpr const static uint32_t kIdmapCurrentVersion = 0x00000003u; +constexpr const static uint32_t kIdmapCurrentVersion = 0x00000004u; /** * In C++11, char16_t is defined as *at least* 16 bits. We do a lot of @@ -1746,6 +1746,9 @@ struct Idmap_header { uint32_t target_crc32; uint32_t overlay_crc32; + uint32_t fulfilled_policies; + uint8_t enforce_overlayable; + uint8_t target_path[256]; uint8_t overlay_path[256]; diff --git a/libs/androidfw/tests/data/overlay/overlay.apk b/libs/androidfw/tests/data/overlay/overlay.apk index 62e98662e68d..f1ed59279fdb 100644 Binary files a/libs/androidfw/tests/data/overlay/overlay.apk and b/libs/androidfw/tests/data/overlay/overlay.apk differ diff --git a/libs/androidfw/tests/data/overlay/overlay.idmap b/libs/androidfw/tests/data/overlay/overlay.idmap index 3759ed650033..29c5eb6a9ccf 100644 Binary files a/libs/androidfw/tests/data/overlay/overlay.idmap and b/libs/androidfw/tests/data/overlay/overlay.idmap differ diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp index 1eb7d95f381a..439f231193df 100644 --- a/tools/aapt2/Debug.cpp +++ b/tools/aapt2/Debug.cpp @@ -252,29 +252,6 @@ class ValueBodyPrinter : public ConstValueVisitor { Printer* printer_; }; -std::string OverlayablePoliciesToString(PolicyFlags policies) { - std::string str; - - uint32_t remaining = policies; - for (auto const& policy : kPolicyStringToFlag) { - if ((policies & policy.second) != policy.second) { - continue; - } - if (!str.empty()) { - str.append("|"); - } - str.append(policy.first.data()); - remaining &= ~policy.second; - } - if (remaining != 0) { - if (!str.empty()) { - str.append("|"); - } - str.append(StringPrintf("0x%08x", remaining)); - } - return !str.empty() ? str : "none"; -} - } // namespace void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions& options, @@ -575,7 +552,7 @@ void Debug::DumpOverlayable(const ResourceTable& table, text::Printer* printer) overlayable_item.overlayable->name.c_str(), overlayable_item.overlayable->actor.c_str()); const auto policy_subsection = StringPrintf(R"(policies="%s")", - OverlayablePoliciesToString(overlayable_item.policies).c_str()); + android::idmap2::policy::PoliciesToDebugString(overlayable_item.policies).c_str()); const auto value = StringPrintf("%s/%s", to_string(type->type).data(), entry->name.c_str()); items.push_back(DumpOverlayableEntry{overlayable_section, policy_subsection, value}); -- cgit v1.2.3-59-g8ed1b