summaryrefslogtreecommitdiff
path: root/libs/androidfw/AssetsProvider.cpp
diff options
context:
space:
mode:
author Yurii Zubrytskyi <zyy@google.com> 2022-12-01 05:32:01 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-12-01 05:32:01 +0000
commit46b0752616f899f0dc0188f8a234449d2e6533d0 (patch)
tree7cccc1ed8d069e66266b3c2b04f4c19b93a04136 /libs/androidfw/AssetsProvider.cpp
parent7b7f8aba2f2c6fca1b065bfe055a4c62d0dd472a (diff)
parent2ab4447ad20bdbf664c00de5f47c2c638ee83241 (diff)
Merge changes Ie5999dda,I2853cd3c,I7d9f1fe3,I19576654,I158af793, ...
* changes: [res] Don't stat asset providers on RO filesystems [res] Change OverlayableInfo to hold string views [res] Change staged alias container to vector [res] Change callback from function to function_ref [res] Reuse memory in RebuildFilterList() [res] Split keys and values in Theme::Entry vector [res] Properly create ZipAssetsProvider with fd
Diffstat (limited to 'libs/androidfw/AssetsProvider.cpp')
-rw-r--r--libs/androidfw/AssetsProvider.cpp54
1 files changed, 35 insertions, 19 deletions
diff --git a/libs/androidfw/AssetsProvider.cpp b/libs/androidfw/AssetsProvider.cpp
index 80e560747a3e..b9264c5d0f2d 100644
--- a/libs/androidfw/AssetsProvider.cpp
+++ b/libs/androidfw/AssetsProvider.cpp
@@ -92,21 +92,27 @@ ZipAssetsProvider::ZipAssetsProvider(ZipArchiveHandle handle, PathOrDebugName&&
last_mod_time_(last_mod_time) {}
std::unique_ptr<ZipAssetsProvider> ZipAssetsProvider::Create(std::string path,
- package_property_t flags) {
+ package_property_t flags,
+ base::unique_fd fd) {
+ const auto released_fd = fd.ok() ? fd.release() : -1;
ZipArchiveHandle handle;
- if (int32_t result = OpenArchive(path.c_str(), &handle); result != 0) {
+ if (int32_t result = released_fd < 0 ? OpenArchive(path.c_str(), &handle)
+ : OpenArchiveFd(released_fd, path.c_str(), &handle)) {
LOG(ERROR) << "Failed to open APK '" << path << "': " << ::ErrorCodeString(result);
CloseArchive(handle);
return {};
}
struct stat sb{.st_mtime = -1};
- if (stat(path.c_str(), &sb) < 0) {
- // Stat requires execute permissions on all directories path to the file. If the process does
- // not have execute permissions on this file, allow the zip to be opened but IsUpToDate() will
- // always have to return true.
- LOG(WARNING) << "Failed to stat file '" << path << "': "
- << base::SystemErrorCodeToString(errno);
+ // Skip all up-to-date checks if the file won't ever change.
+ if (!isReadonlyFilesystem(path.c_str())) {
+ if ((released_fd < 0 ? stat(path.c_str(), &sb) : fstat(released_fd, &sb)) < 0) {
+ // Stat requires execute permissions on all directories path to the file. If the process does
+ // not have execute permissions on this file, allow the zip to be opened but IsUpToDate() will
+ // always have to return true.
+ LOG(WARNING) << "Failed to stat file '" << path << "': "
+ << base::SystemErrorCodeToString(errno);
+ }
}
return std::unique_ptr<ZipAssetsProvider>(
@@ -133,12 +139,15 @@ std::unique_ptr<ZipAssetsProvider> ZipAssetsProvider::Create(base::unique_fd fd,
}
struct stat sb{.st_mtime = -1};
- if (fstat(released_fd, &sb) < 0) {
- // Stat requires execute permissions on all directories path to the file. If the process does
- // not have execute permissions on this file, allow the zip to be opened but IsUpToDate() will
- // always have to return true.
- LOG(WARNING) << "Failed to fstat file '" << friendly_name << "': "
- << base::SystemErrorCodeToString(errno);
+ // Skip all up-to-date checks if the file won't ever change.
+ if (!isReadonlyFilesystem(released_fd)) {
+ if (fstat(released_fd, &sb) < 0) {
+ // Stat requires execute permissions on all directories path to the file. If the process does
+ // not have execute permissions on this file, allow the zip to be opened but IsUpToDate() will
+ // always have to return true.
+ LOG(WARNING) << "Failed to fstat file '" << friendly_name
+ << "': " << base::SystemErrorCodeToString(errno);
+ }
}
return std::unique_ptr<ZipAssetsProvider>(
@@ -275,6 +284,9 @@ const std::string& ZipAssetsProvider::GetDebugName() const {
}
bool ZipAssetsProvider::IsUpToDate() const {
+ if (last_mod_time_ == -1) {
+ return true;
+ }
struct stat sb{};
if (fstat(GetFileDescriptor(zip_handle_.get()), &sb) < 0) {
// If fstat fails on the zip archive, return true so the zip archive the resource system does
@@ -288,7 +300,7 @@ DirectoryAssetsProvider::DirectoryAssetsProvider(std::string&& path, time_t last
: dir_(std::forward<std::string>(path)), last_mod_time_(last_mod_time) {}
std::unique_ptr<DirectoryAssetsProvider> DirectoryAssetsProvider::Create(std::string path) {
- struct stat sb{};
+ struct stat sb;
const int result = stat(path.c_str(), &sb);
if (result == -1) {
LOG(ERROR) << "Failed to find directory '" << path << "'.";
@@ -304,8 +316,9 @@ std::unique_ptr<DirectoryAssetsProvider> DirectoryAssetsProvider::Create(std::st
path += OS_PATH_SEPARATOR;
}
- return std::unique_ptr<DirectoryAssetsProvider>(new DirectoryAssetsProvider(std::move(path),
- sb.st_mtime));
+ const bool isReadonly = isReadonlyFilesystem(path.c_str());
+ return std::unique_ptr<DirectoryAssetsProvider>(
+ new DirectoryAssetsProvider(std::move(path), isReadonly ? -1 : sb.st_mtime));
}
std::unique_ptr<Asset> DirectoryAssetsProvider::OpenInternal(const std::string& path,
@@ -335,7 +348,10 @@ const std::string& DirectoryAssetsProvider::GetDebugName() const {
}
bool DirectoryAssetsProvider::IsUpToDate() const {
- struct stat sb{};
+ if (last_mod_time_ == -1) {
+ return true;
+ }
+ struct stat sb;
if (stat(dir_.c_str(), &sb) < 0) {
// If stat fails on the zip archive, return true so the zip archive the resource system does
// attempt to refresh the ApkAsset.
@@ -431,4 +447,4 @@ bool EmptyAssetsProvider::IsUpToDate() const {
return true;
}
-} // namespace android \ No newline at end of file
+} // namespace android