AAPT2: Fail compiling when private symbols are referenced
Also moved some XML specific stuff into its own directory,
and refactored ReferenceLinker a bit.
Change-Id: I912247a82023c1bbf72dc191fbdaf62858cbec0c
diff --git a/tools/aapt2/flatten/ResourceTypeExtensions.h b/tools/aapt2/flatten/ResourceTypeExtensions.h
index c1ff556..acf5bb5 100644
--- a/tools/aapt2/flatten/ResourceTypeExtensions.h
+++ b/tools/aapt2/flatten/ResourceTypeExtensions.h
@@ -62,7 +62,7 @@
* A raw string value that hasn't had its escape sequences
* processed nor whitespace removed.
*/
- TYPE_RAW_STRING = 0xfe
+ TYPE_RAW_STRING = 0xfe,
};
};
diff --git a/tools/aapt2/flatten/TableFlattener.cpp b/tools/aapt2/flatten/TableFlattener.cpp
index 6b90fb2..636e977 100644
--- a/tools/aapt2/flatten/TableFlattener.cpp
+++ b/tools/aapt2/flatten/TableFlattener.cpp
@@ -78,10 +78,18 @@
explicit SymbolWriter(StringPool* pool) : mPool(pool) {
}
- void addSymbol(const ResourceNameRef& name, size_t offset) {
- symbols.push_back(Entry{ mPool->makeRef(name.package.toString() + u":" +
- toString(name.type).toString() + u"/" +
- name.entry.toString()), offset });
+ void addSymbol(const Reference& ref, size_t offset) {
+ const ResourceName& name = ref.name.value();
+ std::u16string fullName;
+ if (ref.privateReference) {
+ fullName += u"*";
+ }
+
+ if (!name.package.empty()) {
+ fullName += name.package + u":";
+ }
+ fullName += toString(name.type).toString() + u"/" + name.entry;
+ symbols.push_back(Entry{ mPool->makeRef(fullName), offset });
}
void shiftAllOffsets(size_t offset) {
@@ -100,20 +108,23 @@
SymbolWriter* mSymbols;
FlatEntry* mEntry;
BigBuffer* mBuffer;
+ bool mUseExtendedChunks;
size_t mEntryCount = 0;
Maybe<uint32_t> mParentIdent;
Maybe<ResourceNameRef> mParentName;
- MapFlattenVisitor(SymbolWriter* symbols, FlatEntry* entry, BigBuffer* buffer) :
- mSymbols(symbols), mEntry(entry), mBuffer(buffer) {
+ MapFlattenVisitor(SymbolWriter* symbols, FlatEntry* entry, BigBuffer* buffer,
+ bool useExtendedChunks) :
+ mSymbols(symbols), mEntry(entry), mBuffer(buffer),
+ mUseExtendedChunks(useExtendedChunks) {
}
void flattenKey(Reference* key, ResTable_map* outEntry) {
- if (!key->id) {
+ if (!key->id || (key->privateReference && mUseExtendedChunks)) {
assert(key->name && "reference must have a name");
outEntry->name.ident = util::hostToDevice32(0);
- mSymbols->addSymbol(key->name.value(), (mBuffer->size() - sizeof(ResTable_map)) +
+ mSymbols->addSymbol(*key, (mBuffer->size() - sizeof(ResTable_map)) +
offsetof(ResTable_map, name));
} else {
outEntry->name.ident = util::hostToDevice32(key->id.value().id);
@@ -121,16 +132,21 @@
}
void flattenValue(Item* value, ResTable_map* outEntry) {
+ bool privateRef = false;
if (Reference* ref = valueCast<Reference>(value)) {
- if (!ref->id) {
+ privateRef = ref->privateReference && mUseExtendedChunks;
+ if (!ref->id || privateRef) {
assert(ref->name && "reference must have a name");
- mSymbols->addSymbol(ref->name.value(), (mBuffer->size() - sizeof(ResTable_map)) +
+ mSymbols->addSymbol(*ref, (mBuffer->size() - sizeof(ResTable_map)) +
offsetof(ResTable_map, value) + offsetof(Res_value, data));
}
}
bool result = value->flatten(&outEntry->value);
+ if (privateRef) {
+ outEntry->value.data = 0;
+ }
assert(result && "flatten failed");
}
@@ -169,7 +185,8 @@
void visit(Style* style) override {
if (style->parent) {
- if (!style->parent.value().id) {
+ bool privateRef = style->parent.value().privateReference && mUseExtendedChunks;
+ if (!style->parent.value().id || privateRef) {
assert(style->parent.value().name && "reference must have a name");
mParentName = style->parent.value().name;
} else {
@@ -339,21 +356,28 @@
bool flattenValue(FlatEntry* entry, BigBuffer* buffer) {
if (Item* item = valueCast<Item>(entry->value)) {
writeEntry<ResTable_entry, true>(entry, buffer);
+ bool privateRef = false;
if (Reference* ref = valueCast<Reference>(entry->value)) {
- if (!ref->id) {
+ // If there is no ID or the reference is private and we allow extended chunks,
+ // write out a 0 and mark the symbol table with the name of the reference.
+ privateRef = (ref->privateReference && mOptions.useExtendedChunks);
+ if (!ref->id || privateRef) {
assert(ref->name && "reference must have at least a name");
- mSymbols->addSymbol(ref->name.value(),
- buffer->size() + offsetof(Res_value, data));
+ mSymbols->addSymbol(*ref, buffer->size() + offsetof(Res_value, data));
}
}
Res_value* outValue = buffer->nextBlock<Res_value>();
bool result = item->flatten(outValue);
assert(result && "flatten failed");
+ if (privateRef) {
+ // Force the value of 0 so we look up the symbol at unflatten time.
+ outValue->data = 0;
+ }
outValue->size = util::hostToDevice16(sizeof(*outValue));
} else {
const size_t beforeEntry = buffer->size();
ResTable_entry_ext* outEntry = writeEntry<ResTable_entry_ext, false>(entry, buffer);
- MapFlattenVisitor visitor(mSymbols, entry, buffer);
+ MapFlattenVisitor visitor(mSymbols, entry, buffer, mOptions.useExtendedChunks);
entry->value->accept(&visitor);
outEntry->count = util::hostToDevice32(visitor.mEntryCount);
if (visitor.mParentName) {
diff --git a/tools/aapt2/flatten/TableFlattener_test.cpp b/tools/aapt2/flatten/TableFlattener_test.cpp
index 68a1f47..4ffb980 100644
--- a/tools/aapt2/flatten/TableFlattener_test.cpp
+++ b/tools/aapt2/flatten/TableFlattener_test.cpp
@@ -15,11 +15,11 @@
*/
#include "flatten/TableFlattener.h"
+#include "test/Builders.h"
+#include "test/Context.h"
#include "unflatten/BinaryResourceParser.h"
#include "util/Util.h"
-#include "test/Builders.h"
-#include "test/Context.h"
#include <gtest/gtest.h>
diff --git a/tools/aapt2/flatten/XmlFlattener.cpp b/tools/aapt2/flatten/XmlFlattener.cpp
index 4efb08b..8219462 100644
--- a/tools/aapt2/flatten/XmlFlattener.cpp
+++ b/tools/aapt2/flatten/XmlFlattener.cpp
@@ -15,15 +15,14 @@
*/
#include "SdkConstants.h"
-#include "XmlDom.h"
-
#include "flatten/ChunkWriter.h"
#include "flatten/ResourceTypeExtensions.h"
#include "flatten/XmlFlattener.h"
+#include "xml/XmlDom.h"
#include <androidfw/ResourceTypes.h>
-#include <vector>
#include <utils/misc.h>
+#include <vector>
using namespace android;
@@ -306,7 +305,7 @@
return true;
}
-bool XmlFlattener::consume(IAaptContext* context, XmlResource* resource) {
+bool XmlFlattener::consume(IAaptContext* context, xml::XmlResource* resource) {
if (!resource->root) {
return false;
}
diff --git a/tools/aapt2/flatten/XmlFlattener.h b/tools/aapt2/flatten/XmlFlattener.h
index b1fb3a7..a688ac9 100644
--- a/tools/aapt2/flatten/XmlFlattener.h
+++ b/tools/aapt2/flatten/XmlFlattener.h
@@ -17,16 +17,12 @@
#ifndef AAPT_FLATTEN_XMLFLATTENER_H
#define AAPT_FLATTEN_XMLFLATTENER_H
-#include "util/BigBuffer.h"
-
#include "process/IResourceTableConsumer.h"
+#include "util/BigBuffer.h"
+#include "xml/XmlDom.h"
namespace aapt {
-namespace xml {
-struct Node;
-}
-
struct XmlFlattenerOptions {
/**
* Keep attribute raw string values along with typed values.
@@ -45,7 +41,7 @@
mBuffer(buffer), mOptions(options) {
}
- bool consume(IAaptContext* context, XmlResource* resource) override;
+ bool consume(IAaptContext* context, xml::XmlResource* resource) override;
private:
BigBuffer* mBuffer;
diff --git a/tools/aapt2/flatten/XmlFlattener_test.cpp b/tools/aapt2/flatten/XmlFlattener_test.cpp
index 318bcdd..8648879 100644
--- a/tools/aapt2/flatten/XmlFlattener_test.cpp
+++ b/tools/aapt2/flatten/XmlFlattener_test.cpp
@@ -16,11 +16,10 @@
#include "flatten/XmlFlattener.h"
#include "link/Linkers.h"
-#include "util/BigBuffer.h"
-#include "util/Util.h"
-
#include "test/Builders.h"
#include "test/Context.h"
+#include "util/BigBuffer.h"
+#include "util/Util.h"
#include <androidfw/ResourceTypes.h>
#include <gtest/gtest.h>
@@ -45,7 +44,7 @@
.build();
}
- ::testing::AssertionResult flatten(XmlResource* doc, android::ResXMLTree* outTree,
+ ::testing::AssertionResult flatten(xml::XmlResource* doc, android::ResXMLTree* outTree,
XmlFlattenerOptions options = {}) {
BigBuffer buffer(1024);
XmlFlattener flattener(&buffer, options);
@@ -65,7 +64,7 @@
};
TEST_F(XmlFlattenerTest, FlattenXmlWithNoCompiledAttributes) {
- std::unique_ptr<XmlResource> doc = test::buildXmlDom(R"EOF(
+ std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
<View xmlns:test="http://com.test"
attr="hey">
<Layout test:hello="hi" />
@@ -144,7 +143,7 @@
}
TEST_F(XmlFlattenerTest, FlattenCompiledXmlAndStripSdk21) {
- std::unique_ptr<XmlResource> doc = test::buildXmlDom(R"EOF(
+ std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingStart="1dp"
android:colorAccent="#ffffff"/>)EOF");
@@ -169,7 +168,7 @@
}
TEST_F(XmlFlattenerTest, AssignSpecialAttributeIndices) {
- std::unique_ptr<XmlResource> doc = test::buildXmlDom(R"EOF(
+ std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/id"
class="str"
@@ -192,7 +191,7 @@
* namespace.
*/
TEST_F(XmlFlattenerTest, NoNamespaceIsNotTheSameAsEmptyNamespace) {
- std::unique_ptr<XmlResource> doc = test::buildXmlDom("<View package=\"android\"/>");
+ std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom("<View package=\"android\"/>");
android::ResXMLTree tree;
ASSERT_TRUE(flatten(doc.get(), &tree));