summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2025-03-24 15:25:42 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2025-03-24 15:25:42 -0700
commitd4a2d3f993336d8575757badc44995380515642f (patch)
tree45eb8f4bf73585ac31c1b84c59c1985c88eca635
parent534d89b44cdc314a56670e35fa21e690f923594d (diff)
parent0a856ff1a9bb281f5ee62b2fe1f42966f233b388 (diff)
Merge "[res] Remove global overlays from registered lib paths" into main
-rw-r--r--core/java/android/app/ResourcesManager.java32
-rw-r--r--core/tests/coretests/src/android/content/res/ResourcesManagerTest.java109
2 files changed, 73 insertions, 68 deletions
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index d66429a2192d..23a7d94b9308 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -160,7 +160,9 @@ public class ResourcesManager {
return;
}
- final var sharedLibAssets = new SharedLibraryAssets(appInfo);
+ final var application = ActivityThread.currentActivityThread().getApplication();
+ final var currentAppInfo = application != null ? application.getApplicationInfo() : null;
+ final var sharedLibAssets = new SharedLibraryAssets(appInfo, currentAppInfo);
synchronized (mLock) {
if (mSharedLibAssetsMap.containsKey(uniqueId)) {
Slog.v(TAG, "Package resources' paths for uniqueId: " + uniqueId
@@ -191,7 +193,7 @@ public class ResourcesManager {
synchronized (mLock) {
size = mSharedLibAssetsMap.size();
- if (assets == AssetManager.getSystem()) {
+ if (size == 0 || assets == AssetManager.getSystem()) {
return new Pair<>(assets, size);
}
collector = new PathCollector(resourcesKeyFromAssets(assets));
@@ -1998,10 +2000,30 @@ public class ResourcesManager {
public static class SharedLibraryAssets {
private final ResourcesKey mResourcesKey;
- private SharedLibraryAssets(ApplicationInfo appInfo) {
+ private SharedLibraryAssets(@NonNull ApplicationInfo appInfo,
+ @Nullable ApplicationInfo baseAppInfo) {
// We're loading all library's files as shared libs, regardless where they are in
// its own ApplicationInfo.
final var collector = new PathCollector(null);
+ // Pre-populate the collector's sets with the base app paths so they all get filtered
+ // out if they exist in the info that's being registered as well.
+ // Note: if someone is registering their own appInfo, we can't filter out anything
+ // here and this means any asset path changes are going to be ignored.
+ if (baseAppInfo != null && !baseAppInfo.sourceDir.equals(appInfo.sourceDir)) {
+ collector.libsSet.add(baseAppInfo.sourceDir);
+ if (baseAppInfo.splitSourceDirs != null) {
+ collector.libsSet.addAll(Arrays.asList(baseAppInfo.splitSourceDirs));
+ }
+ if (baseAppInfo.sharedLibraryFiles != null) {
+ collector.libsSet.addAll(Arrays.asList(baseAppInfo.sharedLibraryFiles));
+ }
+ if (baseAppInfo.resourceDirs != null) {
+ collector.overlaysSet.addAll(Arrays.asList(baseAppInfo.resourceDirs));
+ }
+ if (baseAppInfo.overlayPaths != null) {
+ collector.overlaysSet.addAll(Arrays.asList(baseAppInfo.overlayPaths));
+ }
+ }
PathCollector.appendNewPath(appInfo.sourceDir, collector.libsSet,
collector.orderedLibs);
PathCollector.appendAllNewPaths(appInfo.splitSourceDirs, collector.libsSet,
@@ -2013,6 +2035,10 @@ public class ResourcesManager {
PathCollector.appendAllNewPaths(appInfo.overlayPaths, collector.overlaysSet,
collector.orderedOverlays);
mResourcesKey = collector.collectedKey();
+
+ if (DEBUG) {
+ Log.i(TAG, "Created shared library assets: " + mResourcesKey);
+ }
}
/**
diff --git a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
index cfcd53e14c79..486085521aab 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
@@ -33,7 +33,6 @@ import android.platform.test.annotations.Postsubmit;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
-import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Display;
@@ -43,12 +42,12 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@@ -66,6 +65,7 @@ public class ResourcesManagerTest {
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
private ResourcesManager mResourcesManager;
+ private ResourcesManager mOldResourcesManager;
private Map<Integer, DisplayMetrics> mDisplayMetricsMap;
@Before
@@ -115,6 +115,12 @@ public class ResourcesManagerTest {
return mDisplayMetricsMap.get(displayId);
}
};
+ mOldResourcesManager = ResourcesManager.setInstance(mResourcesManager);
+ }
+
+ @After
+ public void tearDown() {
+ ResourcesManager.setInstance(mOldResourcesManager);
}
private PackageManager getPackageManager() {
@@ -363,11 +369,6 @@ public class ResourcesManagerTest {
@DisabledOnRavenwood(blockedBy = PackageManager.class)
public void testExistingResourcesAfterResourcePathsRegistration()
throws PackageManager.NameNotFoundException {
- // Inject ResourcesManager instance from this test to the ResourcesManager class so that all
- // the static method can interact with this test smoothly.
- ResourcesManager oriResourcesManager = ResourcesManager.getInstance();
- ResourcesManager.setInstance(mResourcesManager);
-
// Create a Resources before register resources' paths for a package.
Resources resources = mResourcesManager.getResources(
null, APP_ONE_RES_DIR, null, null, null, null, null, null,
@@ -380,16 +381,11 @@ public class ResourcesManagerTest {
assertNotSame(oriResImpl, resources.getImpl());
- String[] resourcePaths = appInfo.getAllApkPaths();
- resourcePaths = removeDuplicates(resourcePaths);
ApkAssets[] loadedAssets = resources.getAssets().getApkAssets();
- assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets));
+ assertTrue(containsPath(TEST_LIB, loadedAssets));
// Package resources' paths should be cached in ResourcesManager.
assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB));
-
- // Revert the ResourcesManager instance back.
- ResourcesManager.setInstance(oriResourcesManager);
}
@Test
@@ -398,11 +394,6 @@ public class ResourcesManagerTest {
@DisabledOnRavenwood(blockedBy = PackageManager.class)
public void testNewResourcesAfterResourcePathsRegistration()
throws PackageManager.NameNotFoundException {
- // Inject ResourcesManager instance from this test to the ResourcesManager class so that all
- // the static method can interact with this test smoothly.
- ResourcesManager oriResourcesManager = ResourcesManager.getInstance();
- ResourcesManager.setInstance(mResourcesManager);
-
ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_LIB, 0);
Resources.registerResourcePaths(TEST_LIB, appInfo);
@@ -412,15 +403,11 @@ public class ResourcesManagerTest {
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources);
- String[] resourcePaths = appInfo.getAllApkPaths();
- resourcePaths = removeDuplicates(resourcePaths);
ApkAssets[] loadedAssets = resources.getAssets().getApkAssets();
- assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets));
+ assertTrue(containsPath(TEST_LIB, loadedAssets));
// Package resources' paths should be cached in ResourcesManager.
assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB));
- // Revert the ResourcesManager instance back.
- ResourcesManager.setInstance(oriResourcesManager);
}
@Test
@@ -429,11 +416,6 @@ public class ResourcesManagerTest {
@DisabledOnRavenwood(blockedBy = PackageManager.class)
public void testExistingResourcesCreatedByConstructorAfterResourcePathsRegistration()
throws PackageManager.NameNotFoundException {
- // Inject ResourcesManager instance from this test to the ResourcesManager class so that all
- // the static method can interact with this test smoothly.
- ResourcesManager oriResourcesManager = ResourcesManager.getInstance();
- ResourcesManager.setInstance(mResourcesManager);
-
// Create a Resources through constructor directly before register resources' paths.
final DisplayMetrics metrics = new DisplayMetrics();
metrics.setToDefaults();
@@ -449,15 +431,11 @@ public class ResourcesManagerTest {
assertNotSame(oriResImpl, resources.getImpl());
- String[] resourcePaths = appInfo.getAllApkPaths();
- resourcePaths = removeDuplicates(resourcePaths);
ApkAssets[] loadedAssets = resources.getAssets().getApkAssets();
- assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets));
+ assertTrue(containsPath(TEST_LIB, loadedAssets));
// Package resources' paths should be cached in ResourcesManager.
assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB));
- // Revert the ResourcesManager instance back.
- ResourcesManager.setInstance(oriResourcesManager);
}
@Test
@@ -509,9 +487,6 @@ public class ResourcesManagerTest {
@DisabledOnRavenwood(blockedBy = PackageManager.class)
public void testNewResourcesWithOutdatedImplAfterResourcePathsRegistration()
throws PackageManager.NameNotFoundException {
- ResourcesManager oriResourcesManager = ResourcesManager.getInstance();
- ResourcesManager.setInstance(mResourcesManager);
-
Resources old_resources = mResourcesManager.getResources(
null, APP_ONE_RES_DIR, null, null, null, null, null, null,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
@@ -532,44 +507,48 @@ public class ResourcesManagerTest {
// which has proper asset paths appended.
assertNotSame(oldImpl, resources.getImpl());
- String[] resourcePaths = appInfo.getAllApkPaths();
- resourcePaths = removeDuplicates(resourcePaths);
ApkAssets[] loadedAssets = resources.getAssets().getApkAssets();
- assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets));
+ assertTrue(containsPath(TEST_LIB, loadedAssets));
// Package resources' paths should be cached in ResourcesManager.
assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB));
- // Revert the ResourcesManager instance back.
- ResourcesManager.setInstance(oriResourcesManager);
}
- private static boolean allResourcePathsLoaded(String[] resourcePaths, ApkAssets[] loadedAsset) {
- for (int i = 0; i < resourcePaths.length; i++) {
- if (!resourcePaths[i].endsWith(".apk")) {
- continue;
- }
- boolean found = false;
- for (int j = 0; j < loadedAsset.length; j++) {
- if (loadedAsset[j].getAssetPath().equals(resourcePaths[i])) {
- found = true;
- }
- }
- if (!found) {
- return false;
- }
- }
- return true;
+
+ @Test
+ @SmallTest
+ @RequiresFlagsEnabled(Flags.FLAG_REGISTER_RESOURCE_PATHS)
+ @DisabledOnRavenwood(blockedBy = PackageManager.class)
+ public void testRegisteringOwnApplicationInfo() {
+ Resources old_resources = mResourcesManager.getResources(
+ null, APP_ONE_RES_DIR, null, null, null, null, null, null,
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
+ assertNotNull(old_resources);
+ ResourcesImpl oldImpl = old_resources.getImpl();
+
+ ApplicationInfo appInfo =
+ InstrumentationRegistry.getInstrumentation().getContext().getApplicationInfo();
+ Resources.registerResourcePaths(TEST_LIB, appInfo);
+
+ // Create another resources with identical parameters.
+ Resources resources = mResourcesManager.getResources(
+ null, APP_ONE_RES_DIR, null, null, null, null, null, null,
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
+ assertNotNull(resources);
+ assertNotSame(oldImpl, resources.getImpl());
+
+ ApkAssets[] loadedAssets = resources.getAssets().getApkAssets();
+ assertTrue(containsPath(appInfo.sourceDir, loadedAssets));
+
+ assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB));
}
- private static String[] removeDuplicates(String[] paths) {
- var pathList = new ArrayList<String>();
- var pathSet = new ArraySet<String>();
- final int pathsLen = paths.length;
- for (int i = 0; i < pathsLen; i++) {
- if (pathSet.add(paths[i])) {
- pathList.add(paths[i]);
+ private static boolean containsPath(String substring, ApkAssets[] assets) {
+ for (final var asset : assets) {
+ if (asset.getAssetPath().contains(substring)) {
+ return true;
}
}
- return pathList.toArray(new String[0]);
+ return false;
}
}