summaryrefslogtreecommitdiff
path: root/tools/aapt2/LoadedApk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aapt2/LoadedApk.cpp')
-rw-r--r--tools/aapt2/LoadedApk.cpp118
1 files changed, 81 insertions, 37 deletions
diff --git a/tools/aapt2/LoadedApk.cpp b/tools/aapt2/LoadedApk.cpp
index 1dd46ba813db..b353ff00a23f 100644
--- a/tools/aapt2/LoadedApk.cpp
+++ b/tools/aapt2/LoadedApk.cpp
@@ -35,6 +35,43 @@ using ::std::unique_ptr;
namespace aapt {
+static ApkFormat DetermineApkFormat(io::IFileCollection* apk) {
+ if (apk->FindFile(kApkResourceTablePath) != nullptr) {
+ return ApkFormat::kBinary;
+ } else if (apk->FindFile(kProtoResourceTablePath) != nullptr) {
+ return ApkFormat::kProto;
+ } else {
+ // If the resource table is not present, attempt to read the manifest.
+ io::IFile* manifest_file = apk->FindFile(kAndroidManifestPath);
+ if (manifest_file == nullptr) {
+ return ApkFormat::kUnknown;
+ }
+
+ // First try in proto format.
+ std::unique_ptr<io::InputStream> manifest_in = manifest_file->OpenInputStream();
+ if (manifest_in != nullptr) {
+ pb::XmlNode pb_node;
+ io::ProtoInputStreamReader proto_reader(manifest_in.get());
+ if (proto_reader.ReadMessage(&pb_node)) {
+ return ApkFormat::kProto;
+ }
+ }
+
+ // If it didn't work, try in binary format.
+ std::unique_ptr<io::IData> manifest_data = manifest_file->OpenAsData();
+ if (manifest_data != nullptr) {
+ std::string error;
+ std::unique_ptr<xml::XmlResource> manifest =
+ xml::Inflate(manifest_data->data(), manifest_data->size(), &error);
+ if (manifest != nullptr) {
+ return ApkFormat::kBinary;
+ }
+ }
+
+ return ApkFormat::kUnknown;
+ }
+}
+
std::unique_ptr<LoadedApk> LoadedApk::LoadApkFromPath(const StringPiece& path, IDiagnostics* diag) {
Source source(path);
std::string error;
@@ -69,14 +106,14 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadProtoApkFromFileCollection(
return {};
}
- io::ZeroCopyInputAdaptor adaptor(in.get());
- if (!pb_table.ParseFromZeroCopyStream(&adaptor)) {
+ io::ProtoInputStreamReader proto_reader(in.get());
+ if (!proto_reader.ReadMessage(&pb_table)) {
diag->Error(DiagMessage(source) << "failed to read " << kProtoResourceTablePath);
return {};
}
std::string error;
- table = util::make_unique<ResourceTable>();
+ table = util::make_unique<ResourceTable>(/** validate_resources **/ false);
if (!DeserializeTableFromPb(pb_table, collection.get(), table.get(), &error)) {
diag->Error(DiagMessage(source)
<< "failed to deserialize " << kProtoResourceTablePath << ": " << error);
@@ -97,8 +134,8 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadProtoApkFromFileCollection(
}
pb::XmlNode pb_node;
- io::ZeroCopyInputAdaptor manifest_adaptor(manifest_in.get());
- if (!pb_node.ParseFromZeroCopyStream(&manifest_adaptor)) {
+ io::ProtoInputStreamReader proto_reader(manifest_in.get());
+ if (!proto_reader.ReadMessage(&pb_node)) {
diag->Error(DiagMessage(source) << "failed to read proto " << kAndroidManifestPath);
return {};
}
@@ -120,7 +157,7 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadBinaryApkFromFileCollection(
io::IFile* table_file = collection->FindFile(kApkResourceTablePath);
if (table_file != nullptr) {
- table = util::make_unique<ResourceTable>();
+ table = util::make_unique<ResourceTable>(/** validate_resources **/ false);
std::unique_ptr<io::IData> data = table_file->OpenAsData();
if (data == nullptr) {
diag->Error(DiagMessage(source) << "failed to open " << kApkResourceTablePath);
@@ -184,10 +221,7 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, ResourceTable* split_table
std::unique_ptr<io::IFileCollectionIterator> iterator = apk_->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);
// Skip resources that are not referenced if requested.
if (path.find("res/") == 0 && referenced_resources.find(path) == referenced_resources.end()) {
@@ -257,41 +291,51 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, ResourceTable* split_table
return true;
}
-ApkFormat LoadedApk::DetermineApkFormat(io::IFileCollection* apk) {
- if (apk->FindFile(kApkResourceTablePath) != nullptr) {
- return ApkFormat::kBinary;
- } else if (apk->FindFile(kProtoResourceTablePath) != nullptr) {
- return ApkFormat::kProto;
- } else {
- // If the resource table is not present, attempt to read the manifest.
- io::IFile* manifest_file = apk->FindFile(kAndroidManifestPath);
- if (manifest_file == nullptr) {
- return ApkFormat::kUnknown;
+std::unique_ptr<xml::XmlResource> LoadedApk::LoadXml(const std::string& file_path,
+ IDiagnostics* diag) const {
+ io::IFile* file = apk_->FindFile(file_path);
+ if (file == nullptr) {
+ diag->Error(DiagMessage() << "failed to find file");
+ return nullptr;
+ }
+
+ std::unique_ptr<xml::XmlResource> doc;
+ if (format_ == ApkFormat::kProto) {
+ std::unique_ptr<io::InputStream> in = file->OpenInputStream();
+ if (!in) {
+ diag->Error(DiagMessage() << "failed to open file");
+ return nullptr;
}
- // First try in proto format.
- std::unique_ptr<io::InputStream> manifest_in = manifest_file->OpenInputStream();
- if (manifest_in != nullptr) {
- pb::XmlNode pb_node;
- io::ZeroCopyInputAdaptor manifest_adaptor(manifest_in.get());
- if (pb_node.ParseFromZeroCopyStream(&manifest_adaptor)) {
- return ApkFormat::kProto;
- }
+ pb::XmlNode pb_node;
+ io::ProtoInputStreamReader proto_reader(in.get());
+ if (!proto_reader.ReadMessage(&pb_node)) {
+ diag->Error(DiagMessage() << "failed to parse file as proto XML");
+ return nullptr;
}
- // If it didn't work, try in binary format.
- std::unique_ptr<io::IData> manifest_data = manifest_file->OpenAsData();
- if (manifest_data != nullptr) {
- std::string error;
- std::unique_ptr<xml::XmlResource> manifest =
- xml::Inflate(manifest_data->data(), manifest_data->size(), &error);
- if (manifest != nullptr) {
- return ApkFormat::kBinary;
- }
+ std::string err;
+ doc = DeserializeXmlResourceFromPb(pb_node, &err);
+ if (!doc) {
+ diag->Error(DiagMessage() << "failed to deserialize proto XML: " << err);
+ return nullptr;
+ }
+ } else if (format_ == ApkFormat::kBinary) {
+ std::unique_ptr<io::IData> data = file->OpenAsData();
+ if (!data) {
+ diag->Error(DiagMessage() << "failed to open file");
+ return nullptr;
}
- return ApkFormat::kUnknown;
+ std::string err;
+ doc = xml::Inflate(data->data(), data->size(), &err);
+ if (!doc) {
+ diag->Error(DiagMessage() << "failed to parse file as binary XML: " << err);
+ return nullptr;
+ }
}
+
+ return doc;
}
} // namespace aapt