summaryrefslogtreecommitdiff
path: root/tools/aapt2/cmd/Convert.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aapt2/cmd/Convert.cpp')
-rw-r--r--tools/aapt2/cmd/Convert.cpp79
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;
}