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
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index 7ffa5ff..137fbd6 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -246,6 +246,36 @@
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 @@
break;
}
+ if (entry->overlayable_item) {
+ printer->Print(" OVERLAYABLE");
+ }
+
printer->Println();
if (options.show_values) {
@@ -525,4 +559,62 @@
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