Loading services/core/java/com/android/server/om/OverlayReferenceMapper.java +37 −24 Original line number Diff line number Diff line Loading @@ -26,10 +26,13 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.CollectionUtils; import com.android.server.SystemConfig; import com.android.server.pm.pkg.AndroidPackage; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; Loading Loading @@ -118,16 +121,20 @@ public class OverlayReferenceMapper { return actorPair.first; } @Nullable @NonNull @Override public Pair<String, String> getTargetToOverlayables(@NonNull AndroidPackage pkg) { public Map<String, Set<String>> getTargetToOverlayables(@NonNull AndroidPackage pkg) { String target = pkg.getOverlayTarget(); if (TextUtils.isEmpty(target)) { return null; return Collections.emptyMap(); } String overlayable = pkg.getOverlayTargetOverlayableName(); return Pair.create(target, overlayable); Map<String, Set<String>> targetToOverlayables = new HashMap<>(); Set<String> overlayables = new HashSet<>(); overlayables.add(overlayable); targetToOverlayables.put(target, overlayables); return targetToOverlayables; } }; } Loading Loading @@ -167,7 +174,7 @@ public class OverlayReferenceMapper { } // TODO(b/135203078): Replace with isOverlay boolean flag check; fix test mocks if (mProvider.getTargetToOverlayables(pkg) != null) { if (!mProvider.getTargetToOverlayables(pkg).isEmpty()) { addOverlay(pkg, otherPkgs, changed); } Loading Loading @@ -238,17 +245,20 @@ public class OverlayReferenceMapper { String target = targetPkg.getPackageName(); removeTarget(target, changedPackages); final Map<String, String> overlayablesToActors = targetPkg.getOverlayables(); for (final var entry : overlayablesToActors.entrySet()) { final String overlayable = entry.getKey(); final String actor = entry.getValue(); Map<String, String> overlayablesToActors = targetPkg.getOverlayables(); for (String overlayable : overlayablesToActors.keySet()) { String actor = overlayablesToActors.get(overlayable); addTargetToMap(actor, target, changedPackages); for (AndroidPackage overlayPkg : otherPkgs.values()) { var targetToOverlayables = Map<String, Set<String>> targetToOverlayables = mProvider.getTargetToOverlayables(overlayPkg); if (targetToOverlayables != null && targetToOverlayables.first.equals(target) && targetToOverlayables.second.equals(overlayable)) { Set<String> overlayables = targetToOverlayables.get(target); if (CollectionUtils.isEmpty(overlayables)) { continue; } if (overlayables.contains(overlayable)) { String overlay = overlayPkg.getPackageName(); addOverlayToMap(actor, target, overlay, changedPackages); } Loading Loading @@ -300,25 +310,28 @@ public class OverlayReferenceMapper { String overlay = overlayPkg.getPackageName(); removeOverlay(overlay, changedPackages); Pair<String, String> targetToOverlayables = Map<String, Set<String>> targetToOverlayables = mProvider.getTargetToOverlayables(overlayPkg); if (targetToOverlayables != null) { String target = targetToOverlayables.first; for (Map.Entry<String, Set<String>> entry : targetToOverlayables.entrySet()) { String target = entry.getKey(); Set<String> overlayables = entry.getValue(); AndroidPackage targetPkg = otherPkgs.get(target); if (targetPkg == null) { return; continue; } String targetPkgName = targetPkg.getPackageName(); Map<String, String> overlayableToActor = targetPkg.getOverlayables(); String overlayable = targetToOverlayables.second; for (String overlayable : overlayables) { String actor = overlayableToActor.get(overlayable); if (TextUtils.isEmpty(actor)) { return; continue; } addOverlayToMap(actor, targetPkgName, overlay, changedPackages); } } } } public void rebuildIfDeferred() { synchronized (mLock) { Loading Loading @@ -417,11 +430,11 @@ public class OverlayReferenceMapper { String getActorPkg(@NonNull String actor); /** * Mock response of overlay tags. * Mock response of multiple overlay tags. * * TODO(b/119899133): Replace with actual implementation; fix OverlayReferenceMapperTests */ @Nullable Pair<String, String> getTargetToOverlayables(@NonNull AndroidPackage pkg); @NonNull Map<String, Set<String>> getTargetToOverlayables(@NonNull AndroidPackage pkg); } } services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/AppsFilterImplTest.java +19 −11 Original line number Diff line number Diff line Loading @@ -45,7 +45,6 @@ import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Pair; import android.util.SparseArray; import androidx.annotation.NonNull; Loading Loading @@ -79,7 +78,10 @@ import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @Presubmit @RunWith(JUnit4.class) Loading Loading @@ -883,15 +885,18 @@ public class AppsFilterImplTest { return null; } @Nullable @NonNull @Override public Pair<String, String> getTargetToOverlayables( public Map<String, Set<String>> getTargetToOverlayables( @NonNull AndroidPackage pkg) { if (overlay.getPackageName().equals(pkg.getPackageName())) { return Pair.create(overlay.getOverlayTarget(), overlay.getOverlayTargetOverlayableName()); Map<String, Set<String>> map = new ArrayMap<>(); Set<String> set = new ArraySet<>(); set.add(overlay.getOverlayTargetOverlayableName()); map.put(overlay.getOverlayTarget(), set); return map; } return null; return Collections.emptyMap(); } }, mMockHandler); Loading Loading @@ -972,15 +977,18 @@ public class AppsFilterImplTest { return null; } @Nullable @NonNull @Override public Pair<String, String> getTargetToOverlayables( public Map<String, Set<String>> getTargetToOverlayables( @NonNull AndroidPackage pkg) { if (overlay.getPackageName().equals(pkg.getPackageName())) { return Pair.create(overlay.getOverlayTarget(), overlay.getOverlayTargetOverlayableName()); Map<String, Set<String>> map = new ArrayMap<>(); Set<String> set = new ArraySet<>(); set.add(overlay.getOverlayTargetOverlayableName()); map.put(overlay.getOverlayTarget(), set); return map; } return null; return Collections.emptyMap(); } }, mMockHandler); Loading services/tests/servicestests/src/com/android/server/om/OverlayReferenceMapperTests.kt +39 −8 Original line number Diff line number Diff line Loading @@ -76,10 +76,12 @@ class OverlayReferenceMapperTests { val overlay1 = mockOverlay(1) mapper = mapper( overlayToTargetToOverlayables = mapOf( overlay0.packageName to android.util.Pair(target.packageName, target.overlayables.keys.first()), overlay1.packageName to android.util.Pair(target.packageName, target.overlayables.keys.first()) overlay0.packageName to mapOf( target.packageName to target.overlayables.keys ), overlay1.packageName to mapOf( target.packageName to target.overlayables.keys ) ) ) val existing = mapper.addInOrder(overlay0, overlay1) { Loading Loading @@ -131,6 +133,33 @@ class OverlayReferenceMapperTests { assertMapping(ACTOR_PACKAGE_NAME to setOf(target)) } @Test fun overlayWithMultipleTargets() { val target0 = mockTarget(0) val target1 = mockTarget(1) val overlay = mockOverlay() mapper = mapper( overlayToTargetToOverlayables = mapOf( overlay.packageName to mapOf( target0.packageName to target0.overlayables.keys, target1.packageName to target1.overlayables.keys ) ) ) mapper.addInOrder(target0, target1, overlay) { assertThat(it).containsExactly(ACTOR_PACKAGE_NAME) } assertMapping(ACTOR_PACKAGE_NAME to setOf(target0, target1, overlay)) mapper.remove(target0) { assertThat(it).containsExactly(ACTOR_PACKAGE_NAME) } assertMapping(ACTOR_PACKAGE_NAME to setOf(target1, overlay)) mapper.remove(target1) { assertThat(it).containsExactly(ACTOR_PACKAGE_NAME) } assertEmpty() } @Test fun overlayWithoutTarget() { val overlay = mockOverlay() Loading Loading @@ -190,15 +219,17 @@ class OverlayReferenceMapperTests { namedActors: Map<String, Map<String, String>> = Uri.parse(ACTOR_NAME).run { mapOf(authority!! to mapOf(pathSegments.first() to ACTOR_PACKAGE_NAME)) }, overlayToTargetToOverlayables: Map<String, android.util.Pair<String, String>> = mapOf( mockOverlay().packageName to mockTarget().run { android.util.Pair(packageName!!, overlayables.keys.first()) }) overlayToTargetToOverlayables: Map<String, Map<String, Set<String>>> = mapOf( mockOverlay().packageName to mapOf( mockTarget().run { packageName to overlayables.keys } ) ) ) = OverlayReferenceMapper(deferRebuild, object : OverlayReferenceMapper.Provider { override fun getActorPkg(actor: String) = OverlayActorEnforcer.getPackageNameForActor(actor, namedActors).first override fun getTargetToOverlayables(pkg: AndroidPackage) = overlayToTargetToOverlayables[pkg.packageName] overlayToTargetToOverlayables[pkg.packageName] ?: emptyMap() }) private fun mockTarget(increment: Int = 0) = mockThrowOnUnmocked<AndroidPackage> { Loading Loading
services/core/java/com/android/server/om/OverlayReferenceMapper.java +37 −24 Original line number Diff line number Diff line Loading @@ -26,10 +26,13 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.CollectionUtils; import com.android.server.SystemConfig; import com.android.server.pm.pkg.AndroidPackage; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; Loading Loading @@ -118,16 +121,20 @@ public class OverlayReferenceMapper { return actorPair.first; } @Nullable @NonNull @Override public Pair<String, String> getTargetToOverlayables(@NonNull AndroidPackage pkg) { public Map<String, Set<String>> getTargetToOverlayables(@NonNull AndroidPackage pkg) { String target = pkg.getOverlayTarget(); if (TextUtils.isEmpty(target)) { return null; return Collections.emptyMap(); } String overlayable = pkg.getOverlayTargetOverlayableName(); return Pair.create(target, overlayable); Map<String, Set<String>> targetToOverlayables = new HashMap<>(); Set<String> overlayables = new HashSet<>(); overlayables.add(overlayable); targetToOverlayables.put(target, overlayables); return targetToOverlayables; } }; } Loading Loading @@ -167,7 +174,7 @@ public class OverlayReferenceMapper { } // TODO(b/135203078): Replace with isOverlay boolean flag check; fix test mocks if (mProvider.getTargetToOverlayables(pkg) != null) { if (!mProvider.getTargetToOverlayables(pkg).isEmpty()) { addOverlay(pkg, otherPkgs, changed); } Loading Loading @@ -238,17 +245,20 @@ public class OverlayReferenceMapper { String target = targetPkg.getPackageName(); removeTarget(target, changedPackages); final Map<String, String> overlayablesToActors = targetPkg.getOverlayables(); for (final var entry : overlayablesToActors.entrySet()) { final String overlayable = entry.getKey(); final String actor = entry.getValue(); Map<String, String> overlayablesToActors = targetPkg.getOverlayables(); for (String overlayable : overlayablesToActors.keySet()) { String actor = overlayablesToActors.get(overlayable); addTargetToMap(actor, target, changedPackages); for (AndroidPackage overlayPkg : otherPkgs.values()) { var targetToOverlayables = Map<String, Set<String>> targetToOverlayables = mProvider.getTargetToOverlayables(overlayPkg); if (targetToOverlayables != null && targetToOverlayables.first.equals(target) && targetToOverlayables.second.equals(overlayable)) { Set<String> overlayables = targetToOverlayables.get(target); if (CollectionUtils.isEmpty(overlayables)) { continue; } if (overlayables.contains(overlayable)) { String overlay = overlayPkg.getPackageName(); addOverlayToMap(actor, target, overlay, changedPackages); } Loading Loading @@ -300,25 +310,28 @@ public class OverlayReferenceMapper { String overlay = overlayPkg.getPackageName(); removeOverlay(overlay, changedPackages); Pair<String, String> targetToOverlayables = Map<String, Set<String>> targetToOverlayables = mProvider.getTargetToOverlayables(overlayPkg); if (targetToOverlayables != null) { String target = targetToOverlayables.first; for (Map.Entry<String, Set<String>> entry : targetToOverlayables.entrySet()) { String target = entry.getKey(); Set<String> overlayables = entry.getValue(); AndroidPackage targetPkg = otherPkgs.get(target); if (targetPkg == null) { return; continue; } String targetPkgName = targetPkg.getPackageName(); Map<String, String> overlayableToActor = targetPkg.getOverlayables(); String overlayable = targetToOverlayables.second; for (String overlayable : overlayables) { String actor = overlayableToActor.get(overlayable); if (TextUtils.isEmpty(actor)) { return; continue; } addOverlayToMap(actor, targetPkgName, overlay, changedPackages); } } } } public void rebuildIfDeferred() { synchronized (mLock) { Loading Loading @@ -417,11 +430,11 @@ public class OverlayReferenceMapper { String getActorPkg(@NonNull String actor); /** * Mock response of overlay tags. * Mock response of multiple overlay tags. * * TODO(b/119899133): Replace with actual implementation; fix OverlayReferenceMapperTests */ @Nullable Pair<String, String> getTargetToOverlayables(@NonNull AndroidPackage pkg); @NonNull Map<String, Set<String>> getTargetToOverlayables(@NonNull AndroidPackage pkg); } }
services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/AppsFilterImplTest.java +19 −11 Original line number Diff line number Diff line Loading @@ -45,7 +45,6 @@ import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Pair; import android.util.SparseArray; import androidx.annotation.NonNull; Loading Loading @@ -79,7 +78,10 @@ import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @Presubmit @RunWith(JUnit4.class) Loading Loading @@ -883,15 +885,18 @@ public class AppsFilterImplTest { return null; } @Nullable @NonNull @Override public Pair<String, String> getTargetToOverlayables( public Map<String, Set<String>> getTargetToOverlayables( @NonNull AndroidPackage pkg) { if (overlay.getPackageName().equals(pkg.getPackageName())) { return Pair.create(overlay.getOverlayTarget(), overlay.getOverlayTargetOverlayableName()); Map<String, Set<String>> map = new ArrayMap<>(); Set<String> set = new ArraySet<>(); set.add(overlay.getOverlayTargetOverlayableName()); map.put(overlay.getOverlayTarget(), set); return map; } return null; return Collections.emptyMap(); } }, mMockHandler); Loading Loading @@ -972,15 +977,18 @@ public class AppsFilterImplTest { return null; } @Nullable @NonNull @Override public Pair<String, String> getTargetToOverlayables( public Map<String, Set<String>> getTargetToOverlayables( @NonNull AndroidPackage pkg) { if (overlay.getPackageName().equals(pkg.getPackageName())) { return Pair.create(overlay.getOverlayTarget(), overlay.getOverlayTargetOverlayableName()); Map<String, Set<String>> map = new ArrayMap<>(); Set<String> set = new ArraySet<>(); set.add(overlay.getOverlayTargetOverlayableName()); map.put(overlay.getOverlayTarget(), set); return map; } return null; return Collections.emptyMap(); } }, mMockHandler); Loading
services/tests/servicestests/src/com/android/server/om/OverlayReferenceMapperTests.kt +39 −8 Original line number Diff line number Diff line Loading @@ -76,10 +76,12 @@ class OverlayReferenceMapperTests { val overlay1 = mockOverlay(1) mapper = mapper( overlayToTargetToOverlayables = mapOf( overlay0.packageName to android.util.Pair(target.packageName, target.overlayables.keys.first()), overlay1.packageName to android.util.Pair(target.packageName, target.overlayables.keys.first()) overlay0.packageName to mapOf( target.packageName to target.overlayables.keys ), overlay1.packageName to mapOf( target.packageName to target.overlayables.keys ) ) ) val existing = mapper.addInOrder(overlay0, overlay1) { Loading Loading @@ -131,6 +133,33 @@ class OverlayReferenceMapperTests { assertMapping(ACTOR_PACKAGE_NAME to setOf(target)) } @Test fun overlayWithMultipleTargets() { val target0 = mockTarget(0) val target1 = mockTarget(1) val overlay = mockOverlay() mapper = mapper( overlayToTargetToOverlayables = mapOf( overlay.packageName to mapOf( target0.packageName to target0.overlayables.keys, target1.packageName to target1.overlayables.keys ) ) ) mapper.addInOrder(target0, target1, overlay) { assertThat(it).containsExactly(ACTOR_PACKAGE_NAME) } assertMapping(ACTOR_PACKAGE_NAME to setOf(target0, target1, overlay)) mapper.remove(target0) { assertThat(it).containsExactly(ACTOR_PACKAGE_NAME) } assertMapping(ACTOR_PACKAGE_NAME to setOf(target1, overlay)) mapper.remove(target1) { assertThat(it).containsExactly(ACTOR_PACKAGE_NAME) } assertEmpty() } @Test fun overlayWithoutTarget() { val overlay = mockOverlay() Loading Loading @@ -190,15 +219,17 @@ class OverlayReferenceMapperTests { namedActors: Map<String, Map<String, String>> = Uri.parse(ACTOR_NAME).run { mapOf(authority!! to mapOf(pathSegments.first() to ACTOR_PACKAGE_NAME)) }, overlayToTargetToOverlayables: Map<String, android.util.Pair<String, String>> = mapOf( mockOverlay().packageName to mockTarget().run { android.util.Pair(packageName!!, overlayables.keys.first()) }) overlayToTargetToOverlayables: Map<String, Map<String, Set<String>>> = mapOf( mockOverlay().packageName to mapOf( mockTarget().run { packageName to overlayables.keys } ) ) ) = OverlayReferenceMapper(deferRebuild, object : OverlayReferenceMapper.Provider { override fun getActorPkg(actor: String) = OverlayActorEnforcer.getPackageNameForActor(actor, namedActors).first override fun getTargetToOverlayables(pkg: AndroidPackage) = overlayToTargetToOverlayables[pkg.packageName] overlayToTargetToOverlayables[pkg.packageName] ?: emptyMap() }) private fun mockTarget(increment: Int = 0) = mockThrowOnUnmocked<AndroidPackage> { Loading