diff options
Diffstat (limited to 'tools/aapt2/cmd/Convert.cpp')
-rw-r--r-- | tools/aapt2/cmd/Convert.cpp | 79 |
1 files changed, 31 insertions, 48 deletions
diff --git a/tools/aapt2/cmd/Convert.cpp b/tools/aapt2/cmd/Convert.cpp index eb307fb1ddce..3ea17552ea7c 100644 --- a/tools/aapt2/cmd/Convert.cpp +++ b/tools/aapt2/cmd/Convert.cpp @@ -14,12 +14,13 @@ * limitations under the License. */ +#include "Convert.h" + #include <vector> #include "android-base/macros.h" #include "androidfw/StringPiece.h" -#include "Flags.h" #include "LoadedApk.h" #include "ValueVisitor.h" #include "cmd/Util.h" @@ -45,7 +46,7 @@ class IApkSerializer { IApkSerializer(IAaptContext* context, const Source& source) : context_(context), source_(source) {} virtual bool SerializeXml(const xml::XmlResource* xml, const std::string& path, bool utf16, - IArchiveWriter* writer) = 0; + IArchiveWriter* writer, uint32_t compression_flags) = 0; virtual bool SerializeTable(ResourceTable* table, IArchiveWriter* writer) = 0; virtual bool SerializeFile(FileReference* file, IArchiveWriter* writer) = 0; @@ -58,7 +59,10 @@ class IApkSerializer { bool ConvertApk(IAaptContext* context, unique_ptr<LoadedApk> apk, IApkSerializer* serializer, IArchiveWriter* writer) { - if (!serializer->SerializeXml(apk->GetManifest(), kAndroidManifestPath, true /*utf16*/, writer)) { + io::IFile* manifest = apk->GetFileCollection()->FindFile(kAndroidManifestPath); + if (!serializer->SerializeXml(apk->GetManifest(), kAndroidManifestPath, true /*utf16*/, writer, + (manifest != nullptr && manifest->WasCompressed()) + ? ArchiveEntry::kCompress : 0u)) { context->GetDiagnostics()->Error(DiagMessage(apk->GetSource()) << "failed to serialize AndroidManifest.xml"); return false; @@ -104,10 +108,7 @@ bool ConvertApk(IAaptContext* context, unique_ptr<LoadedApk> apk, IApkSerializer std::unique_ptr<io::IFileCollectionIterator> iterator = apk->GetFileCollection()->Iterator(); while (iterator->HasNext()) { io::IFile* file = iterator->Next(); - std::string path = file->GetSource().path; - // The name of the path has the format "<zip-file-name>@<path-to-file>". - path = path.substr(path.find('@') + 1); // Manifest, resource table and resources have already been taken care of. if (path == kAndroidManifestPath || @@ -135,7 +136,7 @@ class BinaryApkSerializer : public IApkSerializer { : IApkSerializer(context, source), tableFlattenerOptions_(options) {} bool SerializeXml(const xml::XmlResource* xml, const std::string& path, bool utf16, - IArchiveWriter* writer) override { + IArchiveWriter* writer, uint32_t compression_flags) override { BigBuffer buffer(4096); XmlFlattenerOptions options = {}; options.use_utf16 = utf16; @@ -146,8 +147,7 @@ class BinaryApkSerializer : public IApkSerializer { } io::BigBufferInputStream input_stream(&buffer); - return io::CopyInputStreamToArchive(context_, &input_stream, path, ArchiveEntry::kCompress, - writer); + return io::CopyInputStreamToArchive(context_, &input_stream, path, compression_flags, writer); } bool SerializeTable(ResourceTable* table, IArchiveWriter* writer) override { @@ -172,8 +172,8 @@ class BinaryApkSerializer : public IApkSerializer { } pb::XmlNode pb_node; - io::ZeroCopyInputAdaptor adaptor(in.get()); - if (!pb_node.ParseFromZeroCopyStream(&adaptor)) { + io::ProtoInputStreamReader proto_reader(in.get()); + if (!proto_reader.ReadMessage(&pb_node)) { context_->GetDiagnostics()->Error(DiagMessage(source_) << "failed to parse proto XML " << *file->path); return false; @@ -188,7 +188,8 @@ class BinaryApkSerializer : public IApkSerializer { return false; } - if (!SerializeXml(xml.get(), *file->path, false /*utf16*/, writer)) { + if (!SerializeXml(xml.get(), *file->path, false /*utf16*/, writer, + file->file->WasCompressed() ? ArchiveEntry::kCompress : 0u)) { context_->GetDiagnostics()->Error(DiagMessage(source_) << "failed to serialize to binary XML: " << *file->path); return false; @@ -218,10 +219,10 @@ class ProtoApkSerializer : public IApkSerializer { : IApkSerializer(context, source) {} bool SerializeXml(const xml::XmlResource* xml, const std::string& path, bool utf16, - IArchiveWriter* writer) override { + IArchiveWriter* writer, uint32_t compression_flags) override { pb::XmlNode pb_node; SerializeXmlResourceToPb(*xml, &pb_node); - return io::CopyProtoToArchive(context_, &pb_node, path, ArchiveEntry::kCompress, writer); + return io::CopyProtoToArchive(context_, &pb_node, path, compression_flags, writer); } bool SerializeTable(ResourceTable* table, IArchiveWriter* writer) override { @@ -248,7 +249,8 @@ class ProtoApkSerializer : public IApkSerializer { return false; } - if (!SerializeXml(xml.get(), *file->path, false /*utf16*/, writer)) { + if (!SerializeXml(xml.get(), *file->path, false /*utf16*/, writer, + file->file->WasCompressed() ? ArchiveEntry::kCompress : 0u)) { context_->GetDiagnostics()->Error(DiagMessage(source_) << "failed to serialize to proto XML: " << *file->path); return false; @@ -321,37 +323,18 @@ class Context : public IAaptContext { StdErrDiagnostics diag_; }; -int Convert(const vector<StringPiece>& args) { - - static const char* kOutputFormatProto = "proto"; - static const char* kOutputFormatBinary = "binary"; - - Context context; - std::string output_path; - Maybe<std::string> output_format; - TableFlattenerOptions options; - Flags flags = - Flags() - .RequiredFlag("-o", "Output path", &output_path) - .OptionalFlag("--output-format", StringPrintf("Format of the output. Accepted values are " - "'%s' and '%s'. When not set, defaults to '%s'.", kOutputFormatProto, - kOutputFormatBinary, kOutputFormatBinary), &output_format) - .OptionalSwitch("--enable-sparse-encoding", - "Enables encoding sparse entries using a binary search tree.\n" - "This decreases APK size at the cost of resource retrieval performance.", - &options.use_sparse_entries) - .OptionalSwitch("-v", "Enables verbose logging", &context.verbose_); - if (!flags.Parse("aapt2 convert", args, &std::cerr)) { - return 1; - } +const char* ConvertCommand::kOutputFormatProto = "proto"; +const char* ConvertCommand::kOutputFormatBinary = "binary"; - if (flags.GetArgs().size() != 1) { +int ConvertCommand::Action(const std::vector<std::string>& args) { + if (args.size() != 1) { std::cerr << "must supply a single proto APK\n"; - flags.Usage("aapt2 convert", &std::cerr); + Usage(&std::cerr); return 1; } - const StringPiece& path = flags.GetArgs()[0]; + Context context; + const StringPiece& path = args[0]; unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(path, context.GetDiagnostics()); if (apk == nullptr) { context.GetDiagnostics()->Error(DiagMessage(path) << "failed to load APK"); @@ -367,24 +350,24 @@ int Convert(const vector<StringPiece>& args) { context.package_ = app_info.value().package; unique_ptr<IArchiveWriter> writer = - CreateZipFileArchiveWriter(context.GetDiagnostics(), output_path); + CreateZipFileArchiveWriter(context.GetDiagnostics(), output_path_); if (writer == nullptr) { return 1; } unique_ptr<IApkSerializer> serializer; - if (!output_format || output_format.value() == kOutputFormatBinary) { - serializer.reset(new BinaryApkSerializer(&context, apk->GetSource(), options)); - } else if (output_format.value() == kOutputFormatProto) { + if (!output_format_ || output_format_.value() == ConvertCommand::kOutputFormatBinary) { + + serializer.reset(new BinaryApkSerializer(&context, apk->GetSource(), options_)); + } else if (output_format_.value() == ConvertCommand::kOutputFormatProto) { serializer.reset(new ProtoApkSerializer(&context, apk->GetSource())); } else { context.GetDiagnostics()->Error(DiagMessage(path) - << "Invalid value for flag --output-format: " - << output_format.value()); + << "Invalid value for flag --output-format: " + << output_format_.value()); return 1; } - return ConvertApk(&context, std::move(apk), serializer.get(), writer.get()) ? 0 : 1; } |