From 3edd47264335cf609ac6e733db77522f7c959c3f Mon Sep 17 00:00:00 2001 From: Shane Farmer Date: Fri, 1 Sep 2017 14:34:22 -0700 Subject: AAPT2: Set the minSdkVersion when generating multiple APKs. When generating multiple APKs from a configuration file, check to see if we have filtered resource by minSdkVersion and update the manifest to reflect this. We only want to inflate and modify the manifest file if there is an update to be applied. Bug: 37944703 Bug: 67005138 Test: Ran unit tests Test: Manually split an APK and verified the manifest by dumping with AAPT (both xmltree and badging). Change-Id: I64a0e4889d7d9e57373369b044a091287b06cc35 --- tools/aapt2/LoadedApk.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'tools/aapt2/LoadedApk.cpp') diff --git a/tools/aapt2/LoadedApk.cpp b/tools/aapt2/LoadedApk.cpp index b80780e33dfa..6f2b86528b5b 100644 --- a/tools/aapt2/LoadedApk.cpp +++ b/tools/aapt2/LoadedApk.cpp @@ -20,11 +20,15 @@ #include "ValueVisitor.h" #include "flatten/Archive.h" #include "flatten/TableFlattener.h" +#include "flatten/XmlFlattener.h" #include "io/BigBufferInputStream.h" #include "io/Util.h" +#include "xml/XmlDom.h" namespace aapt { +using xml::XmlResource; + std::unique_ptr LoadedApk::LoadApkFromPath(IAaptContext* context, const android::StringPiece& path) { Source source(path); @@ -52,6 +56,7 @@ std::unique_ptr LoadedApk::LoadApkFromPath(IAaptContext* context, if (!parser.Parse()) { return {}; } + return util::make_unique(source, std::move(apk), std::move(table)); } @@ -63,7 +68,7 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, const TableFlattenerOption bool LoadedApk::WriteToArchive(IAaptContext* context, ResourceTable* split_table, const TableFlattenerOptions& options, FilterChain* filters, - IArchiveWriter* writer) { + IArchiveWriter* writer, XmlResource* manifest) { std::set referenced_resources; // List the files being referenced in the resource table. for (auto& pkg : split_table->packages) { @@ -119,6 +124,20 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, ResourceTable* split_table return false; } + } else if (manifest != nullptr && path == "AndroidManifest.xml") { + BigBuffer buffer(8192); + XmlFlattener xml_flattener(&buffer, {}); + if (!xml_flattener.Consume(context, manifest)) { + context->GetDiagnostics()->Error(DiagMessage(path) << "flattening failed"); + return false; + } + + uint32_t compression_flags = file->WasCompressed() ? ArchiveEntry::kCompress : 0u; + io::BigBufferInputStream manifest_buffer_in(&buffer); + if (!io::CopyInputStreamToArchive(context, &manifest_buffer_in, path, compression_flags, + writer)) { + return false; + } } else { uint32_t compression_flags = file->WasCompressed() ? ArchiveEntry::kCompress : 0u; if (!io::CopyFileToArchive(context, file, path, compression_flags, writer)) { @@ -129,4 +148,26 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, ResourceTable* split_table return true; } +std::unique_ptr LoadedApk::InflateManifest(IAaptContext* context) { + IDiagnostics* diag = context->GetDiagnostics(); + + io::IFile* manifest_file = GetFileCollection()->FindFile("AndroidManifest.xml"); + if (manifest_file == nullptr) { + diag->Error(DiagMessage(source_) << "no AndroidManifest.xml found"); + return {}; + } + + std::unique_ptr manifest_data = manifest_file->OpenAsData(); + if (manifest_data == nullptr) { + diag->Error(DiagMessage(manifest_file->GetSource()) << "could not open AndroidManifest.xml"); + return {}; + } + + std::unique_ptr manifest = + xml::Inflate(manifest_data->data(), manifest_data->size(), diag, manifest_file->GetSource()); + if (manifest == nullptr) { + diag->Error(DiagMessage() << "failed to read binary AndroidManifest.xml"); + } + return manifest; +} } // namespace aapt -- cgit v1.2.3-59-g8ed1b