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.cpp182
1 files changed, 96 insertions, 86 deletions
diff --git a/tools/aapt2/cmd/Convert.cpp b/tools/aapt2/cmd/Convert.cpp
index 3ea17552ea7c..4492f6b49cf0 100644
--- a/tools/aapt2/cmd/Convert.cpp
+++ b/tools/aapt2/cmd/Convert.cpp
@@ -57,78 +57,6 @@ class IApkSerializer {
Source source_;
};
-bool ConvertApk(IAaptContext* context, unique_ptr<LoadedApk> apk, IApkSerializer* serializer,
- IArchiveWriter* 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;
- }
-
- if (apk->GetResourceTable() != nullptr) {
- // The table might be modified by below code.
- auto converted_table = apk->GetResourceTable();
-
- // Resources
- for (const auto& package : converted_table->packages) {
- for (const auto& type : package->types) {
- for (const auto& entry : type->entries) {
- for (const auto& config_value : entry->values) {
- FileReference* file = ValueCast<FileReference>(config_value->value.get());
- if (file != nullptr) {
- if (file->file == nullptr) {
- context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
- << "no file associated with " << *file);
- return false;
- }
-
- if (!serializer->SerializeFile(file, writer)) {
- context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
- << "failed to serialize file " << *file->path);
- return false;
- }
- } // file
- } // config_value
- } // entry
- } // type
- } // package
-
- // Converted resource table
- if (!serializer->SerializeTable(converted_table, writer)) {
- context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
- << "failed to serialize the resource table");
- return false;
- }
- }
-
- // Other files
- std::unique_ptr<io::IFileCollectionIterator> iterator = apk->GetFileCollection()->Iterator();
- while (iterator->HasNext()) {
- io::IFile* file = iterator->Next();
- std::string path = file->GetSource().path;
-
- // Manifest, resource table and resources have already been taken care of.
- if (path == kAndroidManifestPath ||
- path == kApkResourceTablePath ||
- path == kProtoResourceTablePath ||
- path.find("res/") == 0) {
- continue;
- }
-
- if (!io::CopyFileToArchivePreserveCompression(context, file, path, writer)) {
- context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
- << "failed to copy file " << path);
- return false;
- }
- }
-
- return true;
-}
-
-
class BinaryApkSerializer : public IApkSerializer {
public:
BinaryApkSerializer(IAaptContext* context, const Source& source,
@@ -323,12 +251,97 @@ class Context : public IAaptContext {
StdErrDiagnostics diag_;
};
+int Convert(IAaptContext* context, LoadedApk* apk, IArchiveWriter* output_writer,
+ ApkFormat output_format, TableFlattenerOptions& options) {
+ // Do not change the ordering of strings in the values string pool
+ options.sort_stringpool_entries = false;
+
+ unique_ptr<IApkSerializer> serializer;
+ if (output_format == ApkFormat::kBinary) {
+ serializer.reset(new BinaryApkSerializer(context, apk->GetSource(), options));
+ } else if (output_format == ApkFormat::kProto) {
+ serializer.reset(new ProtoApkSerializer(context, apk->GetSource()));
+ } else {
+ context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
+ << "Cannot convert APK to unknown format");
+ return 1;
+ }
+
+ io::IFile* manifest = apk->GetFileCollection()->FindFile(kAndroidManifestPath);
+ if (!serializer->SerializeXml(apk->GetManifest(), kAndroidManifestPath, true /*utf16*/,
+ output_writer, (manifest != nullptr && manifest->WasCompressed())
+ ? ArchiveEntry::kCompress : 0u)) {
+ context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
+ << "failed to serialize AndroidManifest.xml");
+ return 1;
+ }
+
+ if (apk->GetResourceTable() != nullptr) {
+ // The table might be modified by below code.
+ auto converted_table = apk->GetResourceTable();
+
+ // Resources
+ for (const auto& package : converted_table->packages) {
+ for (const auto& type : package->types) {
+ for (const auto& entry : type->entries) {
+ for (const auto& config_value : entry->values) {
+ FileReference* file = ValueCast<FileReference>(config_value->value.get());
+ if (file != nullptr) {
+ if (file->file == nullptr) {
+ context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
+ << "no file associated with " << *file);
+ return 1;
+ }
+
+ if (!serializer->SerializeFile(file, output_writer)) {
+ context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
+ << "failed to serialize file " << *file->path);
+ return 1;
+ }
+ } // file
+ } // config_value
+ } // entry
+ } // type
+ } // package
+
+ // Converted resource table
+ if (!serializer->SerializeTable(converted_table, output_writer)) {
+ context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
+ << "failed to serialize the resource table");
+ return 1;
+ }
+ }
+
+ // Other files
+ std::unique_ptr<io::IFileCollectionIterator> iterator = apk->GetFileCollection()->Iterator();
+ while (iterator->HasNext()) {
+ io::IFile* file = iterator->Next();
+ std::string path = file->GetSource().path;
+
+ // Manifest, resource table and resources have already been taken care of.
+ if (path == kAndroidManifestPath ||
+ path == kApkResourceTablePath ||
+ path == kProtoResourceTablePath ||
+ path.find("res/") == 0) {
+ continue;
+ }
+
+ if (!io::CopyFileToArchivePreserveCompression(context, file, path, output_writer)) {
+ context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
+ << "failed to copy file " << path);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
const char* ConvertCommand::kOutputFormatProto = "proto";
const char* ConvertCommand::kOutputFormatBinary = "binary";
int ConvertCommand::Action(const std::vector<std::string>& args) {
if (args.size() != 1) {
- std::cerr << "must supply a single proto APK\n";
+ std::cerr << "must supply a single APK\n";
Usage(&std::cerr);
return 1;
}
@@ -341,34 +354,31 @@ int ConvertCommand::Action(const std::vector<std::string>& args) {
return 1;
}
- Maybe<AppInfo> app_info =
- ExtractAppInfoFromBinaryManifest(*apk->GetManifest(), context.GetDiagnostics());
+ Maybe<AppInfo> app_info = ExtractAppInfoFromBinaryManifest(*apk->GetManifest(),
+ context.GetDiagnostics());
if (!app_info) {
return 1;
}
context.package_ = app_info.value().package;
-
- unique_ptr<IArchiveWriter> writer =
- CreateZipFileArchiveWriter(context.GetDiagnostics(), output_path_);
+ unique_ptr<IArchiveWriter> writer = CreateZipFileArchiveWriter(context.GetDiagnostics(),
+ output_path_);
if (writer == nullptr) {
return 1;
}
- unique_ptr<IApkSerializer> serializer;
+ ApkFormat format;
if (!output_format_ || output_format_.value() == ConvertCommand::kOutputFormatBinary) {
-
- serializer.reset(new BinaryApkSerializer(&context, apk->GetSource(), options_));
+ format = ApkFormat::kBinary;
} else if (output_format_.value() == ConvertCommand::kOutputFormatProto) {
- serializer.reset(new ProtoApkSerializer(&context, apk->GetSource()));
+ format = ApkFormat::kProto;
} else {
- context.GetDiagnostics()->Error(DiagMessage(path)
- << "Invalid value for flag --output-format: "
- << output_format_.value());
+ context.GetDiagnostics()->Error(DiagMessage(path) << "Invalid value for flag --output-format: "
+ << output_format_.value());
return 1;
}
- return ConvertApk(&context, std::move(apk), serializer.get(), writer.get()) ? 0 : 1;
+ return Convert(&context, apk.get(), writer.get(), format, options_);
}
} // namespace aapt