diff options
author | 2025-01-08 05:57:41 -0800 | |
---|---|---|
committer | 2025-01-08 05:57:41 -0800 | |
commit | 99b48bdd872e8b2a48904f513b4b9feb8299750e (patch) | |
tree | e11efcb7a5d16f457d8392e1c796ea31813bb1b8 | |
parent | 6e4275255688ab4e7a0bc5602f4ba1ee2958cff4 (diff) |
Revert "[res] Optimize isUpToDate() for ApkAssets"
Revert submission 31021037
Reason for revert: Droidmonitor created revert due to b/388342212. Will be verifying through ABTD before submission.
Reverted changes: /q/submissionid:31021037
Change-Id: I7d0eeaf7476c66f5276c68320f93f2b56953d531
-rw-r--r-- | core/java/android/content/res/ApkAssets.java | 56 | ||||
-rw-r--r-- | core/jni/android_content_res_ApkAssets.cpp | 10 | ||||
-rw-r--r-- | libs/androidfw/ApkAssets.cpp | 9 | ||||
-rw-r--r-- | libs/androidfw/AssetsProvider.cpp | 65 | ||||
-rw-r--r-- | libs/androidfw/Idmap.cpp | 21 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/ApkAssets.h | 2 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/AssetsProvider.h | 23 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/Idmap.h | 32 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/misc.h | 6 | ||||
-rw-r--r-- | libs/androidfw/misc.cpp | 69 | ||||
-rw-r--r-- | libs/androidfw/tests/Idmap_test.cpp | 27 |
11 files changed, 112 insertions, 208 deletions
diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java index b938aac811fd..908999b64961 100644 --- a/core/java/android/content/res/ApkAssets.java +++ b/core/java/android/content/res/ApkAssets.java @@ -25,7 +25,6 @@ import android.content.res.loader.ResourcesProvider; import android.ravenwood.annotation.RavenwoodClassLoadHook; import android.ravenwood.annotation.RavenwoodKeepWholeClass; import android.text.TextUtils; -import android.util.Log; import com.android.internal.annotations.GuardedBy; @@ -51,7 +50,6 @@ import java.util.Objects; @RavenwoodKeepWholeClass @RavenwoodClassLoadHook(RavenwoodClassLoadHook.LIBANDROID_LOADING_HOOK) public final class ApkAssets { - private static final boolean DEBUG = false; /** * The apk assets contains framework resource values specified by the system. @@ -136,17 +134,6 @@ public final class ApkAssets { @Nullable private final AssetsProvider mAssets; - @NonNull - private String mName; - - private static final int UPTODATE_FALSE = 0; - private static final int UPTODATE_TRUE = 1; - private static final int UPTODATE_ALWAYS_TRUE = 2; - - // Start with the only value that may change later and would force a native call to - // double check it. - private int mPreviousUpToDateResult = UPTODATE_TRUE; - /** * Creates a new ApkAssets instance from the given path on disk. * @@ -317,7 +304,7 @@ public final class ApkAssets { private ApkAssets(@FormatType int format, @NonNull String path, @PropertyFlags int flags, @Nullable AssetsProvider assets) throws IOException { - this(format, flags, assets, path); + this(format, flags, assets); Objects.requireNonNull(path, "path"); mNativePtr = nativeLoad(format, path, flags, assets); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); @@ -326,7 +313,7 @@ public final class ApkAssets { private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, @PropertyFlags int flags, @Nullable AssetsProvider assets) throws IOException { - this(format, flags, assets, friendlyName); + this(format, flags, assets); Objects.requireNonNull(fd, "fd"); Objects.requireNonNull(friendlyName, "friendlyName"); mNativePtr = nativeLoadFd(format, fd, friendlyName, flags, assets); @@ -336,7 +323,7 @@ public final class ApkAssets { private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags, @Nullable AssetsProvider assets) throws IOException { - this(format, flags, assets, friendlyName); + this(format, flags, assets); Objects.requireNonNull(fd, "fd"); Objects.requireNonNull(friendlyName, "friendlyName"); mNativePtr = nativeLoadFdOffsets(format, fd, friendlyName, offset, length, flags, assets); @@ -344,17 +331,16 @@ public final class ApkAssets { } private ApkAssets(@PropertyFlags int flags, @Nullable AssetsProvider assets) { - this(FORMAT_APK, flags, assets, "empty"); + this(FORMAT_APK, flags, assets); mNativePtr = nativeLoadEmpty(flags, assets); mStringBlock = null; } private ApkAssets(@FormatType int format, @PropertyFlags int flags, - @Nullable AssetsProvider assets, @NonNull String name) { + @Nullable AssetsProvider assets) { mFlags = flags; mAssets = assets; mIsOverlay = format == FORMAT_IDMAP; - if (DEBUG) mName = name; } @UnsupportedAppUsage @@ -435,41 +421,13 @@ public final class ApkAssets { } } - private static double intervalMs(long beginNs, long endNs) { - return (endNs - beginNs) / 1000000.0; - } - /** * Returns false if the underlying APK was changed since this ApkAssets was loaded. */ public boolean isUpToDate() { - // This function is performance-critical - it's called multiple times on every Resources - // object creation, and on few other cache accesses - so it's important to avoid the native - // call when we know for sure what it will return (which is the case for both ALWAYS_TRUE - // and FALSE). - if (mPreviousUpToDateResult != UPTODATE_TRUE) { - return mPreviousUpToDateResult == UPTODATE_ALWAYS_TRUE; - } - final long beforeTs, afterLockTs, afterNativeTs, afterUnlockTs; - if (DEBUG) beforeTs = System.nanoTime(); - final int res; synchronized (this) { - if (DEBUG) afterLockTs = System.nanoTime(); - res = nativeIsUpToDate(mNativePtr); - if (DEBUG) afterNativeTs = System.nanoTime(); - } - if (DEBUG) { - afterUnlockTs = System.nanoTime(); - if (afterUnlockTs - beforeTs >= 10L * 1000000) { - Log.d("ApkAssets", "isUpToDate(" + mName + ") took " - + intervalMs(beforeTs, afterUnlockTs) - + " ms: " + intervalMs(beforeTs, afterLockTs) - + " / " + intervalMs(afterLockTs, afterNativeTs) - + " / " + intervalMs(afterNativeTs, afterUnlockTs)); - } + return nativeIsUpToDate(mNativePtr); } - mPreviousUpToDateResult = res; - return res != UPTODATE_FALSE; } public boolean isSystem() { @@ -529,7 +487,7 @@ public final class ApkAssets { private static native @NonNull String nativeGetAssetPath(long ptr); private static native @NonNull String nativeGetDebugName(long ptr); private static native long nativeGetStringBlock(long ptr); - @CriticalNative private static native int nativeIsUpToDate(long ptr); + @CriticalNative private static native boolean nativeIsUpToDate(long ptr); private static native long nativeOpenXml(long ptr, @NonNull String fileName) throws IOException; private static native @Nullable OverlayableInfo nativeGetOverlayableInfo(long ptr, String overlayableName) throws IOException; diff --git a/core/jni/android_content_res_ApkAssets.cpp b/core/jni/android_content_res_ApkAssets.cpp index 0da9b188ac5a..1e7bfe32ba79 100644 --- a/core/jni/android_content_res_ApkAssets.cpp +++ b/core/jni/android_content_res_ApkAssets.cpp @@ -129,8 +129,8 @@ class LoaderAssetsProvider : public AssetsProvider { return debug_name_; } - UpToDate IsUpToDate() const override { - return UpToDate::Always; + bool IsUpToDate() const override { + return true; } ~LoaderAssetsProvider() override { @@ -443,10 +443,10 @@ static jlong NativeGetStringBlock(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) return reinterpret_cast<jlong>(apk_assets->GetLoadedArsc()->GetStringPool()); } -static jint NativeIsUpToDate(CRITICAL_JNI_PARAMS_COMMA jlong ptr) { +static jboolean NativeIsUpToDate(CRITICAL_JNI_PARAMS_COMMA jlong ptr) { auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); - return (jint)apk_assets->IsUpToDate(); + return apk_assets->IsUpToDate() ? JNI_TRUE : JNI_FALSE; } static jlong NativeOpenXml(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring file_name) { @@ -558,7 +558,7 @@ static const JNINativeMethod gApkAssetsMethods[] = { {"nativeGetDebugName", "(J)Ljava/lang/String;", (void*)NativeGetDebugName}, {"nativeGetStringBlock", "(J)J", (void*)NativeGetStringBlock}, // @CriticalNative - {"nativeIsUpToDate", "(J)I", (void*)NativeIsUpToDate}, + {"nativeIsUpToDate", "(J)Z", (void*)NativeIsUpToDate}, {"nativeOpenXml", "(JLjava/lang/String;)J", (void*)NativeOpenXml}, {"nativeGetOverlayableInfo", "(JLjava/lang/String;)Landroid/content/om/OverlayableInfo;", (void*)NativeGetOverlayableInfo}, diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp index e693fcfd3918..dbb891455ddd 100644 --- a/libs/androidfw/ApkAssets.cpp +++ b/libs/androidfw/ApkAssets.cpp @@ -162,13 +162,10 @@ const std::string& ApkAssets::GetDebugName() const { return assets_provider_->GetDebugName(); } -UpToDate ApkAssets::IsUpToDate() const { +bool ApkAssets::IsUpToDate() const { // Loaders are invalidated by the app, not the system, so assume they are up to date. - if (IsLoader()) { - return UpToDate::Always; - } - const auto idmap_res = loaded_idmap_ ? loaded_idmap_->IsUpToDate() : UpToDate::Always; - return combine(idmap_res, [this] { return assets_provider_->IsUpToDate(); }); + return IsLoader() || ((!loaded_idmap_ || loaded_idmap_->IsUpToDate()) + && assets_provider_->IsUpToDate()); } } // namespace android diff --git a/libs/androidfw/AssetsProvider.cpp b/libs/androidfw/AssetsProvider.cpp index 59c6aba7b8b0..2d3c06506a1f 100644 --- a/libs/androidfw/AssetsProvider.cpp +++ b/libs/androidfw/AssetsProvider.cpp @@ -86,9 +86,11 @@ void ZipAssetsProvider::ZipCloser::operator()(ZipArchive* a) const { } ZipAssetsProvider::ZipAssetsProvider(ZipArchiveHandle handle, PathOrDebugName&& path, - package_property_t flags, ModDate last_mod_time) - : zip_handle_(handle), name_(std::move(path)), flags_(flags), last_mod_time_(last_mod_time) { -} + package_property_t flags, time_t last_mod_time) + : zip_handle_(handle), + name_(std::move(path)), + flags_(flags), + last_mod_time_(last_mod_time) {} std::unique_ptr<ZipAssetsProvider> ZipAssetsProvider::Create(std::string path, package_property_t flags, @@ -102,10 +104,10 @@ std::unique_ptr<ZipAssetsProvider> ZipAssetsProvider::Create(std::string path, return {}; } - ModDate mod_date = kInvalidModDate; + struct stat sb{.st_mtime = -1}; // Skip all up-to-date checks if the file won't ever change. - if (isKnownWritablePath(path.c_str()) || !isReadonlyFilesystem(GetFileDescriptor(handle))) { - if (mod_date = getFileModDate(GetFileDescriptor(handle)); mod_date == kInvalidModDate) { + 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. @@ -114,7 +116,7 @@ std::unique_ptr<ZipAssetsProvider> ZipAssetsProvider::Create(std::string path, } return std::unique_ptr<ZipAssetsProvider>( - new ZipAssetsProvider(handle, PathOrDebugName::Path(std::move(path)), flags, mod_date)); + new ZipAssetsProvider(handle, PathOrDebugName::Path(std::move(path)), flags, sb.st_mtime)); } std::unique_ptr<ZipAssetsProvider> ZipAssetsProvider::Create(base::unique_fd fd, @@ -135,10 +137,10 @@ std::unique_ptr<ZipAssetsProvider> ZipAssetsProvider::Create(base::unique_fd fd, return {}; } - ModDate mod_date = kInvalidModDate; + struct stat sb{.st_mtime = -1}; // Skip all up-to-date checks if the file won't ever change. if (!isReadonlyFilesystem(released_fd)) { - if (mod_date = getFileModDate(released_fd); mod_date == kInvalidModDate) { + 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. @@ -148,7 +150,7 @@ std::unique_ptr<ZipAssetsProvider> ZipAssetsProvider::Create(base::unique_fd fd, } return std::unique_ptr<ZipAssetsProvider>(new ZipAssetsProvider( - handle, PathOrDebugName::DebugName(std::move(friendly_name)), flags, mod_date)); + handle, PathOrDebugName::DebugName(std::move(friendly_name)), flags, sb.st_mtime)); } std::unique_ptr<Asset> ZipAssetsProvider::OpenInternal(const std::string& path, @@ -280,16 +282,21 @@ const std::string& ZipAssetsProvider::GetDebugName() const { return name_.GetDebugName(); } -UpToDate ZipAssetsProvider::IsUpToDate() const { - if (last_mod_time_ == kInvalidModDate) { - return UpToDate::Always; +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 + // attempt to refresh the ApkAsset. + return true; } - return fromBool(last_mod_time_ == getFileModDate(GetFileDescriptor(zip_handle_.get()))); + return last_mod_time_ == sb.st_mtime; } -DirectoryAssetsProvider::DirectoryAssetsProvider(std::string&& path, ModDate last_mod_time) - : dir_(std::move(path)), last_mod_time_(last_mod_time) { -} +DirectoryAssetsProvider::DirectoryAssetsProvider(std::string&& path, time_t last_mod_time) + : dir_(std::move(path)), last_mod_time_(last_mod_time) {} std::unique_ptr<DirectoryAssetsProvider> DirectoryAssetsProvider::Create(std::string path) { struct stat sb; @@ -310,7 +317,7 @@ std::unique_ptr<DirectoryAssetsProvider> DirectoryAssetsProvider::Create(std::st const bool isReadonly = isReadonlyFilesystem(path.c_str()); return std::unique_ptr<DirectoryAssetsProvider>( - new DirectoryAssetsProvider(std::move(path), isReadonly ? kInvalidModDate : getModDate(sb))); + new DirectoryAssetsProvider(std::move(path), isReadonly ? -1 : sb.st_mtime)); } std::unique_ptr<Asset> DirectoryAssetsProvider::OpenInternal(const std::string& path, @@ -339,11 +346,17 @@ const std::string& DirectoryAssetsProvider::GetDebugName() const { return dir_; } -UpToDate DirectoryAssetsProvider::IsUpToDate() const { - if (last_mod_time_ == kInvalidModDate) { - return UpToDate::Always; +bool DirectoryAssetsProvider::IsUpToDate() const { + if (last_mod_time_ == -1) { + return true; } - return fromBool(last_mod_time_ == getFileModDate(dir_.c_str())); + 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. + return true; + } + return last_mod_time_ == sb.st_mtime; } MultiAssetsProvider::MultiAssetsProvider(std::unique_ptr<AssetsProvider>&& primary, @@ -384,8 +397,8 @@ const std::string& MultiAssetsProvider::GetDebugName() const { return debug_name_; } -UpToDate MultiAssetsProvider::IsUpToDate() const { - return combine(primary_->IsUpToDate(), [this] { return secondary_->IsUpToDate(); }); +bool MultiAssetsProvider::IsUpToDate() const { + return primary_->IsUpToDate() && secondary_->IsUpToDate(); } EmptyAssetsProvider::EmptyAssetsProvider(std::optional<std::string>&& path) : @@ -429,8 +442,8 @@ const std::string& EmptyAssetsProvider::GetDebugName() const { return kEmpty; } -UpToDate EmptyAssetsProvider::IsUpToDate() const { - return UpToDate::Always; +bool EmptyAssetsProvider::IsUpToDate() const { + return true; } } // namespace android diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp index 262e7df185b7..3ecd82b074a1 100644 --- a/libs/androidfw/Idmap.cpp +++ b/libs/androidfw/Idmap.cpp @@ -22,10 +22,9 @@ #include "android-base/logging.h" #include "android-base/stringprintf.h" #include "android-base/utf8.h" -#include "androidfw/AssetManager.h" +#include "androidfw/misc.h" #include "androidfw/ResourceTypes.h" #include "androidfw/Util.h" -#include "androidfw/misc.h" #include "utils/ByteOrder.h" #include "utils/Trace.h" @@ -269,16 +268,11 @@ LoadedIdmap::LoadedIdmap(const std::string& idmap_path, const Idmap_header* head configurations_(configs), overlay_entries_(overlay_entries), string_pool_(std::move(string_pool)), + idmap_fd_( + android::base::utf8::open(idmap_path.c_str(), O_RDONLY | O_CLOEXEC | O_BINARY | O_PATH)), overlay_apk_path_(overlay_apk_path), target_apk_path_(target_apk_path), - idmap_last_mod_time_(kInvalidModDate) { - if (!isReadonlyFilesystem(std::string(overlay_apk_path_).c_str()) || - !(target_apk_path_ == AssetManager::TARGET_APK_PATH || - isReadonlyFilesystem(std::string(target_apk_path_).c_str()))) { - idmap_fd_.reset( - android::base::utf8::open(idmap_path.c_str(), O_RDONLY | O_CLOEXEC | O_BINARY | O_PATH)); - idmap_last_mod_time_ = getFileModDate(idmap_fd_); - } + idmap_last_mod_time_(getFileModDate(idmap_fd_.get())) { } std::unique_ptr<LoadedIdmap> LoadedIdmap::Load(StringPiece idmap_path, StringPiece idmap_data) { @@ -387,11 +381,8 @@ std::unique_ptr<LoadedIdmap> LoadedIdmap::Load(StringPiece idmap_path, StringPie overlay_entries, std::move(idmap_string_pool), *overlay_path, *target_path)); } -UpToDate LoadedIdmap::IsUpToDate() const { - if (idmap_last_mod_time_ == kInvalidModDate) { - return UpToDate::Always; - } - return fromBool(idmap_last_mod_time_ == getFileModDate(idmap_fd_.get())); +bool LoadedIdmap::IsUpToDate() const { + return idmap_last_mod_time_ == getFileModDate(idmap_fd_.get()); } } // namespace android diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h index 3f6f4661f2f7..231808beb718 100644 --- a/libs/androidfw/include/androidfw/ApkAssets.h +++ b/libs/androidfw/include/androidfw/ApkAssets.h @@ -116,7 +116,7 @@ class ApkAssets : public RefBase { return resources_asset_ != nullptr && resources_asset_->isAllocated(); } - UpToDate IsUpToDate() const; + bool IsUpToDate() const; // DANGER! // This is a destructive method that rips the assets provider out of ApkAssets object. diff --git a/libs/androidfw/include/androidfw/AssetsProvider.h b/libs/androidfw/include/androidfw/AssetsProvider.h index 46d7a57ab763..d33c325ff369 100644 --- a/libs/androidfw/include/androidfw/AssetsProvider.h +++ b/libs/androidfw/include/androidfw/AssetsProvider.h @@ -14,7 +14,8 @@ * limitations under the License. */ -#pragma once +#ifndef ANDROIDFW_ASSETSPROVIDER_H +#define ANDROIDFW_ASSETSPROVIDER_H #include <memory> #include <string> @@ -57,7 +58,7 @@ struct AssetsProvider { WARN_UNUSED virtual const std::string& GetDebugName() const = 0; // Returns whether the interface provides the most recent version of its files. - WARN_UNUSED virtual UpToDate IsUpToDate() const = 0; + WARN_UNUSED virtual bool IsUpToDate() const = 0; // Creates an Asset from a file on disk. static std::unique_ptr<Asset> CreateAssetFromFile(const std::string& path); @@ -94,7 +95,7 @@ struct ZipAssetsProvider : public AssetsProvider { WARN_UNUSED std::optional<std::string_view> GetPath() const override; WARN_UNUSED const std::string& GetDebugName() const override; - WARN_UNUSED UpToDate IsUpToDate() const override; + WARN_UNUSED bool IsUpToDate() const override; WARN_UNUSED std::optional<uint32_t> GetCrc(std::string_view path) const; ~ZipAssetsProvider() override = default; @@ -105,7 +106,7 @@ struct ZipAssetsProvider : public AssetsProvider { private: struct PathOrDebugName; ZipAssetsProvider(ZipArchive* handle, PathOrDebugName&& path, package_property_t flags, - ModDate last_mod_time); + time_t last_mod_time); struct PathOrDebugName { static PathOrDebugName Path(std::string value) { @@ -134,7 +135,7 @@ struct ZipAssetsProvider : public AssetsProvider { std::unique_ptr<ZipArchive, ZipCloser> zip_handle_; PathOrDebugName name_; package_property_t flags_; - ModDate last_mod_time_; + time_t last_mod_time_; }; // Supplies assets from a root directory. @@ -146,7 +147,7 @@ struct DirectoryAssetsProvider : public AssetsProvider { WARN_UNUSED std::optional<std::string_view> GetPath() const override; WARN_UNUSED const std::string& GetDebugName() const override; - WARN_UNUSED UpToDate IsUpToDate() const override; + WARN_UNUSED bool IsUpToDate() const override; ~DirectoryAssetsProvider() override = default; protected: @@ -155,9 +156,9 @@ struct DirectoryAssetsProvider : public AssetsProvider { bool* file_exists) const override; private: - explicit DirectoryAssetsProvider(std::string&& path, ModDate last_mod_time); + explicit DirectoryAssetsProvider(std::string&& path, time_t last_mod_time); std::string dir_; - ModDate last_mod_time_; + time_t last_mod_time_; }; // Supplies assets from a `primary` asset provider and falls back to supplying assets from the @@ -171,7 +172,7 @@ struct MultiAssetsProvider : public AssetsProvider { WARN_UNUSED std::optional<std::string_view> GetPath() const override; WARN_UNUSED const std::string& GetDebugName() const override; - WARN_UNUSED UpToDate IsUpToDate() const override; + WARN_UNUSED bool IsUpToDate() const override; ~MultiAssetsProvider() override = default; protected: @@ -198,7 +199,7 @@ struct EmptyAssetsProvider : public AssetsProvider { WARN_UNUSED std::optional<std::string_view> GetPath() const override; WARN_UNUSED const std::string& GetDebugName() const override; - WARN_UNUSED UpToDate IsUpToDate() const override; + WARN_UNUSED bool IsUpToDate() const override; ~EmptyAssetsProvider() override = default; protected: @@ -211,3 +212,5 @@ struct EmptyAssetsProvider : public AssetsProvider { }; } // namespace android + +#endif /* ANDROIDFW_ASSETSPROVIDER_H */ diff --git a/libs/androidfw/include/androidfw/Idmap.h b/libs/androidfw/include/androidfw/Idmap.h index 87f3c9df9a91..ac75eb3bb98c 100644 --- a/libs/androidfw/include/androidfw/Idmap.h +++ b/libs/androidfw/include/androidfw/Idmap.h @@ -14,7 +14,8 @@ * limitations under the License. */ -#pragma once +#ifndef IDMAP_H_ +#define IDMAP_H_ #include <memory> #include <string> @@ -31,31 +32,6 @@ namespace android { -// An enum that tracks more states than just 'up to date' or 'not' for a resources container: -// there are several cases where we know for sure that the object can't change and won't get -// out of date. Reporting those states to the managed layer allows it to stop checking here -// completely, speeding up the cache lookups by dozens of milliseconds. -enum class UpToDate : int { False, True, Always }; - -// Combines two UpToDate values, and only accesses the second one if it matters to the result. -template <class Getter> -UpToDate combine(UpToDate first, Getter secondGetter) { - switch (first) { - case UpToDate::False: - return UpToDate::False; - case UpToDate::True: { - const auto second = secondGetter(); - return second == UpToDate::False ? UpToDate::False : UpToDate::True; - } - case UpToDate::Always: - return secondGetter(); - } -} - -inline UpToDate fromBool(bool value) { - return value ? UpToDate::True : UpToDate::False; -} - class LoadedIdmap; class IdmapResMap; struct Idmap_header; @@ -220,7 +196,7 @@ class LoadedIdmap { // Returns whether the idmap file on disk has not been modified since the construction of this // LoadedIdmap. - UpToDate IsUpToDate() const; + bool IsUpToDate() const; protected: // Exposed as protected so that tests can subclass and mock this class out. @@ -255,3 +231,5 @@ class LoadedIdmap { }; } // namespace android + +#endif // IDMAP_H_ diff --git a/libs/androidfw/include/androidfw/misc.h b/libs/androidfw/include/androidfw/misc.h index d8ca64a174a2..c9ba8a01a5e9 100644 --- a/libs/androidfw/include/androidfw/misc.h +++ b/libs/androidfw/include/androidfw/misc.h @@ -15,7 +15,6 @@ */ #pragma once -#include <sys/stat.h> #include <time.h> // @@ -65,15 +64,10 @@ ModDate getFileModDate(const char* fileName); /* same, but also returns -1 if the file has already been deleted */ ModDate getFileModDate(int fd); -// Extract the modification date from the stat structure. -ModDate getModDate(const struct ::stat& st); - // Check if |path| or |fd| resides on a readonly filesystem. bool isReadonlyFilesystem(const char* path); bool isReadonlyFilesystem(int fd); -bool isKnownWritablePath(const char* path); - } // namespace android // Whoever uses getFileModDate() will need this as well diff --git a/libs/androidfw/misc.cpp b/libs/androidfw/misc.cpp index 26eb320805c9..32f3624a3aee 100644 --- a/libs/androidfw/misc.cpp +++ b/libs/androidfw/misc.cpp @@ -16,10 +16,10 @@ #define LOG_TAG "misc" -#include "androidfw/misc.h" - -#include <errno.h> -#include <sys/stat.h> +// +// Miscellaneous utility functions. +// +#include <androidfw/misc.h> #include "android-base/logging.h" @@ -28,7 +28,9 @@ #include <sys/vfs.h> #endif // __linux__ -#include <array> +#include <errno.h> +#include <sys/stat.h> + #include <cstdio> #include <cstring> #include <tuple> @@ -38,26 +40,28 @@ namespace android { /* * Get a file's type. */ -FileType getFileType(const char* fileName) { - struct stat sb; - if (stat(fileName, &sb) < 0) { - if (errno == ENOENT || errno == ENOTDIR) - return kFileTypeNonexistent; - else { - PLOG(ERROR) << "getFileType(): stat(" << fileName << ") failed"; - return kFileTypeUnknown; - } - } else { - if (S_ISREG(sb.st_mode)) - return kFileTypeRegular; - else if (S_ISDIR(sb.st_mode)) - return kFileTypeDirectory; - else if (S_ISCHR(sb.st_mode)) - return kFileTypeCharDev; - else if (S_ISBLK(sb.st_mode)) - return kFileTypeBlockDev; - else if (S_ISFIFO(sb.st_mode)) - return kFileTypeFifo; +FileType getFileType(const char* fileName) +{ + struct stat sb; + + if (stat(fileName, &sb) < 0) { + if (errno == ENOENT || errno == ENOTDIR) + return kFileTypeNonexistent; + else { + PLOG(ERROR) << "getFileType(): stat(" << fileName << ") failed"; + return kFileTypeUnknown; + } + } else { + if (S_ISREG(sb.st_mode)) + return kFileTypeRegular; + else if (S_ISDIR(sb.st_mode)) + return kFileTypeDirectory; + else if (S_ISCHR(sb.st_mode)) + return kFileTypeCharDev; + else if (S_ISBLK(sb.st_mode)) + return kFileTypeBlockDev; + else if (S_ISFIFO(sb.st_mode)) + return kFileTypeFifo; #if defined(S_ISLNK) else if (S_ISLNK(sb.st_mode)) return kFileTypeSymlink; @@ -71,7 +75,7 @@ FileType getFileType(const char* fileName) { } } -ModDate getModDate(const struct stat& st) { +static ModDate getModDate(const struct stat& st) { #ifdef _WIN32 return st.st_mtime; #elif defined(__APPLE__) @@ -109,14 +113,8 @@ bool isReadonlyFilesystem(const char*) { bool isReadonlyFilesystem(int) { return false; } -bool isKnownWritablePath(const char*) { - return false; -} #else // __linux__ bool isReadonlyFilesystem(const char* path) { - if (isKnownWritablePath(path)) { - return false; - } struct statfs sfs; if (::statfs(path, &sfs)) { PLOG(ERROR) << "isReadonlyFilesystem(): statfs(" << path << ") failed"; @@ -133,13 +131,6 @@ bool isReadonlyFilesystem(int fd) { } return (sfs.f_flags & ST_RDONLY) != 0; } - -bool isKnownWritablePath(const char* path) { - // We know that all paths in /data/ are writable. - static constexpr char kRwPrefix[] = "/data/"; - return strncmp(kRwPrefix, path, std::size(kRwPrefix) - 1) == 0; -} - #endif // __linux__ } // namespace android diff --git a/libs/androidfw/tests/Idmap_test.cpp b/libs/androidfw/tests/Idmap_test.cpp index 22b9e69500d9..cb2e56f5f5e4 100644 --- a/libs/androidfw/tests/Idmap_test.cpp +++ b/libs/androidfw/tests/Idmap_test.cpp @@ -218,11 +218,10 @@ TEST_F(IdmapTest, OverlayAssetsIsUpToDate) { auto apk_assets = ApkAssets::LoadOverlay(temp_file.path); ASSERT_NE(nullptr, apk_assets); - ASSERT_TRUE(apk_assets->IsOverlay()); - ASSERT_EQ(UpToDate::True, apk_assets->IsUpToDate()); + ASSERT_TRUE(apk_assets->IsUpToDate()); unlink(temp_file.path); - ASSERT_EQ(UpToDate::False, apk_assets->IsUpToDate()); + ASSERT_FALSE(apk_assets->IsUpToDate()); const auto sleep_duration = std::chrono::nanoseconds(std::max(kModDateResolutionNs, 1'000'000ull)); @@ -231,27 +230,7 @@ TEST_F(IdmapTest, OverlayAssetsIsUpToDate) { base::WriteStringToFile("hello", temp_file.path); std::this_thread::sleep_for(sleep_duration); - ASSERT_EQ(UpToDate::False, apk_assets->IsUpToDate()); -} - -TEST(IdmapTestUpToDate, Combine) { - ASSERT_EQ(UpToDate::False, combine(UpToDate::False, [] { - ADD_FAILURE(); // Shouldn't get called at all. - return UpToDate::False; - })); - - ASSERT_EQ(UpToDate::False, combine(UpToDate::True, [] { return UpToDate::False; })); - - ASSERT_EQ(UpToDate::True, combine(UpToDate::True, [] { return UpToDate::True; })); - ASSERT_EQ(UpToDate::True, combine(UpToDate::True, [] { return UpToDate::Always; })); - ASSERT_EQ(UpToDate::True, combine(UpToDate::Always, [] { return UpToDate::True; })); - - ASSERT_EQ(UpToDate::Always, combine(UpToDate::Always, [] { return UpToDate::Always; })); -} - -TEST(IdmapTestUpToDate, FromBool) { - ASSERT_EQ(UpToDate::False, fromBool(false)); - ASSERT_EQ(UpToDate::True, fromBool(true)); + ASSERT_FALSE(apk_assets->IsUpToDate()); } } // namespace |