AAPT2: Add manifest merging
Now that AAPT2 is library-aware, it needs to take care of
all library related work, including merging manifests.
The logic was taken from the current Java ManifestMerger.
Change-Id: Id93f713f27ae8617922bf89e325e45be9f863c06
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 84957b4..de2dafc 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -23,6 +23,7 @@
#include "Flag.h"
#include "JavaClassGenerator.h"
#include "Linker.h"
+#include "ManifestMerger.h"
#include "ManifestParser.h"
#include "ManifestValidator.h"
#include "NameMangler.h"
@@ -56,6 +57,20 @@
using namespace aapt;
/**
+ * Used with smart pointers to free malloc'ed memory.
+ */
+struct DeleteMalloc {
+ void operator()(void* ptr) {
+ free(ptr);
+ }
+};
+
+struct StaticLibraryData {
+ Source source;
+ std::unique_ptr<ZipFile> apk;
+};
+
+/**
* Collect files from 'root', filtering out any files that do not
* match the FileFilter 'filter'.
*/
@@ -493,6 +508,7 @@
}
bool compileManifest(const AaptOptions& options, const std::shared_ptr<IResolver>& resolver,
+ const std::map<std::shared_ptr<ResourceTable>, StaticLibraryData>& libApks,
const android::ResTable& table, ZipFile* outApk) {
if (options.verbose) {
Logger::note(options.manifest) << "compiling AndroidManifest.xml." << std::endl;
@@ -510,9 +526,40 @@
return false;
}
+ ManifestMerger merger({});
+ if (!merger.setAppManifest(options.manifest, options.appInfo.package, std::move(root))) {
+ return false;
+ }
+
+ for (const auto& entry : libApks) {
+ ZipFile* libApk = entry.second.apk.get();
+ const std::u16string& libPackage = entry.first->getPackage();
+ const Source& libSource = entry.second.source;
+
+ ZipEntry* zipEntry = libApk->getEntryByName("AndroidManifest.xml");
+ if (!zipEntry) {
+ continue;
+ }
+
+ std::unique_ptr<void, DeleteMalloc> uncompressedData = std::unique_ptr<void, DeleteMalloc>(
+ libApk->uncompress(zipEntry));
+ assert(uncompressedData);
+
+ SourceLogger logger(libSource);
+ std::unique_ptr<xml::Node> libRoot = xml::inflate(uncompressedData.get(),
+ zipEntry->getUncompressedLen(), &logger);
+ if (!libRoot) {
+ return false;
+ }
+
+ if (!merger.mergeLibraryManifest(libSource, libPackage, std::move(libRoot))) {
+ return false;
+ }
+ }
+
BigBuffer outBuffer(1024);
- if (!xml::flattenAndLink(options.manifest, root.get(), options.appInfo.package, resolver, {},
- &outBuffer)) {
+ if (!xml::flattenAndLink(options.manifest, merger.getMergedXml(), options.appInfo.package,
+ resolver, {}, &outBuffer)) {
return false;
}
@@ -667,17 +714,6 @@
static constexpr int kOpenFlags = ZipFile::kOpenCreate | ZipFile::kOpenTruncate |
ZipFile::kOpenReadWrite;
-struct DeleteMalloc {
- void operator()(void* ptr) {
- free(ptr);
- }
-};
-
-struct StaticLibraryData {
- Source source;
- std::unique_ptr<ZipFile> apk;
-};
-
bool link(const AaptOptions& options, const std::shared_ptr<ResourceTable>& outTable,
const std::shared_ptr<IResolver>& resolver) {
std::map<std::shared_ptr<ResourceTable>, StaticLibraryData> apkFiles;
@@ -770,7 +806,7 @@
}
android::ResTable binTable;
- if (!compileManifest(options, resolver, binTable, &outApk)) {
+ if (!compileManifest(options, resolver, apkFiles, binTable, &outApk)) {
return false;
}