diff options
-rw-r--r-- | core/java/android/app/ResourcesManager.java | 4 | ||||
-rw-r--r-- | core/java/android/content/res/AssetManager.java | 36 | ||||
-rw-r--r-- | core/java/android/content/res/ResourcesImpl.java | 13 | ||||
-rw-r--r-- | core/jni/android_util_AssetManager.cpp | 17 | ||||
-rw-r--r-- | libs/androidfw/AssetManager2.cpp | 20 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/AssetManager2.h | 5 |
6 files changed, 70 insertions, 25 deletions
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index 24a51573b48a..625526047212 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -550,7 +550,7 @@ public class ResourcesManager { @UnsupportedAppUsage protected @Nullable AssetManager createAssetManager(@NonNull final ResourcesKey key, @Nullable ApkAssetsSupplier apkSupplier) { - final AssetManager.Builder builder = new AssetManager.Builder(); + final AssetManager.Builder builder = new AssetManager.Builder().setNoInit(); final ArrayList<ApkKey> apkKeys = extractApkKeys(key); for (int i = 0, n = apkKeys.size(); i < n; i++) { @@ -1555,7 +1555,7 @@ public class ResourcesManager { } else if(overlayPaths == null) { return ArrayUtils.cloneOrNull(resourceDirs); } else { - final ArrayList<String> paths = new ArrayList<>(); + final var paths = new ArrayList<String>(overlayPaths.length + resourceDirs.length); for (final String path : overlayPaths) { paths.add(path); } diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 23b9d0b7c9a7..d259e9755a41 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -137,6 +137,8 @@ public final class AssetManager implements AutoCloseable { private ArrayList<ApkAssets> mUserApkAssets = new ArrayList<>(); private ArrayList<ResourcesLoader> mLoaders = new ArrayList<>(); + private boolean mNoInit = false; + public Builder addApkAssets(ApkAssets apkAssets) { mUserApkAssets.add(apkAssets); return this; @@ -147,6 +149,11 @@ public final class AssetManager implements AutoCloseable { return this; } + public Builder setNoInit() { + mNoInit = true; + return this; + } + public AssetManager build() { // Retrieving the system ApkAssets forces their creation as well. final ApkAssets[] systemApkAssets = getSystem().getApkAssets(); @@ -188,7 +195,7 @@ public final class AssetManager implements AutoCloseable { final AssetManager assetManager = new AssetManager(false /*sentinel*/); assetManager.mApkAssets = apkAssets; AssetManager.nativeSetApkAssets(assetManager.mObject, apkAssets, - false /*invalidateCaches*/); + false /*invalidateCaches*/, mNoInit /*preset*/); assetManager.mLoaders = mLoaders.isEmpty() ? null : mLoaders.toArray(new ResourcesLoader[0]); @@ -329,7 +336,7 @@ public final class AssetManager implements AutoCloseable { synchronized (this) { ensureOpenLocked(); mApkAssets = newApkAssets; - nativeSetApkAssets(mObject, mApkAssets, invalidateCaches); + nativeSetApkAssets(mObject, mApkAssets, invalidateCaches, false); if (invalidateCaches) { // Invalidate all caches. invalidateCachesLocked(-1); @@ -496,7 +503,7 @@ public final class AssetManager implements AutoCloseable { mApkAssets = Arrays.copyOf(mApkAssets, count + 1); mApkAssets[count] = assets; - nativeSetApkAssets(mObject, mApkAssets, true); + nativeSetApkAssets(mObject, mApkAssets, true, false); invalidateCachesLocked(-1); return count + 1; } @@ -1503,12 +1510,29 @@ public final class AssetManager implements AutoCloseable { int navigation, int screenWidth, int screenHeight, int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp, int screenLayout, int uiMode, int colorMode, int grammaticalGender, int majorVersion) { + setConfigurationInternal(mcc, mnc, defaultLocale, locales, orientation, + touchscreen, density, keyboard, keyboardHidden, navigation, screenWidth, + screenHeight, smallestScreenWidthDp, screenWidthDp, screenHeightDp, + screenLayout, uiMode, colorMode, grammaticalGender, majorVersion, false); + } + + /** + * Change the configuration used when retrieving resources, and potentially force a refresh of + * the state. Not for use by applications. + * @hide + */ + void setConfigurationInternal(int mcc, int mnc, String defaultLocale, String[] locales, + int orientation, int touchscreen, int density, int keyboard, int keyboardHidden, + int navigation, int screenWidth, int screenHeight, int smallestScreenWidthDp, + int screenWidthDp, int screenHeightDp, int screenLayout, int uiMode, int colorMode, + int grammaticalGender, int majorVersion, boolean forceRefresh) { synchronized (this) { ensureValidLocked(); nativeSetConfiguration(mObject, mcc, mnc, defaultLocale, locales, orientation, touchscreen, density, keyboard, keyboardHidden, navigation, screenWidth, screenHeight, smallestScreenWidthDp, screenWidthDp, screenHeightDp, - screenLayout, uiMode, colorMode, grammaticalGender, majorVersion); + screenLayout, uiMode, colorMode, grammaticalGender, majorVersion, + forceRefresh); } } @@ -1593,13 +1617,13 @@ public final class AssetManager implements AutoCloseable { private static native long nativeCreate(); private static native void nativeDestroy(long ptr); private static native void nativeSetApkAssets(long ptr, @NonNull ApkAssets[] apkAssets, - boolean invalidateCaches); + boolean invalidateCaches, boolean preset); private static native void nativeSetConfiguration(long ptr, int mcc, int mnc, @Nullable String defaultLocale, @NonNull String[] locales, int orientation, int touchscreen, int density, int keyboard, int keyboardHidden, int navigation, int screenWidth, int screenHeight, int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp, int screenLayout, int uiMode, int colorMode, int grammaticalGender, - int majorVersion); + int majorVersion, boolean forceRefresh); private static native @NonNull SparseArray<String> nativeGetAssignedPackageIdentifiers( long ptr, boolean includeOverlays, boolean includeLoaders); diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java index 5e442b819774..079c2c1ab7c9 100644 --- a/core/java/android/content/res/ResourcesImpl.java +++ b/core/java/android/content/res/ResourcesImpl.java @@ -200,7 +200,7 @@ public class ResourcesImpl { mMetrics.setToDefaults(); mDisplayAdjustments = displayAdjustments; mConfiguration.setToDefaults(); - updateConfiguration(config, metrics, displayAdjustments.getCompatibilityInfo()); + updateConfigurationImpl(config, metrics, displayAdjustments.getCompatibilityInfo(), true); } public DisplayAdjustments getDisplayAdjustments() { @@ -402,7 +402,12 @@ public class ResourcesImpl { } public void updateConfiguration(Configuration config, DisplayMetrics metrics, - CompatibilityInfo compat) { + CompatibilityInfo compat) { + updateConfigurationImpl(config, metrics, compat, false); + } + + private void updateConfigurationImpl(Configuration config, DisplayMetrics metrics, + CompatibilityInfo compat, boolean forceAssetsRefresh) { Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesImpl#updateConfiguration"); try { synchronized (mAccessLock) { @@ -528,7 +533,7 @@ public class ResourcesImpl { keyboardHidden = mConfiguration.keyboardHidden; } - mAssets.setConfiguration(mConfiguration.mcc, mConfiguration.mnc, + mAssets.setConfigurationInternal(mConfiguration.mcc, mConfiguration.mnc, defaultLocale, selectedLocales, mConfiguration.orientation, @@ -539,7 +544,7 @@ public class ResourcesImpl { mConfiguration.screenWidthDp, mConfiguration.screenHeightDp, mConfiguration.screenLayout, mConfiguration.uiMode, mConfiguration.colorMode, mConfiguration.getGrammaticalGender(), - Build.VERSION.RESOURCES_SDK_INT); + Build.VERSION.RESOURCES_SDK_INT, forceAssetsRefresh); if (DEBUG_CONFIG) { Slog.i(TAG, "**** Updating config of " + this + ": final config is " diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index 3ee15ab734b9..3d0ab4ef0981 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -314,7 +314,8 @@ static void NativeDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) { } static void NativeSetApkAssets(JNIEnv* env, jclass /*clazz*/, jlong ptr, - jobjectArray apk_assets_array, jboolean invalidate_caches) { + jobjectArray apk_assets_array, jboolean invalidate_caches, + jboolean preset) { ATRACE_NAME("AssetManager::SetApkAssets"); const jsize apk_assets_len = env->GetArrayLength(apk_assets_array); @@ -343,7 +344,11 @@ static void NativeSetApkAssets(JNIEnv* env, jclass /*clazz*/, jlong ptr, } auto assetmanager = LockAndStartAssetManager(ptr); - assetmanager->SetApkAssets(apk_assets, invalidate_caches); + if (preset) { + assetmanager->PresetApkAssets(apk_assets); + } else { + assetmanager->SetApkAssets(apk_assets, invalidate_caches); + } } static void NativeSetConfiguration(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint mcc, jint mnc, @@ -353,7 +358,7 @@ static void NativeSetConfiguration(JNIEnv* env, jclass /*clazz*/, jlong ptr, jin jint screen_height, jint smallest_screen_width_dp, jint screen_width_dp, jint screen_height_dp, jint screen_layout, jint ui_mode, jint color_mode, jint grammatical_gender, - jint major_version) { + jint major_version, jboolean force_refresh) { ATRACE_NAME("AssetManager::SetConfiguration"); const jsize locale_count = (locales == NULL) ? 0 : env->GetArrayLength(locales); @@ -413,7 +418,7 @@ static void NativeSetConfiguration(JNIEnv* env, jclass /*clazz*/, jlong ptr, jin } auto assetmanager = LockAndStartAssetManager(ptr); - assetmanager->SetConfigurations(configs); + assetmanager->SetConfigurations(std::move(configs), force_refresh != JNI_FALSE); assetmanager->SetDefaultLocale(default_locale_int); } @@ -1522,8 +1527,8 @@ static const JNINativeMethod gAssetManagerMethods[] = { // AssetManager setup methods. {"nativeCreate", "()J", (void*)NativeCreate}, {"nativeDestroy", "(J)V", (void*)NativeDestroy}, - {"nativeSetApkAssets", "(J[Landroid/content/res/ApkAssets;Z)V", (void*)NativeSetApkAssets}, - {"nativeSetConfiguration", "(JIILjava/lang/String;[Ljava/lang/String;IIIIIIIIIIIIIIII)V", + {"nativeSetApkAssets", "(J[Landroid/content/res/ApkAssets;ZZ)V", (void*)NativeSetApkAssets}, + {"nativeSetConfiguration", "(JIILjava/lang/String;[Ljava/lang/String;IIIIIIIIIIIIIIIIZ)V", (void*)NativeSetConfiguration}, {"nativeGetAssignedPackageIdentifiers", "(JZZ)Landroid/util/SparseArray;", (void*)NativeGetAssignedPackageIdentifiers}, diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp index 8748dab581bb..46f636e2ae7f 100644 --- a/libs/androidfw/AssetManager2.cpp +++ b/libs/androidfw/AssetManager2.cpp @@ -117,6 +117,10 @@ bool AssetManager2::SetApkAssets(ApkAssetsList apk_assets, bool invalidate_cache return true; } +void AssetManager2::PresetApkAssets(ApkAssetsList apk_assets) { + BuildDynamicRefTable(apk_assets); +} + bool AssetManager2::SetApkAssets(std::initializer_list<ApkAssetsPtr> apk_assets, bool invalidate_caches) { return SetApkAssets(ApkAssetsList(apk_assets.begin(), apk_assets.size()), invalidate_caches); @@ -432,13 +436,18 @@ bool AssetManager2::ContainsAllocatedTable() const { return false; } -void AssetManager2::SetConfigurations(std::vector<ResTable_config> configurations) { +void AssetManager2::SetConfigurations(std::vector<ResTable_config> configurations, + bool force_refresh) { int diff = 0; - if (configurations_.size() != configurations.size()) { + if (force_refresh) { diff = -1; } else { - for (int i = 0; i < configurations_.size(); i++) { - diff |= configurations_[i].diff(configurations[i]); + if (configurations_.size() != configurations.size()) { + diff = -1; + } else { + for (int i = 0; i < configurations_.size(); i++) { + diff |= configurations_[i].diff(configurations[i]); + } } } configurations_ = std::move(configurations); @@ -775,8 +784,7 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( bool has_locale = false; if (result->config.locale == 0) { if (default_locale_ != 0) { - ResTable_config conf; - conf.locale = default_locale_; + ResTable_config conf = {.locale = default_locale_}; // Since we know conf has a locale and only a locale, match will tell us if that locale // matches has_locale = conf.match(config); diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h index d9ff35b49e0a..17a8ba6c03bd 100644 --- a/libs/androidfw/include/androidfw/AssetManager2.h +++ b/libs/androidfw/include/androidfw/AssetManager2.h @@ -124,6 +124,9 @@ class AssetManager2 { // new resource IDs. bool SetApkAssets(ApkAssetsList apk_assets, bool invalidate_caches = true); bool SetApkAssets(std::initializer_list<ApkAssetsPtr> apk_assets, bool invalidate_caches = true); + // This one is an optimization - it skips all calculations for applying the currently set + // configuration, expecting a configuration update later with a forced refresh. + void PresetApkAssets(ApkAssetsList apk_assets); const ApkAssetsPtr& GetApkAssets(ApkAssetsCookie cookie) const; int GetApkAssetsCount() const { @@ -156,7 +159,7 @@ class AssetManager2 { // Sets/resets the configuration for this AssetManager. This will cause all // caches that are related to the configuration change to be invalidated. - void SetConfigurations(std::vector<ResTable_config> configurations); + void SetConfigurations(std::vector<ResTable_config> configurations, bool force_refresh = false); inline const std::vector<ResTable_config>& GetConfigurations() const { return configurations_; |