From b0085ce5b63bc5d2d86eaf84ed20d8a4a7b532a7 Mon Sep 17 00:00:00 2001 From: Winson Date: Tue, 19 Feb 2019 12:48:22 -0800 Subject: [PATCH] Fix AssetManager2 isUpToDate check This logic was lost in the AssetManager1 -> 2 migration. The old AM1 checked the last modification time of the file and compared it to a previously stored value. This re-adds the logic to ApkAssets and fixes the checks in the JNI/Java layer. Unfortunately I couldn't find a failing/practical case where this check mattered. It only came up when diagnosing an issue which ended up being unrelated. Test: manually ran with other overlay changes Change-Id: I758e4af1d32a9c03b2204a8a3a26e82b7e83feda --- core/java/android/content/res/AssetManager.java | 13 ++++++++++--- core/jni/android_content_res_ApkAssets.cpp | 3 +-- libs/androidfw/ApkAssets.cpp | 15 ++++++++++++--- libs/androidfw/include/androidfw/ApkAssets.h | 5 ++++- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 49b4cb01c6a6e..514015fe0c86a 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -1263,12 +1263,19 @@ public final class AssetManager implements AutoCloseable { */ @UnsupportedAppUsage public boolean isUpToDate() { - for (ApkAssets apkAssets : getApkAssets()) { - if (!apkAssets.isUpToDate()) { + synchronized (this) { + if (!mOpen) { return false; } + + for (ApkAssets apkAssets : mApkAssets) { + if (!apkAssets.isUpToDate()) { + return false; + } + } + + return true; } - return true; } /** diff --git a/core/jni/android_content_res_ApkAssets.cpp b/core/jni/android_content_res_ApkAssets.cpp index f40b461a6dfd6..bd4862dfb08de 100644 --- a/core/jni/android_content_res_ApkAssets.cpp +++ b/core/jni/android_content_res_ApkAssets.cpp @@ -106,8 +106,7 @@ static jlong NativeGetStringBlock(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) static jboolean NativeIsUpToDate(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) { const ApkAssets* apk_assets = reinterpret_cast(ptr); - (void)apk_assets; - return JNI_TRUE; + return apk_assets->IsUpToDate() ? JNI_TRUE : JNI_FALSE; } static jlong NativeOpenXml(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring file_name) { diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp index 66a547723b2fc..7b7599ff74ecf 100644 --- a/libs/androidfw/ApkAssets.cpp +++ b/libs/androidfw/ApkAssets.cpp @@ -29,6 +29,7 @@ #include "androidfw/Asset.h" #include "androidfw/Idmap.h" +#include "androidfw/misc.h" #include "androidfw/ResourceTypes.h" #include "androidfw/Util.h" @@ -39,8 +40,10 @@ using base::unique_fd; static const std::string kResourcesArsc("resources.arsc"); -ApkAssets::ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path) - : zip_handle_(unmanaged_handle, ::CloseArchive), path_(path) { +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) { } std::unique_ptr ApkAssets::Load(const std::string& path, bool system) { @@ -116,8 +119,10 @@ std::unique_ptr ApkAssets::LoadImpl( return {}; } + time_t last_mod_time = getFileModDate(path.c_str()); + // Wrap the handle in a unique_ptr so it gets automatically closed. - std::unique_ptr loaded_apk(new ApkAssets(unmanaged_handle, path)); + std::unique_ptr loaded_apk(new ApkAssets(unmanaged_handle, path, last_mod_time)); // Find the resource table. ::ZipString entry_name(kResourcesArsc.c_str()); @@ -248,4 +253,8 @@ bool ApkAssets::ForEachFile(const std::string& root_path, return result == -1; } +bool ApkAssets::IsUpToDate() const { + return last_mod_time_ == getFileModDate(path_.c_str()); +} + } // namespace android diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h index 35bbb5804df46..49fc82bff11eb 100644 --- a/libs/androidfw/include/androidfw/ApkAssets.h +++ b/libs/androidfw/include/androidfw/ApkAssets.h @@ -84,6 +84,8 @@ class ApkAssets { return idmap_asset_.get() != nullptr; } + bool IsUpToDate() const; + private: DISALLOW_COPY_AND_ASSIGN(ApkAssets); @@ -95,12 +97,13 @@ class ApkAssets { // Creates an Asset from any file on the file system. static std::unique_ptr CreateAssetFromFile(const std::string& path); - ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path); + ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path, time_t last_mod_time); using ZipArchivePtr = std::unique_ptr; ZipArchivePtr zip_handle_; const std::string path_; + time_t last_mod_time_; std::unique_ptr resources_asset_; std::unique_ptr idmap_asset_; std::unique_ptr loaded_arsc_;