[aapt2] Print type specs in 'dump chunks'
'aapt2 dump chunks' command used to skip the type specs
completely, but those contain important information about
the types' configuration masks and flags
Flag: EXEMPT host tool
Test: build
Change-Id: Id562e7bdca2347ea39d1dbc3b7dc74be34e98d08
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index 2527dcd..661df4d 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -21,10 +21,13 @@
#include <format/binary/ResChunkPullParser.h>
#include <algorithm>
+#include <array>
#include <map>
#include <memory>
#include <queue>
#include <set>
+#include <span>
+#include <utility>
#include <vector>
#include "ResourceTable.h"
@@ -684,6 +687,80 @@
printer_->Print("\n");
}
+ void PrintQualifiers(uint32_t qualifiers) const {
+ if (qualifiers == 0) {
+ printer_->Print("0");
+ return;
+ }
+
+ printer_->Print(StringPrintf("0x%04x: ", qualifiers));
+ static constinit std::array kValues = {
+ std::pair{ResTable_config::CONFIG_MCC, "mcc"},
+ std::pair{ResTable_config::CONFIG_MNC, "mnc"},
+ std::pair{ResTable_config::CONFIG_LOCALE, "locale"},
+ std::pair{ResTable_config::CONFIG_TOUCHSCREEN, "touchscreen"},
+ std::pair{ResTable_config::CONFIG_KEYBOARD, "keyboard"},
+ std::pair{ResTable_config::CONFIG_KEYBOARD_HIDDEN, "keyboard_hidden"},
+ std::pair{ResTable_config::CONFIG_NAVIGATION, "navigation"},
+ std::pair{ResTable_config::CONFIG_ORIENTATION, "orientation"},
+ std::pair{ResTable_config::CONFIG_DENSITY, "screen_density"},
+ std::pair{ResTable_config::CONFIG_SCREEN_SIZE, "screen_size"},
+ std::pair{ResTable_config::CONFIG_SMALLEST_SCREEN_SIZE, "screen_smallest_size"},
+ std::pair{ResTable_config::CONFIG_VERSION, "version"},
+ std::pair{ResTable_config::CONFIG_SCREEN_LAYOUT, "screen_layout"},
+ std::pair{ResTable_config::CONFIG_UI_MODE, "ui_mode"},
+ std::pair{ResTable_config::CONFIG_LAYOUTDIR, "layout_dir"},
+ std::pair{ResTable_config::CONFIG_SCREEN_ROUND, "screen_round"},
+ std::pair{ResTable_config::CONFIG_COLOR_MODE, "color_mode"},
+ std::pair{ResTable_config::CONFIG_GRAMMATICAL_GENDER, "grammatical_gender"}};
+ const char* delimiter = "";
+ for (auto&& pair : kValues) {
+ if (qualifiers & pair.first) {
+ printer_->Print(StringPrintf("%s%s", delimiter, pair.second));
+ delimiter = "|";
+ }
+ }
+ }
+
+ bool PrintTypeSpec(const ResTable_typeSpec* chunk) const {
+ printer_->Print(StringPrintf(" id: 0x%02x", android::util::DeviceToHost32(chunk->id)));
+ printer_->Print(StringPrintf(" types: %u", android::util::DeviceToHost16(chunk->typesCount)));
+ printer_->Print(
+ StringPrintf(" entry configs: %u\n", android::util::DeviceToHost32(chunk->entryCount)));
+ printer_->Print("Entry qualifier masks:\n");
+ printer_->Indent();
+ std::span<const uint32_t> masks(reinterpret_cast<const uint32_t*>(GetChunkData(&chunk->header)),
+ GetChunkDataLen(&chunk->header) / sizeof(uint32_t));
+ int i = 0;
+ int non_empty_count = 0;
+ for (auto dev_mask : masks) {
+ auto mask = android::util::DeviceToHost32(dev_mask);
+ if (mask == 0) {
+ i++;
+ continue;
+ }
+ ++non_empty_count;
+ printer_->Print(StringPrintf("#0x%02x = ", i++));
+ if (mask & ResTable_typeSpec::SPEC_PUBLIC) {
+ mask &= ~ResTable_typeSpec::SPEC_PUBLIC;
+ printer_->Print("(PUBLIC) ");
+ }
+ if (mask & ResTable_typeSpec::SPEC_STAGED_API) {
+ mask &= ~ResTable_typeSpec::SPEC_STAGED_API;
+ printer_->Print("(STAGED) ");
+ }
+ PrintQualifiers(mask);
+ printer_->Print("\n");
+ }
+ if (non_empty_count > 0) {
+ printer_->Print("\n");
+ } else {
+ printer_->Print("(all empty)\n");
+ }
+ printer_->Undent();
+ return true;
+ }
+
bool PrintTableType(const ResTable_type* chunk) {
printer_->Print(StringPrintf(" id: 0x%02x", android::util::DeviceToHost32(chunk->id)));
printer_->Print(StringPrintf(
@@ -864,6 +941,10 @@
PrintTableType(reinterpret_cast<const ResTable_type*>(chunk));
break;
+ case RES_TABLE_TYPE_SPEC_TYPE:
+ PrintTypeSpec(reinterpret_cast<const ResTable_typeSpec*>(chunk));
+ break;
+
default:
printer_->Print("\n");
break;