summaryrefslogtreecommitdiff
path: root/libs/androidfw/ApkAssets.cpp
diff options
context:
space:
mode:
authorSteven Laver <lavers@google.com>2019-11-05 13:42:59 -0800
committerSteven Laver <lavers@google.com>2019-11-09 01:16:30 +0000
commit7c6cc72e18cc1df5205fd2bc47664e6cc2534ad2 (patch)
treefc34e4ad6037cf231cccc3b56ccd13e82917520a /libs/androidfw/ApkAssets.cpp
parent8f4f93bf3ba75d8e83cb0a8618cb80f226ada5ac (diff)
parentda5e1bd24a9a0ca24e7e49fad9e604409e573376 (diff)
Merge RP1A.191024.001
Change-Id: I5cda3bba276e99d948b752be87d4599e9f882e0f
Diffstat (limited to 'libs/androidfw/ApkAssets.cpp')
-rw-r--r--libs/androidfw/ApkAssets.cpp97
1 files changed, 85 insertions, 12 deletions
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index cf2ef3070385..16dbbf61351a 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -42,12 +42,16 @@ static const std::string kResourcesArsc("resources.arsc");
ApkAssets::ApkAssets(ZipArchiveHandle unmanaged_handle,
const std::string& path,
- time_t last_mod_time)
- : zip_handle_(unmanaged_handle, ::CloseArchive), path_(path), last_mod_time_(last_mod_time) {
+ time_t last_mod_time,
+ bool for_loader)
+ : zip_handle_(unmanaged_handle, ::CloseArchive), path_(path), last_mod_time_(last_mod_time),
+ for_loader_(for_loader) {
}
-std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system) {
- return LoadImpl({} /*fd*/, path, nullptr, nullptr, system, false /*load_as_shared_library*/);
+std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system,
+ bool for_loader) {
+ return LoadImpl({} /*fd*/, path, nullptr, nullptr, system, false /*load_as_shared_library*/,
+ for_loader);
}
std::unique_ptr<const ApkAssets> ApkAssets::LoadAsSharedLibrary(const std::string& path,
@@ -71,14 +75,26 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadOverlay(const std::string& idmap
return {};
}
return LoadImpl({} /*fd*/, loaded_idmap->OverlayApkPath(), std::move(idmap_asset),
- std::move(loaded_idmap), system, false /*load_as_shared_library*/);
+ std::move(loaded_idmap), system, true /*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) {
+ bool system, bool force_shared_lib,
+ bool for_loader) {
return LoadImpl(std::move(fd), friendly_name, nullptr /*idmap_asset*/, nullptr /*loaded_idmap*/,
- system, force_shared_lib);
+ system, force_shared_lib, for_loader);
+}
+
+std::unique_ptr<const ApkAssets> ApkAssets::LoadArsc(const std::string& path,
+ bool for_loader) {
+ return LoadArscImpl({} /*fd*/, path, for_loader);
+}
+
+std::unique_ptr<const ApkAssets> ApkAssets::LoadArsc(unique_fd fd,
+ const std::string& friendly_name,
+ bool for_loader) {
+ return LoadArscImpl(std::move(fd), friendly_name, for_loader);
}
std::unique_ptr<Asset> ApkAssets::CreateAssetFromFile(const std::string& path) {
@@ -104,7 +120,8 @@ std::unique_ptr<Asset> ApkAssets::CreateAssetFromFile(const std::string& path) {
std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(
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) {
+ std::unique_ptr<const LoadedIdmap> loaded_idmap, bool system, bool load_as_shared_library,
+ bool for_loader) {
::ZipArchiveHandle unmanaged_handle;
int32_t result;
if (fd >= 0) {
@@ -123,7 +140,8 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(
time_t last_mod_time = getFileModDate(path.c_str());
// Wrap the handle in a unique_ptr so it gets automatically closed.
- std::unique_ptr<ApkAssets> loaded_apk(new ApkAssets(unmanaged_handle, path, last_mod_time));
+ std::unique_ptr<ApkAssets>
+ loaded_apk(new ApkAssets(unmanaged_handle, path, last_mod_time, for_loader));
// Find the resource table.
::ZipEntry entry;
@@ -147,12 +165,14 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(
// Must retain ownership of the IDMAP Asset so that all pointers to its mmapped data remain valid.
loaded_apk->idmap_asset_ = std::move(idmap_asset);
+ loaded_apk->loaded_idmap_ = std::move(loaded_idmap);
const StringPiece data(
reinterpret_cast<const char*>(loaded_apk->resources_asset_->getBuffer(true /*wordAligned*/)),
loaded_apk->resources_asset_->getLength());
loaded_apk->loaded_arsc_ =
- LoadedArsc::Load(data, loaded_idmap.get(), system, load_as_shared_library);
+ LoadedArsc::Load(data, loaded_apk->loaded_idmap_.get(), system, load_as_shared_library,
+ for_loader);
if (loaded_apk->loaded_arsc_ == nullptr) {
LOG(ERROR) << "Failed to load '" << kResourcesArsc << "' in APK '" << path << "'.";
return {};
@@ -162,8 +182,53 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(
return std::move(loaded_apk);
}
+std::unique_ptr<const ApkAssets> ApkAssets::LoadArscImpl(unique_fd fd,
+ const std::string& path,
+ bool for_loader) {
+ std::unique_ptr<Asset> resources_asset;
+
+ if (fd >= 0) {
+ resources_asset = std::unique_ptr<Asset>(Asset::createFromFd(fd.release(), nullptr,
+ Asset::AccessMode::ACCESS_BUFFER));
+ } else {
+ resources_asset = CreateAssetFromFile(path);
+ }
+
+ if (resources_asset == nullptr) {
+ LOG(ERROR) << "Failed to open ARSC '" << path;
+ return {};
+ }
+
+ time_t last_mod_time = getFileModDate(path.c_str());
+
+ std::unique_ptr<ApkAssets> loaded_apk(new ApkAssets(nullptr, path, last_mod_time, for_loader));
+ loaded_apk->resources_asset_ = std::move(resources_asset);
+
+ const StringPiece data(
+ reinterpret_cast<const char*>(loaded_apk->resources_asset_->getBuffer(true /*wordAligned*/)),
+ loaded_apk->resources_asset_->getLength());
+ loaded_apk->loaded_arsc_ = LoadedArsc::Load(data, nullptr, false, false, for_loader);
+ if (loaded_apk->loaded_arsc_ == nullptr) {
+ LOG(ERROR) << "Failed to load '" << kResourcesArsc << path;
+ return {};
+ }
+
+ // Need to force a move for mingw32.
+ return std::move(loaded_apk);
+}
+
+std::unique_ptr<const ApkAssets> ApkAssets::LoadEmpty(bool for_loader) {
+ std::unique_ptr<ApkAssets> loaded_apk(new ApkAssets(nullptr, "", -1, for_loader));
+ loaded_apk->loaded_arsc_ = LoadedArsc::CreateEmpty();
+ // Need to force a move for mingw32.
+ return std::move(loaded_apk);
+}
+
std::unique_ptr<Asset> ApkAssets::Open(const std::string& path, Asset::AccessMode mode) const {
- CHECK(zip_handle_ != nullptr);
+ // If this is a resource loader from an .arsc, there will be no zip handle
+ if (zip_handle_ == nullptr) {
+ return {};
+ }
::ZipEntry entry;
int32_t result = ::FindEntry(zip_handle_.get(), path, &entry);
@@ -205,7 +270,10 @@ std::unique_ptr<Asset> ApkAssets::Open(const std::string& path, Asset::AccessMod
bool ApkAssets::ForEachFile(const std::string& root_path,
const std::function<void(const StringPiece&, FileType)>& f) const {
- CHECK(zip_handle_ != nullptr);
+ // If this is a resource loader from an .arsc, there will be no zip handle
+ if (zip_handle_ == nullptr) {
+ return false;
+ }
std::string root_path_full = root_path;
if (root_path_full.back() != '/') {
@@ -252,6 +320,11 @@ bool ApkAssets::ForEachFile(const std::string& root_path,
}
bool ApkAssets::IsUpToDate() const {
+ // Loaders are invalidated by the app, not the system, so assume up to date
+ if (for_loader_) {
+ return true;
+ }
+
return last_mod_time_ == getFileModDate(path_.c_str());
}