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:
committed by
Todd Kennedy
parent
755f72686b
commit
1d3b64855b
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user