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
This commit is contained in:
Mårten Kongstad
2019-09-17 13:02:32 +02:00
committed by Todd Kennedy
parent 755f72686b
commit 1d3b64855b
4 changed files with 115 additions and 1 deletions

View File

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

View File

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

View File

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

View File

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