diff options
author | 2019-09-17 13:02:32 +0200 | |
---|---|---|
committer | 2019-09-18 07:35:44 -0700 | |
commit | 1d3b64855b0d4178d6d8cb7beba9156a39caecfa (patch) | |
tree | 090bdec67f570310906ba7f93b58e4ccb1027452 | |
parent | 755f72686b2d596a043b2306d27796cbf80b56e5 (diff) |
aapt2: add 'dump overlayable' command
Add a command to print a resource table's <overlayable> resources. Given
the following input
<overlayable name="TestResources">
<policy type="system">
<item type="string" name="a" />
</policy>
<policy type="sytem|vendor">
<item type="string" name="b" />
<item type="string" name="c" />
</policy>
</overlayable>
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
-rw-r--r-- | tools/aapt2/Debug.cpp | 92 | ||||
-rw-r--r-- | tools/aapt2/Debug.h | 1 | ||||
-rw-r--r-- | tools/aapt2/cmd/Dump.cpp | 11 | ||||
-rw-r--r-- | tools/aapt2/cmd/Dump.h | 12 |
4 files changed, 115 insertions, 1 deletions
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<OverlayableItem::PolicyFlags, std::string> 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<DumpOverlayableEntry> 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<std::string> files_; }; +class DumpOverlayableCommand : public DumpApkCommand { + public: + explicit DumpOverlayableCommand(text::Printer* printer, IDiagnostics* diag) + : DumpApkCommand("overlayable", printer, diag) { + SetDescription("Print the <overlayable> 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<DumpTableCommand>(printer, diag_)); AddOptionalSubcommand(util::make_unique<DumpXmlStringsCommand>(printer, diag_)); AddOptionalSubcommand(util::make_unique<DumpXmlTreeCommand>(printer, diag_)); + AddOptionalSubcommand(util::make_unique<DumpOverlayableCommand>(printer, diag_)); AddOptionalSubcommand(util::make_unique<DumpBadgerCommand>(printer), /* hidden */ true); - // TODO(b/120609160): Add aapt2 overlayable dump command } int Action(const std::vector<std::string>& args) override { |