From fa06394138cf18fc37d86ddf7c760604342a4c39 Mon Sep 17 00:00:00 2001 From: Yurii Zubrytskyi Date: Mon, 26 Aug 2024 22:32:34 +0000 Subject: Revert^2 "[res] Fix the registered shared lib asset caching" Bug: 357789416 0f3702e5a38b7acff6c1a2fa0293c36ebccc693f Merged-In: I089ec2fecc875d758a0a5639e7db77081927a25f Change-Id: Ib26bbd105ebcda008f696b1b8b28b4544c704754 --- core/java/android/app/ResourcesManager.java | 262 +++++++++++++-------- core/java/android/content/res/AssetManager.java | 124 +++++++--- core/java/android/content/res/ResourcesImpl.java | 24 +- .../android/content/res/ResourcesManagerTest.java | 16 +- 4 files changed, 269 insertions(+), 157 deletions(-) diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index 370aff8e7a0f..b51462e6b363 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -30,6 +30,7 @@ import android.content.res.AssetManager; import android.content.res.CompatResources; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; +import android.content.res.Flags; import android.content.res.Resources; import android.content.res.ResourcesImpl; import android.content.res.ResourcesKey; @@ -138,16 +139,22 @@ public class ResourcesManager { private final ArrayMap mSharedLibAssetsMap = new ArrayMap<>(); + @VisibleForTesting + public ArrayMap getRegisteredResourcePaths() { + return mSharedLibAssetsMap; + } + /** * The internal function to register the resources paths of a package (e.g. a shared library). * This will collect the package resources' paths from its ApplicationInfo and add them to all * existing and future contexts while the application is running. */ public void registerResourcePaths(@NonNull String uniqueId, @NonNull ApplicationInfo appInfo) { - SharedLibraryAssets sharedLibAssets = new SharedLibraryAssets(appInfo.sourceDir, - appInfo.splitSourceDirs, appInfo.sharedLibraryFiles, - appInfo.resourceDirs, appInfo.overlayPaths); + if (!Flags.registerResourcePaths()) { + return; + } + final var sharedLibAssets = new SharedLibraryAssets(appInfo); synchronized (mLock) { if (mSharedLibAssetsMap.containsKey(uniqueId)) { Slog.v(TAG, "Package resources' paths for uniqueId: " + uniqueId @@ -155,18 +162,37 @@ public class ResourcesManager { return; } mSharedLibAssetsMap.put(uniqueId, sharedLibAssets); - appendLibAssetsLocked(sharedLibAssets.getAllAssetPaths()); - Slog.v(TAG, "The following resources' paths have been added: " - + Arrays.toString(sharedLibAssets.getAllAssetPaths())); + appendLibAssetsLocked(sharedLibAssets); + Slog.v(TAG, "The following library key has been added: " + + sharedLibAssets.getResourcesKey()); } } - private static class ApkKey { + /** + * Apply the registered library paths to the passed impl object + * @return the hash code for the current version of the registered paths + */ + public int updateResourceImplWithRegisteredLibs(@NonNull ResourcesImpl impl) { + if (!Flags.registerResourcePaths()) { + return 0; + } + + final var collector = new PathCollector(null); + final int size = mSharedLibAssetsMap.size(); + for (int i = 0; i < size; i++) { + final var libraryKey = mSharedLibAssetsMap.valueAt(i).getResourcesKey(); + collector.appendKey(libraryKey); + } + impl.getAssets().addPresetApkKeys(extractApkKeys(collector.collectedKey())); + return size; + } + + public static class ApkKey { public final String path; public final boolean sharedLib; public final boolean overlay; - ApkKey(String path, boolean sharedLib, boolean overlay) { + public ApkKey(String path, boolean sharedLib, boolean overlay) { this.path = path; this.sharedLib = sharedLib; this.overlay = overlay; @@ -190,6 +216,12 @@ public class ResourcesManager { return this.path.equals(other.path) && this.sharedLib == other.sharedLib && this.overlay == other.overlay; } + + @Override + public String toString() { + return "ApkKey[" + (sharedLib ? "lib" : "app") + (overlay ? ", overlay" : "") + ": " + + path + "]"; + } } /** @@ -505,7 +537,10 @@ public class ResourcesManager { return "/data/resource-cache/" + path.substring(1).replace('/', '@') + "@idmap"; } - private @NonNull ApkAssets loadApkAssets(@NonNull final ApkKey key) throws IOException { + /** + * Loads the ApkAssets object for the passed key, or picks the one from the cache if available. + */ + public @NonNull ApkAssets loadApkAssets(@NonNull final ApkKey key) throws IOException { ApkAssets apkAssets; // Optimistically check if this ApkAssets exists somewhere else. @@ -747,8 +782,8 @@ public class ResourcesManager { private @Nullable ResourcesImpl findOrCreateResourcesImplForKeyLocked( @NonNull ResourcesKey key, @Nullable ApkAssetsSupplier apkSupplier) { ResourcesImpl impl = findResourcesImplForKeyLocked(key); - // ResourcesImpl also need to be recreated if its shared library count is not up-to-date. - if (impl == null || impl.getSharedLibCount() != mSharedLibAssetsMap.size()) { + // ResourcesImpl also need to be recreated if its shared library hash is not up-to-date. + if (impl == null || impl.getAppliedSharedLibsHash() != mSharedLibAssetsMap.size()) { impl = createResourcesImpl(key, apkSupplier); if (impl != null) { mResourceImpls.put(key, new WeakReference<>(impl)); @@ -1533,56 +1568,109 @@ public class ResourcesManager { } } - private void appendLibAssetsLocked(String[] libAssets) { - synchronized (mLock) { - // Record which ResourcesImpl need updating - // (and what ResourcesKey they should update to). - final ArrayMap updatedResourceKeys = new ArrayMap<>(); + /** + * A utility class to collect resources paths into a ResourcesKey object: + * - Separates the libraries and the overlays into different sets as those are loaded in + * different ways. + * - Allows to start with an existing original key object, and copies all non-path related + * properties into the final one. + * - Preserves the path order while dropping all duplicates in an efficient manner. + */ + private static class PathCollector { + public final ResourcesKey originalKey; + public final ArrayList orderedLibs = new ArrayList<>(); + public final ArraySet libsSet = new ArraySet<>(); + public final ArrayList orderedOverlays = new ArrayList<>(); + public final ArraySet overlaysSet = new ArraySet<>(); + + static void appendNewPath(@NonNull String path, + @NonNull ArraySet uniquePaths, @NonNull ArrayList orderedPaths) { + if (uniquePaths.add(path)) { + orderedPaths.add(path); + } + } - final int implCount = mResourceImpls.size(); - for (int i = 0; i < implCount; i++) { - final ResourcesKey key = mResourceImpls.keyAt(i); - final WeakReference weakImplRef = mResourceImpls.valueAt(i); - final ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null; - if (impl == null) { - Slog.w(TAG, "Found a ResourcesImpl which is null, skip it and continue to " - + "append shared library assets for next ResourcesImpl."); - continue; - } + static void appendAllNewPaths(@Nullable String[] paths, + @NonNull ArraySet uniquePaths, @NonNull ArrayList orderedPaths) { + if (paths == null) return; + for (int i = 0, size = paths.length; i < size; i++) { + appendNewPath(paths[i], uniquePaths, orderedPaths); + } + } - var newDirs = new ArrayList(); - var dirsSet = new ArraySet(); - if (key.mLibDirs != null) { - final int dirsLength = key.mLibDirs.length; - for (int k = 0; k < dirsLength; k++) { - newDirs.add(key.mLibDirs[k]); - dirsSet.add(key.mLibDirs[k]); - } - } - final int assetsLength = libAssets.length; - for (int j = 0; j < assetsLength; j++) { - if (dirsSet.add(libAssets[j])) { - newDirs.add(libAssets[j]); - } - } - String[] newLibAssets = newDirs.toArray(new String[0]); - if (!Arrays.equals(newLibAssets, key.mLibDirs)) { - updatedResourceKeys.put(impl, new ResourcesKey( - key.mResDir, - key.mSplitResDirs, - key.mOverlayPaths, - newLibAssets, - key.mDisplayId, - key.mOverrideConfiguration, - key.mCompatInfo, - key.mLoaders)); - } + PathCollector(@Nullable ResourcesKey original) { + originalKey = original; + if (originalKey != null) { + appendKey(originalKey); } + } - redirectAllResourcesToNewImplLocked(updatedResourceKeys); + public void appendKey(@NonNull ResourcesKey key) { + appendAllNewPaths(key.mLibDirs, libsSet, orderedLibs); + appendAllNewPaths(key.mOverlayPaths, overlaysSet, orderedOverlays); + } + + boolean isSameAsOriginal() { + if (originalKey == null) { + return orderedLibs.isEmpty() && orderedOverlays.isEmpty(); + } + return ((originalKey.mLibDirs == null && orderedLibs.isEmpty()) + || (originalKey.mLibDirs != null + && originalKey.mLibDirs.length == orderedLibs.size())) + && ((originalKey.mOverlayPaths == null && orderedOverlays.isEmpty()) + || (originalKey.mOverlayPaths != null + && originalKey.mOverlayPaths.length == orderedOverlays.size())); + } + + @NonNull ResourcesKey collectedKey() { + return new ResourcesKey( + originalKey == null ? null : originalKey.mResDir, + originalKey == null ? null : originalKey.mSplitResDirs, + orderedOverlays.toArray(new String[0]), orderedLibs.toArray(new String[0]), + originalKey == null ? 0 : originalKey.mDisplayId, + originalKey == null ? null : originalKey.mOverrideConfiguration, + originalKey == null ? null : originalKey.mCompatInfo, + originalKey == null ? null : originalKey.mLoaders); } } + /** + * Takes the original resources key and the one containing a set of library paths and overlays + * to append, and combines them together. In case when the original key already contains all + * those paths this function returns null, otherwise it makes a new ResourcesKey object. + */ + private @Nullable ResourcesKey createNewResourceKeyIfNeeded( + @NonNull ResourcesKey original, @NonNull ResourcesKey library) { + final var collector = new PathCollector(original); + collector.appendKey(library); + return collector.isSameAsOriginal() ? null : collector.collectedKey(); + } + + /** + * Append the newly registered shared library asset paths to all existing resources objects. + */ + private void appendLibAssetsLocked(@NonNull SharedLibraryAssets libAssets) { + // Record the ResourcesImpl's that need updating, and what ResourcesKey they should + // update to. + final ArrayMap updatedResourceKeys = new ArrayMap<>(); + final int implCount = mResourceImpls.size(); + for (int i = 0; i < implCount; i++) { + final ResourcesKey key = mResourceImpls.keyAt(i); + final WeakReference weakImplRef = mResourceImpls.valueAt(i); + final ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null; + if (impl == null) { + Slog.w(TAG, "Found a null ResourcesImpl, skipped."); + continue; + } + + final var newKey = createNewResourceKeyIfNeeded(key, libAssets.getResourcesKey()); + if (newKey != null) { + updatedResourceKeys.put(impl, newKey); + } + } + redirectAllResourcesToNewImplLocked(updatedResourceKeys); + } + private void applyNewResourceDirsLocked(@Nullable final String[] oldSourceDirs, @NonNull final ApplicationInfo appInfo) { try { @@ -1718,8 +1806,9 @@ public class ResourcesManager { } } - // Another redirect function which will loop through all Resources and reload ResourcesImpl - // if it needs a shared library asset paths update. + // Another redirect function which will loop through all Resources in the process, even the ones + // the app created outside of the regular Android Runtime, and reload their ResourcesImpl if it + // needs a shared library asset paths update. private void redirectAllResourcesToNewImplLocked( @NonNull final ArrayMap updatedResourceKeys) { cleanupReferences(mAllResourceReferences, mAllResourceReferencesQueue); @@ -1830,52 +1919,35 @@ public class ResourcesManager { } } - public static class SharedLibraryAssets{ - private final String[] mAssetPaths; - - SharedLibraryAssets(String sourceDir, String[] splitSourceDirs, String[] sharedLibraryFiles, - String[] resourceDirs, String[] overlayPaths) { - mAssetPaths = collectAssetPaths(sourceDir, splitSourceDirs, sharedLibraryFiles, - resourceDirs, overlayPaths); - } - - private @NonNull String[] collectAssetPaths(String sourceDir, String[] splitSourceDirs, - String[] sharedLibraryFiles, String[] resourceDirs, String[] overlayPaths) { - final String[][] inputLists = { - splitSourceDirs, sharedLibraryFiles, resourceDirs, overlayPaths - }; - - final ArraySet assetPathSet = new ArraySet<>(); - final List assetPathList = new ArrayList<>(); - if (sourceDir != null) { - assetPathSet.add(sourceDir); - assetPathList.add(sourceDir); - } - - for (int i = 0; i < inputLists.length; i++) { - if (inputLists[i] != null) { - for (int j = 0; j < inputLists[i].length; j++) { - if (assetPathSet.add(inputLists[i][j])) { - assetPathList.add(inputLists[i][j]); - } - } - } - } - return assetPathList.toArray(new String[0]); + @VisibleForTesting + public static class SharedLibraryAssets { + private final ResourcesKey mResourcesKey; + + private SharedLibraryAssets(ApplicationInfo appInfo) { + // We're loading all library's files as shared libs, regardless where they are in + // its own ApplicationInfo. + final var collector = new PathCollector(null); + PathCollector.appendNewPath(appInfo.sourceDir, collector.libsSet, + collector.orderedLibs); + PathCollector.appendAllNewPaths(appInfo.splitSourceDirs, collector.libsSet, + collector.orderedLibs); + PathCollector.appendAllNewPaths(appInfo.sharedLibraryFiles, collector.libsSet, + collector.orderedLibs); + PathCollector.appendAllNewPaths(appInfo.resourceDirs, collector.overlaysSet, + collector.orderedOverlays); + PathCollector.appendAllNewPaths(appInfo.overlayPaths, collector.overlaysSet, + collector.orderedOverlays); + mResourcesKey = collector.collectedKey(); } /** - * @return all the asset paths of this collected in this class. + * @return the resources key for this library assets. */ - public @NonNull String[] getAllAssetPaths() { - return mAssetPaths; + public @NonNull ResourcesKey getResourcesKey() { + return mResourcesKey; } } - public @NonNull ArrayMap getSharedLibAssetsMap() { - return new ArrayMap<>(mSharedLibAssetsMap); - } - /** * Add all resources references to the list which is designed to help to append shared library * asset paths. This is invoked in Resources constructor to include all Resources instances. diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 273e40a21bb2..fd9361d4f2d8 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -17,6 +17,7 @@ package android.content.res; import static android.content.res.Resources.ID_NULL; +import static android.app.ResourcesManager.ApkKey; import android.annotation.AnyRes; import android.annotation.ArrayRes; @@ -26,12 +27,14 @@ import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.StyleRes; import android.annotation.TestApi; +import android.app.ResourcesManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo; import android.content.res.Configuration.NativeConfig; import android.content.res.loader.ResourcesLoader; import android.os.Build; import android.os.ParcelFileDescriptor; +import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.SparseArray; @@ -264,7 +267,7 @@ public final class AssetManager implements AutoCloseable { } sSystemApkAssetsSet = new ArraySet<>(apkAssets); - sSystemApkAssets = apkAssets.toArray(new ApkAssets[apkAssets.size()]); + sSystemApkAssets = apkAssets.toArray(new ApkAssets[0]); if (sSystem == null) { sSystem = new AssetManager(true /*sentinel*/); } @@ -448,7 +451,7 @@ public final class AssetManager implements AutoCloseable { @Deprecated @UnsupportedAppUsage public int addAssetPath(String path) { - return addAssetPathInternal(path, false /*overlay*/, false /*appAsLib*/); + return addAssetPathInternal(List.of(new ApkKey(path, false, false)), false); } /** @@ -458,7 +461,7 @@ public final class AssetManager implements AutoCloseable { @Deprecated @UnsupportedAppUsage public int addAssetPathAsSharedLibrary(String path) { - return addAssetPathInternal(path, false /*overlay*/, true /*appAsLib*/); + return addAssetPathInternal(List.of(new ApkKey(path, true, false)), false); } /** @@ -468,55 +471,110 @@ public final class AssetManager implements AutoCloseable { @Deprecated @UnsupportedAppUsage public int addOverlayPath(String path) { - return addAssetPathInternal(path, true /*overlay*/, false /*appAsLib*/); + return addAssetPathInternal(List.of(new ApkKey(path, false, true)), false); } /** * @hide */ - public void addSharedLibraryPaths(@NonNull String[] paths) { - final int length = paths.length; - for (int i = 0; i < length; i++) { - addAssetPathInternal(paths[i], false, true); - } + public void addPresetApkKeys(@NonNull List keys) { + addAssetPathInternal(keys, true); } - private int addAssetPathInternal(String path, boolean overlay, boolean appAsLib) { - Objects.requireNonNull(path, "path"); + private int addAssetPathInternal(List apkKeys, boolean presetAssets) { + Objects.requireNonNull(apkKeys, "apkKeys"); + if (apkKeys.isEmpty()) { + return 0; + } + synchronized (this) { ensureOpenLocked(); final int count = mApkAssets.length; - // See if we already have it loaded. - for (int i = 0; i < count; i++) { - if (mApkAssets[i].getAssetPath().equals(path)) { - return i + 1; - } + // See if we already have some of the apkKeys loaded. + final int originalAssetsCount = mApkAssets.length; + + // Getting an assets' path is a relatively expensive operation, cache them. + final ArrayMap assetPaths = new ArrayMap<>(originalAssetsCount); + for (int i = 0; i < originalAssetsCount; i++) { + assetPaths.put(mApkAssets[i].getAssetPath(), i); } - final ApkAssets assets; - try { - if (overlay) { - // TODO(b/70343104): This hardcoded path will be removed once - // addAssetPathInternal is deleted. - final String idmapPath = "/data/resource-cache/" - + path.substring(1).replace('/', '@') - + "@idmap"; - assets = ApkAssets.loadOverlayFromPath(idmapPath, 0 /* flags */); + final var newKeys = new ArrayList(apkKeys.size()); + int lastFoundIndex = -1; + for (int i = 0, pathsSize = apkKeys.size(); i < pathsSize; i++) { + final var key = apkKeys.get(i); + final var index = assetPaths.get(key.path); + if (index == null) { + newKeys.add(key); } else { - assets = ApkAssets.loadFromPath(path, - appAsLib ? ApkAssets.PROPERTY_DYNAMIC : 0); + lastFoundIndex = index; } - } catch (IOException e) { - return 0; + } + if (newKeys.isEmpty()) { + return lastFoundIndex + 1; } - mApkAssets = Arrays.copyOf(mApkAssets, count + 1); - mApkAssets[count] = assets; - nativeSetApkAssets(mObject, mApkAssets, true, false); + final var newAssets = loadAssets(newKeys); + if (newAssets.isEmpty()) { + return 0; + } + mApkAssets = makeNewAssetsArrayLocked(newAssets); + nativeSetApkAssets(mObject, mApkAssets, true, presetAssets); invalidateCachesLocked(-1); - return count + 1; + return originalAssetsCount + 1; + } + } + + /** + * Insert the new assets preserving the correct order: all non-loader assets go before all + * of the loader assets. + */ + @GuardedBy("this") + private @NonNull ApkAssets[] makeNewAssetsArrayLocked( + @NonNull ArrayList newNonLoaderAssets) { + final int originalAssetsCount = mApkAssets.length; + int firstLoaderIndex = originalAssetsCount; + for (int i = 0; i < originalAssetsCount; i++) { + if (mApkAssets[i].isForLoader()) { + firstLoaderIndex = i; + break; + } + } + final int newAssetsSize = newNonLoaderAssets.size(); + final var newAssetsArray = new ApkAssets[originalAssetsCount + newAssetsSize]; + if (firstLoaderIndex > 0) { + // This should always be true, but who knows... + System.arraycopy(mApkAssets, 0, newAssetsArray, 0, firstLoaderIndex); + } + for (int i = 0; i < newAssetsSize; i++) { + newAssetsArray[firstLoaderIndex + i] = newNonLoaderAssets.get(i); + } + if (originalAssetsCount > firstLoaderIndex) { + System.arraycopy( + mApkAssets, firstLoaderIndex, + newAssetsArray, firstLoaderIndex + newAssetsSize, + originalAssetsCount - firstLoaderIndex); + } + return newAssetsArray; + } + + private static @NonNull ArrayList loadAssets(@NonNull ArrayList keys) { + final int pathsSize = keys.size(); + final var loadedAssets = new ArrayList(pathsSize); + final var resourcesManager = ResourcesManager.getInstance(); + for (int i = 0; i < pathsSize; i++) { + final var key = keys.get(i); + try { + // ResourcesManager has a cache of loaded assets, ensuring we don't open the same + // file repeatedly, which is useful for the common overlays and registered + // shared libraries. + loadedAssets.add(resourcesManager.loadApkAssets(key)); + } catch (IOException e) { + Log.w(TAG, "Failed to load asset, key = " + key, e); + } } + return loadedAssets; } /** @hide */ diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java index 31cacb705d0e..d874270b4653 100644 --- a/core/java/android/content/res/ResourcesImpl.java +++ b/core/java/android/content/res/ResourcesImpl.java @@ -29,7 +29,6 @@ import android.annotation.StyleRes; import android.annotation.StyleableRes; import android.app.LocaleConfig; import android.app.ResourcesManager; -import android.app.ResourcesManager.SharedLibraryAssets; import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.Config; @@ -48,7 +47,6 @@ import android.os.Build; import android.os.LocaleList; import android.os.ParcelFileDescriptor; import android.os.Trace; -import android.util.ArrayMap; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; @@ -147,10 +145,9 @@ public class ResourcesImpl { // Cyclical cache used for recently-accessed XML files. private int mLastCachedXmlBlockIndex = -1; - // The number of shared libraries registered within this ResourcesImpl, which is designed to - // help to determine whether this ResourcesImpl is outdated on shared library information and - // needs to be replaced. - private int mSharedLibCount; + // The hash that allows to detect when the shared libraries applied to this object have changed, + // and it is outdated and needs to be replaced. + private final int mAppliedSharedLibsHash; private final int[] mCachedXmlBlockCookies = new int[XML_BLOCK_CACHE_SIZE]; private final String[] mCachedXmlBlockFiles = new String[XML_BLOCK_CACHE_SIZE]; private final XmlBlock[] mCachedXmlBlocks = new XmlBlock[XML_BLOCK_CACHE_SIZE]; @@ -204,15 +201,8 @@ public class ResourcesImpl { public ResourcesImpl(@NonNull AssetManager assets, @Nullable DisplayMetrics metrics, @Nullable Configuration config, @NonNull DisplayAdjustments displayAdjustments) { mAssets = assets; - if (Flags.registerResourcePaths()) { - ArrayMap sharedLibMap = - ResourcesManager.getInstance().getSharedLibAssetsMap(); - final int size = sharedLibMap.size(); - for (int i = 0; i < size; i++) { - assets.addSharedLibraryPaths(sharedLibMap.valueAt(i).getAllAssetPaths()); - } - mSharedLibCount = sharedLibMap.size(); - } + mAppliedSharedLibsHash = + ResourcesManager.getInstance().updateResourceImplWithRegisteredLibs(this); mMetrics.setToDefaults(); mDisplayAdjustments = displayAdjustments; mConfiguration.setToDefaults(); @@ -1615,7 +1605,7 @@ public class ResourcesImpl { } } - public int getSharedLibCount() { - return mSharedLibCount; + public int getAppliedSharedLibsHash() { + return mAppliedSharedLibsHash; } } diff --git a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java index 6b3cf7bb628f..ee1b6589f7e6 100644 --- a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java +++ b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java @@ -44,7 +44,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -382,8 +381,7 @@ public class ResourcesManagerTest extends TestCase { assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets)); // Package resources' paths should be cached in ResourcesManager. - assertEquals(Arrays.toString(resourcePaths), Arrays.toString(ResourcesManager.getInstance() - .getSharedLibAssetsMap().get(TEST_LIB).getAllAssetPaths())); + assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB)); // Revert the ResourcesManager instance back. ResourcesManager.setInstance(oriResourcesManager); @@ -414,9 +412,7 @@ public class ResourcesManagerTest extends TestCase { assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets)); // Package resources' paths should be cached in ResourcesManager. - assertEquals(Arrays.toString(resourcePaths), Arrays.toString(ResourcesManager.getInstance() - .getSharedLibAssetsMap().get(TEST_LIB).getAllAssetPaths())); - + assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB)); // Revert the ResourcesManager instance back. ResourcesManager.setInstance(oriResourcesManager); } @@ -452,9 +448,7 @@ public class ResourcesManagerTest extends TestCase { assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets)); // Package resources' paths should be cached in ResourcesManager. - assertEquals(Arrays.toString(resourcePaths), Arrays.toString(ResourcesManager.getInstance() - .getSharedLibAssetsMap().get(TEST_LIB).getAllAssetPaths())); - + assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB)); // Revert the ResourcesManager instance back. ResourcesManager.setInstance(oriResourcesManager); } @@ -493,9 +487,7 @@ public class ResourcesManagerTest extends TestCase { assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets)); // Package resources' paths should be cached in ResourcesManager. - assertEquals(Arrays.toString(resourcePaths), Arrays.toString(ResourcesManager.getInstance() - .getSharedLibAssetsMap().get(TEST_LIB).getAllAssetPaths())); - + assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB)); // Revert the ResourcesManager instance back. ResourcesManager.setInstance(oriResourcesManager); } -- cgit v1.2.3-59-g8ed1b