AAPT2: Share split functionality between link and optimize
Generating splits should be possible to do from the optimize command.
This means that a lot of infrastructure around split APKs can be
shared by both the optimize and link phase.
Bug: 35925830
Change-Id: Ia88b9e4bff300a56353b2f7a4a2547c8eb43a299
Test: manual
diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp
index d9ea1bc..4a278f63 100644
--- a/tools/aapt2/xml/XmlDom.cpp
+++ b/tools/aapt2/xml/XmlDom.cpp
@@ -25,6 +25,7 @@
#include "android-base/logging.h"
+#include "ResourceUtils.h"
#include "XmlPullParser.h"
#include "util/Util.h"
@@ -193,16 +194,14 @@
stack->pending_comment += comment;
}
-std::unique_ptr<XmlResource> Inflate(std::istream* in, IDiagnostics* diag,
- const Source& source) {
+std::unique_ptr<XmlResource> Inflate(std::istream* in, IDiagnostics* diag, const Source& source) {
Stack stack;
XML_Parser parser = XML_ParserCreateNS(nullptr, kXmlNamespaceSep);
XML_SetUserData(parser, &stack);
XML_UseParserAsHandlerArg(parser);
XML_SetElementHandler(parser, StartElementHandler, EndElementHandler);
- XML_SetNamespaceDeclHandler(parser, StartNamespaceHandler,
- EndNamespaceHandler);
+ XML_SetNamespaceDeclHandler(parser, StartNamespaceHandler, EndNamespaceHandler);
XML_SetCharacterDataHandler(parser, CharacterDataHandler);
XML_SetCommentHandler(parser, CommentDataHandler);
@@ -215,8 +214,7 @@
break;
}
- if (XML_Parse(parser, buffer, in->gcount(), in->eof()) ==
- XML_STATUS_ERROR) {
+ if (XML_Parse(parser, buffer, in->gcount(), in->eof()) == XML_STATUS_ERROR) {
stack.root = {};
diag->Error(DiagMessage(source.WithLine(XML_GetCurrentLineNumber(parser)))
<< XML_ErrorString(XML_GetErrorCode(parser)));
@@ -226,13 +224,12 @@
XML_ParserFree(parser);
if (stack.root) {
- return util::make_unique<XmlResource>(ResourceFile{{}, {}, source},
- std::move(stack.root));
+ return util::make_unique<XmlResource>(ResourceFile{{}, {}, source}, std::move(stack.root));
}
return {};
}
-static void CopyAttributes(Element* el, android::ResXMLParser* parser) {
+static void CopyAttributes(Element* el, android::ResXMLParser* parser, StringPool* out_pool) {
const size_t attr_count = parser->getAttributeCount();
if (attr_count > 0) {
el->attributes.reserve(attr_count);
@@ -253,18 +250,26 @@
if (str16) {
attr.value = util::Utf16ToUtf8(StringPiece16(str16, len));
}
+
+ android::Res_value res_value;
+ if (parser->getAttributeValue(i, &res_value) > 0) {
+ attr.compiled_value = ResourceUtils::ParseBinaryResValue(
+ ResourceType::kAnim, {}, parser->getStrings(), res_value, out_pool);
+ }
+
el->attributes.push_back(std::move(attr));
}
}
}
-std::unique_ptr<XmlResource> Inflate(const void* data, size_t data_len,
- IDiagnostics* diag, const Source& source) {
+std::unique_ptr<XmlResource> Inflate(const void* data, size_t data_len, IDiagnostics* diag,
+ const Source& source) {
// We import the android namespace because on Windows NO_ERROR is a macro, not
// an enum, which
// causes errors when qualifying it with android::
using namespace android;
+ StringPool string_pool;
std::unique_ptr<Node> root;
std::stack<Node*> node_stack;
@@ -307,7 +312,7 @@
node->name = util::Utf16ToUtf8(StringPiece16(str16, len));
}
- CopyAttributes(node.get(), &tree);
+ CopyAttributes(node.get(), &tree, &string_pool);
new_node = std::move(node);
break;
@@ -352,7 +357,7 @@
}
}
}
- return util::make_unique<XmlResource>(ResourceFile{}, std::move(root));
+ return util::make_unique<XmlResource>(ResourceFile{}, std::move(root), std::move(string_pool));
}
std::unique_ptr<Node> Namespace::Clone() {
diff --git a/tools/aapt2/xml/XmlDom.h b/tools/aapt2/xml/XmlDom.h
index 90cdfb6..f1d0953 100644
--- a/tools/aapt2/xml/XmlDom.h
+++ b/tools/aapt2/xml/XmlDom.h
@@ -129,21 +129,21 @@
public:
ResourceFile file;
std::unique_ptr<xml::Node> root;
+ StringPool string_pool;
};
/**
* Inflates an XML DOM from a text stream, logging errors to the logger.
* Returns the root node on success, or nullptr on failure.
*/
-std::unique_ptr<XmlResource> Inflate(std::istream* in, IDiagnostics* diag,
- const Source& source);
+std::unique_ptr<XmlResource> Inflate(std::istream* in, IDiagnostics* diag, const Source& source);
/**
* Inflates an XML DOM from a binary ResXMLTree, logging errors to the logger.
* Returns the root node on success, or nullptr on failure.
*/
-std::unique_ptr<XmlResource> Inflate(const void* data, size_t data_len,
- IDiagnostics* diag, const Source& source);
+std::unique_ptr<XmlResource> Inflate(const void* data, size_t data_len, IDiagnostics* diag,
+ const Source& source);
Element* FindRootElement(XmlResource* doc);
Element* FindRootElement(Node* node);