Loading services/core/java/com/android/server/om/OverlayReferenceMapper.java +25 −37 Original line number Diff line number Diff line Loading @@ -26,15 +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.Objects; import java.util.Set; /** Loading Loading @@ -121,20 +119,16 @@ public class OverlayReferenceMapper { return actorPair.first; } @NonNull @Nullable @Override public Map<String, Set<String>> getTargetToOverlayables(@NonNull AndroidPackage pkg) { public Pair<String, String> getTargetToOverlayables(@NonNull AndroidPackage pkg) { String target = pkg.getOverlayTarget(); if (TextUtils.isEmpty(target)) { return Collections.emptyMap(); return null; } String overlayable = pkg.getOverlayTargetOverlayableName(); Map<String, Set<String>> targetToOverlayables = new HashMap<>(); Set<String> overlayables = new HashSet<>(); overlayables.add(overlayable); targetToOverlayables.put(target, overlayables); return targetToOverlayables; return Pair.create(target, overlayable); } }; } Loading Loading @@ -174,7 +168,7 @@ public class OverlayReferenceMapper { } // TODO(b/135203078): Replace with isOverlay boolean flag check; fix test mocks if (!mProvider.getTargetToOverlayables(pkg).isEmpty()) { if (mProvider.getTargetToOverlayables(pkg) != null) { addOverlay(pkg, otherPkgs, changed); } Loading Loading @@ -245,20 +239,17 @@ public class OverlayReferenceMapper { String target = targetPkg.getPackageName(); removeTarget(target, changedPackages); Map<String, String> overlayablesToActors = targetPkg.getOverlayables(); for (String overlayable : overlayablesToActors.keySet()) { String actor = overlayablesToActors.get(overlayable); final Map<String, String> overlayablesToActors = targetPkg.getOverlayables(); for (final var entry : overlayablesToActors.entrySet()) { final String overlayable = entry.getKey(); final String actor = entry.getValue(); addTargetToMap(actor, target, changedPackages); for (AndroidPackage overlayPkg : otherPkgs.values()) { Map<String, Set<String>> targetToOverlayables = var targetToOverlayables = mProvider.getTargetToOverlayables(overlayPkg); Set<String> overlayables = targetToOverlayables.get(target); if (CollectionUtils.isEmpty(overlayables)) { continue; } if (overlayables.contains(overlayable)) { if (targetToOverlayables != null && targetToOverlayables.first.equals(target) && Objects.equals(targetToOverlayables.second, overlayable)) { String overlay = overlayPkg.getPackageName(); addOverlayToMap(actor, target, overlay, changedPackages); } Loading Loading @@ -310,28 +301,25 @@ public class OverlayReferenceMapper { String overlay = overlayPkg.getPackageName(); removeOverlay(overlay, changedPackages); Map<String, Set<String>> targetToOverlayables = Pair<String, String> targetToOverlayables = mProvider.getTargetToOverlayables(overlayPkg); for (Map.Entry<String, Set<String>> entry : targetToOverlayables.entrySet()) { String target = entry.getKey(); Set<String> overlayables = entry.getValue(); if (targetToOverlayables != null) { String target = targetToOverlayables.first; AndroidPackage targetPkg = otherPkgs.get(target); if (targetPkg == null) { continue; return; } String targetPkgName = targetPkg.getPackageName(); Map<String, String> overlayableToActor = targetPkg.getOverlayables(); for (String overlayable : overlayables) { String overlayable = targetToOverlayables.second; String actor = overlayableToActor.get(overlayable); if (TextUtils.isEmpty(actor)) { continue; return; } addOverlayToMap(actor, targetPkgName, overlay, changedPackages); } } } } public void rebuildIfDeferred() { synchronized (mLock) { Loading Loading @@ -430,11 +418,11 @@ public class OverlayReferenceMapper { String getActorPkg(@NonNull String actor); /** * Mock response of multiple overlay tags. * Mock response of overlay tags. * * TODO(b/119899133): Replace with actual implementation; fix OverlayReferenceMapperTests */ @NonNull Map<String, Set<String>> getTargetToOverlayables(@NonNull AndroidPackage pkg); @Nullable Pair<String, String> getTargetToOverlayables(@NonNull AndroidPackage pkg); } } services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/AppsFilterImplTest.java +11 −19 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ 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 @@ -78,10 +79,7 @@ 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 @@ -885,18 +883,15 @@ public class AppsFilterImplTest { return null; } @NonNull @Nullable @Override public Map<String, Set<String>> getTargetToOverlayables( public Pair<String, String> getTargetToOverlayables( @NonNull AndroidPackage pkg) { if (overlay.getPackageName().equals(pkg.getPackageName())) { Map<String, Set<String>> map = new ArrayMap<>(); Set<String> set = new ArraySet<>(); set.add(overlay.getOverlayTargetOverlayableName()); map.put(overlay.getOverlayTarget(), set); return map; return Pair.create(overlay.getOverlayTarget(), overlay.getOverlayTargetOverlayableName()); } return Collections.emptyMap(); return null; } }, mMockHandler); Loading Loading @@ -977,18 +972,15 @@ public class AppsFilterImplTest { return null; } @NonNull @Nullable @Override public Map<String, Set<String>> getTargetToOverlayables( public Pair<String, String> getTargetToOverlayables( @NonNull AndroidPackage pkg) { if (overlay.getPackageName().equals(pkg.getPackageName())) { Map<String, Set<String>> map = new ArrayMap<>(); Set<String> set = new ArraySet<>(); set.add(overlay.getOverlayTargetOverlayableName()); map.put(overlay.getOverlayTarget(), set); return map; return Pair.create(overlay.getOverlayTarget(), overlay.getOverlayTargetOverlayableName()); } return Collections.emptyMap(); return null; } }, mMockHandler); Loading services/tests/servicestests/src/com/android/server/om/OverlayReferenceMapperTests.kt +29 −37 Original line number Diff line number Diff line Loading @@ -76,12 +76,10 @@ class OverlayReferenceMapperTests { val overlay1 = mockOverlay(1) mapper = mapper( overlayToTargetToOverlayables = mapOf( overlay0.packageName to mapOf( target.packageName to target.overlayables.keys ), overlay1.packageName to mapOf( target.packageName to target.overlayables.keys ) overlay0.packageName to android.util.Pair(target.packageName, target.overlayables.keys.first()), overlay1.packageName to android.util.Pair(target.packageName, target.overlayables.keys.first()) ) ) val existing = mapper.addInOrder(overlay0, overlay1) { Loading Loading @@ -134,42 +132,38 @@ class OverlayReferenceMapperTests { } @Test fun overlayWithMultipleTargets() { val target0 = mockTarget(0) val target1 = mockTarget(1) fun overlayWithoutTarget() { 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) mapper.addInOrder(overlay) { assertThat(it).isEmpty() } assertMapping(ACTOR_PACKAGE_NAME to setOf(target1, overlay)) mapper.remove(target1) { assertThat(it).containsExactly(ACTOR_PACKAGE_NAME) // An overlay can only have visibility exposed through its target assertEmpty() mapper.remove(overlay) { assertThat(it).isEmpty() } assertEmpty() } @Test fun overlayWithoutTarget() { fun targetWithNullOverlayable() { val target = mockTarget() val overlay = mockOverlay() mapper.addInOrder(overlay) { mapper = mapper( overlayToTargetToOverlayables = mapOf( overlay.packageName to android.util.Pair(target.packageName, null) ) ) val existing = mapper.addInOrder(overlay) { assertThat(it).isEmpty() } // An overlay can only have visibility exposed through its target assertEmpty() mapper.remove(overlay) { assertThat(it).isEmpty() mapper.addInOrder(target, existing = existing) { assertThat(it).containsExactly(ACTOR_PACKAGE_NAME) } assertMapping(ACTOR_PACKAGE_NAME to setOf(target)) mapper.remove(target) { assertThat(it).containsExactly(ACTOR_PACKAGE_NAME) } assertEmpty() } Loading Loading @@ -219,17 +213,15 @@ 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, Map<String, Set<String>>> = mapOf( mockOverlay().packageName to mapOf( mockTarget().run { packageName to overlayables.keys } ) ) overlayToTargetToOverlayables: Map<String, android.util.Pair<String, String>> = mapOf( mockOverlay().packageName to mockTarget().run { android.util.Pair(packageName!!, overlayables.keys.first()) }) ) = OverlayReferenceMapper(deferRebuild, object : OverlayReferenceMapper.Provider { override fun getActorPkg(actor: String) = OverlayActorEnforcer.getPackageNameForActor(actor, namedActors).first override fun getTargetToOverlayables(pkg: AndroidPackage) = overlayToTargetToOverlayables[pkg.packageName] ?: emptyMap() overlayToTargetToOverlayables[pkg.packageName] }) private fun mockTarget(increment: Int = 0) = mockThrowOnUnmocked<AndroidPackage> { Loading Loading
services/core/java/com/android/server/om/OverlayReferenceMapper.java +25 −37 Original line number Diff line number Diff line Loading @@ -26,15 +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.Objects; import java.util.Set; /** Loading Loading @@ -121,20 +119,16 @@ public class OverlayReferenceMapper { return actorPair.first; } @NonNull @Nullable @Override public Map<String, Set<String>> getTargetToOverlayables(@NonNull AndroidPackage pkg) { public Pair<String, String> getTargetToOverlayables(@NonNull AndroidPackage pkg) { String target = pkg.getOverlayTarget(); if (TextUtils.isEmpty(target)) { return Collections.emptyMap(); return null; } String overlayable = pkg.getOverlayTargetOverlayableName(); Map<String, Set<String>> targetToOverlayables = new HashMap<>(); Set<String> overlayables = new HashSet<>(); overlayables.add(overlayable); targetToOverlayables.put(target, overlayables); return targetToOverlayables; return Pair.create(target, overlayable); } }; } Loading Loading @@ -174,7 +168,7 @@ public class OverlayReferenceMapper { } // TODO(b/135203078): Replace with isOverlay boolean flag check; fix test mocks if (!mProvider.getTargetToOverlayables(pkg).isEmpty()) { if (mProvider.getTargetToOverlayables(pkg) != null) { addOverlay(pkg, otherPkgs, changed); } Loading Loading @@ -245,20 +239,17 @@ public class OverlayReferenceMapper { String target = targetPkg.getPackageName(); removeTarget(target, changedPackages); Map<String, String> overlayablesToActors = targetPkg.getOverlayables(); for (String overlayable : overlayablesToActors.keySet()) { String actor = overlayablesToActors.get(overlayable); final Map<String, String> overlayablesToActors = targetPkg.getOverlayables(); for (final var entry : overlayablesToActors.entrySet()) { final String overlayable = entry.getKey(); final String actor = entry.getValue(); addTargetToMap(actor, target, changedPackages); for (AndroidPackage overlayPkg : otherPkgs.values()) { Map<String, Set<String>> targetToOverlayables = var targetToOverlayables = mProvider.getTargetToOverlayables(overlayPkg); Set<String> overlayables = targetToOverlayables.get(target); if (CollectionUtils.isEmpty(overlayables)) { continue; } if (overlayables.contains(overlayable)) { if (targetToOverlayables != null && targetToOverlayables.first.equals(target) && Objects.equals(targetToOverlayables.second, overlayable)) { String overlay = overlayPkg.getPackageName(); addOverlayToMap(actor, target, overlay, changedPackages); } Loading Loading @@ -310,28 +301,25 @@ public class OverlayReferenceMapper { String overlay = overlayPkg.getPackageName(); removeOverlay(overlay, changedPackages); Map<String, Set<String>> targetToOverlayables = Pair<String, String> targetToOverlayables = mProvider.getTargetToOverlayables(overlayPkg); for (Map.Entry<String, Set<String>> entry : targetToOverlayables.entrySet()) { String target = entry.getKey(); Set<String> overlayables = entry.getValue(); if (targetToOverlayables != null) { String target = targetToOverlayables.first; AndroidPackage targetPkg = otherPkgs.get(target); if (targetPkg == null) { continue; return; } String targetPkgName = targetPkg.getPackageName(); Map<String, String> overlayableToActor = targetPkg.getOverlayables(); for (String overlayable : overlayables) { String overlayable = targetToOverlayables.second; String actor = overlayableToActor.get(overlayable); if (TextUtils.isEmpty(actor)) { continue; return; } addOverlayToMap(actor, targetPkgName, overlay, changedPackages); } } } } public void rebuildIfDeferred() { synchronized (mLock) { Loading Loading @@ -430,11 +418,11 @@ public class OverlayReferenceMapper { String getActorPkg(@NonNull String actor); /** * Mock response of multiple overlay tags. * Mock response of overlay tags. * * TODO(b/119899133): Replace with actual implementation; fix OverlayReferenceMapperTests */ @NonNull Map<String, Set<String>> getTargetToOverlayables(@NonNull AndroidPackage pkg); @Nullable Pair<String, String> getTargetToOverlayables(@NonNull AndroidPackage pkg); } }
services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/AppsFilterImplTest.java +11 −19 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ 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 @@ -78,10 +79,7 @@ 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 @@ -885,18 +883,15 @@ public class AppsFilterImplTest { return null; } @NonNull @Nullable @Override public Map<String, Set<String>> getTargetToOverlayables( public Pair<String, String> getTargetToOverlayables( @NonNull AndroidPackage pkg) { if (overlay.getPackageName().equals(pkg.getPackageName())) { Map<String, Set<String>> map = new ArrayMap<>(); Set<String> set = new ArraySet<>(); set.add(overlay.getOverlayTargetOverlayableName()); map.put(overlay.getOverlayTarget(), set); return map; return Pair.create(overlay.getOverlayTarget(), overlay.getOverlayTargetOverlayableName()); } return Collections.emptyMap(); return null; } }, mMockHandler); Loading Loading @@ -977,18 +972,15 @@ public class AppsFilterImplTest { return null; } @NonNull @Nullable @Override public Map<String, Set<String>> getTargetToOverlayables( public Pair<String, String> getTargetToOverlayables( @NonNull AndroidPackage pkg) { if (overlay.getPackageName().equals(pkg.getPackageName())) { Map<String, Set<String>> map = new ArrayMap<>(); Set<String> set = new ArraySet<>(); set.add(overlay.getOverlayTargetOverlayableName()); map.put(overlay.getOverlayTarget(), set); return map; return Pair.create(overlay.getOverlayTarget(), overlay.getOverlayTargetOverlayableName()); } return Collections.emptyMap(); return null; } }, mMockHandler); Loading
services/tests/servicestests/src/com/android/server/om/OverlayReferenceMapperTests.kt +29 −37 Original line number Diff line number Diff line Loading @@ -76,12 +76,10 @@ class OverlayReferenceMapperTests { val overlay1 = mockOverlay(1) mapper = mapper( overlayToTargetToOverlayables = mapOf( overlay0.packageName to mapOf( target.packageName to target.overlayables.keys ), overlay1.packageName to mapOf( target.packageName to target.overlayables.keys ) overlay0.packageName to android.util.Pair(target.packageName, target.overlayables.keys.first()), overlay1.packageName to android.util.Pair(target.packageName, target.overlayables.keys.first()) ) ) val existing = mapper.addInOrder(overlay0, overlay1) { Loading Loading @@ -134,42 +132,38 @@ class OverlayReferenceMapperTests { } @Test fun overlayWithMultipleTargets() { val target0 = mockTarget(0) val target1 = mockTarget(1) fun overlayWithoutTarget() { 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) mapper.addInOrder(overlay) { assertThat(it).isEmpty() } assertMapping(ACTOR_PACKAGE_NAME to setOf(target1, overlay)) mapper.remove(target1) { assertThat(it).containsExactly(ACTOR_PACKAGE_NAME) // An overlay can only have visibility exposed through its target assertEmpty() mapper.remove(overlay) { assertThat(it).isEmpty() } assertEmpty() } @Test fun overlayWithoutTarget() { fun targetWithNullOverlayable() { val target = mockTarget() val overlay = mockOverlay() mapper.addInOrder(overlay) { mapper = mapper( overlayToTargetToOverlayables = mapOf( overlay.packageName to android.util.Pair(target.packageName, null) ) ) val existing = mapper.addInOrder(overlay) { assertThat(it).isEmpty() } // An overlay can only have visibility exposed through its target assertEmpty() mapper.remove(overlay) { assertThat(it).isEmpty() mapper.addInOrder(target, existing = existing) { assertThat(it).containsExactly(ACTOR_PACKAGE_NAME) } assertMapping(ACTOR_PACKAGE_NAME to setOf(target)) mapper.remove(target) { assertThat(it).containsExactly(ACTOR_PACKAGE_NAME) } assertEmpty() } Loading Loading @@ -219,17 +213,15 @@ 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, Map<String, Set<String>>> = mapOf( mockOverlay().packageName to mapOf( mockTarget().run { packageName to overlayables.keys } ) ) overlayToTargetToOverlayables: Map<String, android.util.Pair<String, String>> = mapOf( mockOverlay().packageName to mockTarget().run { android.util.Pair(packageName!!, overlayables.keys.first()) }) ) = OverlayReferenceMapper(deferRebuild, object : OverlayReferenceMapper.Provider { override fun getActorPkg(actor: String) = OverlayActorEnforcer.getPackageNameForActor(actor, namedActors).first override fun getTargetToOverlayables(pkg: AndroidPackage) = overlayToTargetToOverlayables[pkg.packageName] ?: emptyMap() overlayToTargetToOverlayables[pkg.packageName] }) private fun mockTarget(increment: Int = 0) = mockThrowOnUnmocked<AndroidPackage> { Loading