summaryrefslogtreecommitdiffstats
path: root/tools/aapt2/TableFlattener.cpp
diff options
context:
space:
mode:
authorAdam Lesinski <adamlesinski@google.com>2015-04-30 17:40:46 -0700
committerAdam Lesinski <adamlesinski@google.com>2015-05-04 16:43:24 -0700
commit6ff19664f9279023c96e5a65c3059e1ef4beac0f (patch)
treef193586403acb034359ffbba1f9211827918fe07 /tools/aapt2/TableFlattener.cpp
parent24aad163bc88cb10d2275385e9afc3de7f342d65 (diff)
downloadframeworks_base-6ff19664f9279023c96e5a65c3059e1ef4beac0f.zip
frameworks_base-6ff19664f9279023c96e5a65c3059e1ef4beac0f.tar.gz
frameworks_base-6ff19664f9279023c96e5a65c3059e1ef4beac0f.tar.bz2
AAPT2: Record public status in a more robust way
This allows us to store the source and comments of a resource's public declaration and avoids issues where there is no default configuration for a publicly declared resource (like with drawables of various densities) and AAPT2 mistakenly took this as an error. Change-Id: I07a2fe9f551daefcce842f205fb219d2fa453ebc
Diffstat (limited to 'tools/aapt2/TableFlattener.cpp')
-rw-r--r--tools/aapt2/TableFlattener.cpp56
1 files changed, 41 insertions, 15 deletions
diff --git a/tools/aapt2/TableFlattener.cpp b/tools/aapt2/TableFlattener.cpp
index 406e506..aa0f1d5 100644
--- a/tools/aapt2/TableFlattener.cpp
+++ b/tools/aapt2/TableFlattener.cpp
@@ -31,8 +31,8 @@
namespace aapt {
struct FlatEntry {
- const ResourceEntry& entry;
- const Value& value;
+ const ResourceEntry* entry;
+ const Value* value;
uint32_t entryKey;
uint32_t sourcePathKey;
uint32_t sourceLine;
@@ -48,10 +48,10 @@ public:
mMap = mOut->nextBlock<android::ResTable_map_entry>();
mMap->key.index = flatEntry.entryKey;
mMap->flags = android::ResTable_entry::FLAG_COMPLEX;
- if (flatEntry.entry.publicStatus.isPublic) {
+ if (flatEntry.entry->publicStatus.isPublic) {
mMap->flags |= android::ResTable_entry::FLAG_PUBLIC;
}
- if (flatEntry.value.isWeak()) {
+ if (flatEntry.value->isWeak()) {
mMap->flags |= android::ResTable_entry::FLAG_WEAK;
}
@@ -229,14 +229,14 @@ TableFlattener::TableFlattener(Options options)
bool TableFlattener::flattenValue(BigBuffer* out, const FlatEntry& flatEntry,
SymbolEntryVector* symbols) {
- if (flatEntry.value.isItem()) {
+ if (flatEntry.value->isItem()) {
android::ResTable_entry* entry = out->nextBlock<android::ResTable_entry>();
- if (flatEntry.entry.publicStatus.isPublic) {
+ if (flatEntry.entry->publicStatus.isPublic) {
entry->flags |= android::ResTable_entry::FLAG_PUBLIC;
}
- if (flatEntry.value.isWeak()) {
+ if (flatEntry.value->isWeak()) {
entry->flags |= android::ResTable_entry::FLAG_WEAK;
}
@@ -252,14 +252,14 @@ bool TableFlattener::flattenValue(BigBuffer* out, const FlatEntry& flatEntry,
entry->size += sizeof(*sourceBlock);
}
- const Item* item = static_cast<const Item*>(&flatEntry.value);
+ const Item* item = static_cast<const Item*>(flatEntry.value);
ValueFlattener flattener(out, symbols);
item->accept(flattener, {});
return flattener.result;
}
MapFlattener flattener(out, flatEntry, symbols);
- flatEntry.value.accept(flattener, {});
+ flatEntry.value->accept(flattener, {});
return true;
}
@@ -373,6 +373,15 @@ bool TableFlattener::flatten(BigBuffer* out, const ResourceTable& table) {
}
}
+ const size_t beforePublicHeader = typeBlock.size();
+ Public_header* publicHeader = nullptr;
+ if (mOptions.useExtendedChunks) {
+ publicHeader = typeBlock.nextBlock<Public_header>();
+ publicHeader->header.type = RES_TABLE_PUBLIC_TYPE;
+ publicHeader->header.headerSize = sizeof(*publicHeader);
+ publicHeader->typeId = type->typeId;
+ }
+
// The binary resource table lists resource entries for each configuration.
// We store them inverted, where a resource entry lists the values for each
// configuration available. Here we reverse this to match the binary table.
@@ -387,18 +396,35 @@ bool TableFlattener::flatten(BigBuffer* out, const ResourceTable& table) {
return false;
}
+ if (publicHeader && entry->publicStatus.isPublic) {
+ // Write the public status of this entry.
+ Public_entry* publicEntry = typeBlock.nextBlock<Public_entry>();
+ publicEntry->entryId = static_cast<uint32_t>(entry->entryId);
+ publicEntry->key.index = static_cast<uint32_t>(keyIndex);
+ publicEntry->source.index = static_cast<uint32_t>(sourcePool.makeRef(
+ util::utf8ToUtf16(entry->publicStatus.source.path)).getIndex());
+ publicEntry->sourceLine = static_cast<uint32_t>(entry->publicStatus.source.line);
+ publicHeader->count += 1;
+ }
+
for (const auto& configValue : entry->values) {
data[configValue.config].push_back(FlatEntry{
- *entry,
- *configValue.value,
+ entry,
+ configValue.value.get(),
static_cast<uint32_t>(keyIndex),
static_cast<uint32_t>(sourcePool.makeRef(util::utf8ToUtf16(
- configValue.source.path)).getIndex()),
+ configValue.source.path)).getIndex()),
static_cast<uint32_t>(configValue.source.line)
});
}
}
+ if (publicHeader) {
+ typeBlock.align4();
+ publicHeader->header.size =
+ static_cast<uint32_t>(typeBlock.size() - beforePublicHeader);
+ }
+
// Begin flattening a configuration for the current type.
for (const auto& entry : data) {
const size_t typeHeaderStart = typeBlock.size();
@@ -416,13 +442,13 @@ bool TableFlattener::flatten(BigBuffer* out, const ResourceTable& table) {
const size_t entryStart = typeBlock.size();
for (const FlatEntry& flatEntry : entry.second) {
- assert(flatEntry.entry.entryId < type->entries.size());
- indices[flatEntry.entry.entryId] = typeBlock.size() - entryStart;
+ assert(flatEntry.entry->entryId < type->entries.size());
+ indices[flatEntry.entry->entryId] = typeBlock.size() - entryStart;
if (!flattenValue(&typeBlock, flatEntry, &symbolEntries)) {
Logger::error()
<< "failed to flatten resource '"
<< ResourceNameRef {
- table.getPackage(), type->type, flatEntry.entry.name }
+ table.getPackage(), type->type, flatEntry.entry->name }
<< "' for configuration '"
<< entry.first
<< "'."