AAPT2: Add library support
Change-Id: I307f56d9631784ab29ee4156d94886f9b2f25b30
diff --git a/tools/aapt2/BinaryResourceParser.cpp b/tools/aapt2/BinaryResourceParser.cpp
index 3eb96bc..71016c1 100644
--- a/tools/aapt2/BinaryResourceParser.cpp
+++ b/tools/aapt2/BinaryResourceParser.cpp
@@ -17,6 +17,7 @@
#include "BinaryResourceParser.h"
#include "Logger.h"
#include "ResChunkPullParser.h"
+#include "Resolver.h"
#include "ResourceParser.h"
#include "ResourceTable.h"
#include "ResourceTypeExtensions.h"
@@ -33,28 +34,14 @@
using namespace android;
-template <typename T>
-inline static const T* convertTo(const ResChunk_header* chunk) {
- if (chunk->headerSize < sizeof(T)) {
- return nullptr;
- }
- return reinterpret_cast<const T*>(chunk);
-}
-
-inline static const uint8_t* getChunkData(const ResChunk_header& chunk) {
- return reinterpret_cast<const uint8_t*>(&chunk) + chunk.headerSize;
-}
-
-inline static size_t getChunkDataLen(const ResChunk_header& chunk) {
- return chunk.size - chunk.headerSize;
-}
-
/*
* Visitor that converts a reference's resource ID to a resource name,
* given a mapping from resource ID to resource name.
*/
struct ReferenceIdToNameVisitor : ValueVisitor {
- ReferenceIdToNameVisitor(const std::map<ResourceId, ResourceName>& cache) : mCache(cache) {
+ ReferenceIdToNameVisitor(const std::shared_ptr<Resolver>& resolver,
+ std::map<ResourceId, ResourceName>* cache) :
+ mResolver(resolver), mCache(cache) {
}
void visit(Reference& reference, ValueVisitorArgs&) override {
@@ -104,24 +91,39 @@
return;
}
- auto cacheIter = mCache.find(reference.id);
- if (cacheIter == std::end(mCache)) {
- Logger::note() << "failed to find " << reference.id << std::endl;
- } else {
+ auto cacheIter = mCache->find(reference.id);
+ if (cacheIter != mCache->end()) {
reference.name = cacheIter->second;
reference.id = 0;
+ } else {
+ const android::ResTable& table = mResolver->getResTable();
+ android::ResTable::resource_name resourceName;
+ if (table.getResourceName(reference.id.id, false, &resourceName)) {
+ const ResourceType* type = parseResourceType(StringPiece16(resourceName.type,
+ resourceName.typeLen));
+ assert(type);
+ reference.name.package.assign(resourceName.package, resourceName.packageLen);
+ reference.name.type = *type;
+ reference.name.entry.assign(resourceName.name, resourceName.nameLen);
+ reference.id = 0;
+
+ // Add to cache.
+ mCache->insert({reference.id, reference.name});
+ }
}
}
- const std::map<ResourceId, ResourceName>& mCache;
+ std::shared_ptr<Resolver> mResolver;
+ std::map<ResourceId, ResourceName>* mCache;
};
-BinaryResourceParser::BinaryResourceParser(std::shared_ptr<ResourceTable> table,
+BinaryResourceParser::BinaryResourceParser(const std::shared_ptr<ResourceTable>& table,
+ const std::shared_ptr<Resolver>& resolver,
const Source& source,
const void* data,
size_t len) :
- mTable(table), mSource(source), mData(data), mDataLen(len) {
+ mTable(table), mResolver(resolver), mSource(source), mData(data), mDataLen(len) {
}
bool BinaryResourceParser::parse() {
@@ -421,7 +423,7 @@
// Now go through the table and change resource ID references to
// symbolic references.
- ReferenceIdToNameVisitor visitor(mIdIndex);
+ ReferenceIdToNameVisitor visitor(mResolver, &mIdIndex);
for (auto& type : *mTable) {
for (auto& entry : type->entries) {
for (auto& configValue : entry->values) {
@@ -676,7 +678,8 @@
std::unique_ptr<Style> BinaryResourceParser::parseStyle(const ResourceNameRef& name,
const ConfigDescription& config,
const ResTable_map_entry* map) {
- std::unique_ptr<Style> style = util::make_unique<Style>();
+ const bool isWeak = (map->flags & ResTable_entry::FLAG_WEAK) != 0;
+ std::unique_ptr<Style> style = util::make_unique<Style>(isWeak);
if (map->parent.ident == 0) {
// The parent is either not set or it is an unresolved symbol.
// Check to see if it is a symbol.
@@ -759,7 +762,17 @@
const ResTable_map_entry* map) {
std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
for (const ResTable_map& mapEntry : map) {
- styleable->entries.emplace_back(mapEntry.name.ident);
+ if (mapEntry.name.ident == 0) {
+ // The map entry's key (attribute) is not set. This must be
+ // a symbol reference, so resolve it.
+ ResourceNameRef symbol;
+ bool result = getSymbol(&mapEntry.name.ident, &symbol);
+ assert(result);
+ styleable->entries.emplace_back(symbol);
+ } else {
+ // The map entry's key (attribute) is a regular reference.
+ styleable->entries.emplace_back(mapEntry.name.ident);
+ }
}
return styleable;
}