diff options
author | Adam Lesinski <adamlesinski@google.com> | 2015-05-20 15:24:01 -0700 |
---|---|---|
committer | Adam Lesinski <adamlesinski@google.com> | 2015-06-04 18:00:33 -0700 |
commit | 8c831ca87bb7c8699b2a5cb34b8d35deedf9ce4e (patch) | |
tree | 454f5342f3634e3cb2ea858fcf6226ec3b133911 /tools/aapt2/Main.cpp | |
parent | 581cc1ee59d01fe4b4a31618ab4aedfa639e42b0 (diff) |
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
Diffstat (limited to 'tools/aapt2/Main.cpp')
-rw-r--r-- | tools/aapt2/Main.cpp | 64 |
1 files changed, 50 insertions, 14 deletions
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp index 84957b4fbbd1..de2dafce3352 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 @@ constexpr const char* kAaptVersionStr = "2.0-alpha"; 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 copyFile(const AaptOptions& options, const CompileItem& item, ZipFile* outA } 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 @@ bool compileManifest(const AaptOptions& options, const std::shared_ptr<IResolver 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 void addApkFilesToLinkQueue(const std::u16string& package, const Source& 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 @@ bool link(const AaptOptions& options, const std::shared_ptr<ResourceTable>& outT } android::ResTable binTable; - if (!compileManifest(options, resolver, binTable, &outApk)) { + if (!compileManifest(options, resolver, apkFiles, binTable, &outApk)) { return false; } |