libandroidfw: Support loading ApkAssets from a file descriptor
Test: make aapt2_tests
Change-Id: I041f9e9e3d3f6a10684cbd8baa49f4dda7d6dc40
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 158df13..da0205d 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -47,12 +47,12 @@
}
std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system) {
- return ApkAssets::LoadImpl(path, nullptr, nullptr, system, false /*load_as_shared_library*/);
+ return LoadImpl({} /*fd*/, path, nullptr, nullptr, system, false /*load_as_shared_library*/);
}
std::unique_ptr<const ApkAssets> ApkAssets::LoadAsSharedLibrary(const std::string& path,
bool system) {
- return ApkAssets::LoadImpl(path, nullptr, nullptr, system, true /*load_as_shared_library*/);
+ return LoadImpl({} /*fd*/, path, nullptr, nullptr, system, true /*load_as_shared_library*/);
}
std::unique_ptr<const ApkAssets> ApkAssets::LoadOverlay(const std::string& idmap_path,
@@ -70,8 +70,15 @@
LOG(ERROR) << "failed to load IDMAP " << idmap_path;
return {};
}
- return LoadImpl(loaded_idmap->OverlayApkPath(), std::move(idmap_asset), std::move(loaded_idmap),
- system, false /*load_as_shared_library*/);
+ return LoadImpl({} /*fd*/, loaded_idmap->OverlayApkPath(), std::move(idmap_asset),
+ std::move(loaded_idmap), system, false /*load_as_shared_library*/);
+}
+
+std::unique_ptr<const ApkAssets> ApkAssets::LoadFromFd(unique_fd fd,
+ const std::string& friendly_name,
+ bool system, bool force_shared_lib) {
+ return LoadImpl(std::move(fd), friendly_name, nullptr /*idmap_asset*/, nullptr /*loaded_idmap*/,
+ system, force_shared_lib);
}
std::unique_ptr<Asset> ApkAssets::CreateAssetFromFile(const std::string& path) {
@@ -96,11 +103,19 @@
}
std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(
- const std::string& path, std::unique_ptr<Asset> idmap_asset,
+ unique_fd fd, const std::string& path, std::unique_ptr<Asset> idmap_asset,
std::unique_ptr<const LoadedIdmap> loaded_idmap, bool system, bool load_as_shared_library) {
ATRACE_CALL();
+
::ZipArchiveHandle unmanaged_handle;
- int32_t result = ::OpenArchive(path.c_str(), &unmanaged_handle);
+ int32_t result;
+ if (fd >= 0) {
+ result =
+ ::OpenArchiveFd(fd.release(), path.c_str(), &unmanaged_handle, true /*assume_ownership*/);
+ } else {
+ result = ::OpenArchive(path.c_str(), &unmanaged_handle);
+ }
+
if (result != 0) {
LOG(ERROR) << "Failed to open APK '" << path << "' " << ::ErrorCodeString(result);
return {};