Loading services/core/java/com/android/server/pm/DistractingPackageHelper.java +50 −12 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.pm; import static android.content.pm.PackageManager.RESTRICTION_NONE; import static android.os.Process.SYSTEM_UID; import android.annotation.NonNull; import android.content.Intent; Loading @@ -27,11 +28,13 @@ import android.os.UserHandle; import android.util.ArraySet; import android.util.IntArray; import android.util.Slog; import android.util.SparseArray; import com.android.internal.util.ArrayUtils; import com.android.server.pm.pkg.PackageStateInternal; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** Loading Loading @@ -126,7 +129,7 @@ public final class DistractingPackageHelper { if (!changedPackagesList.isEmpty()) { final String[] changedPackages = changedPackagesList.toArray( new String[changedPackagesList.size()]); sendDistractingPackagesChanged(changedPackages, changedUids.toArray(), userId, sendDistractingPackagesChanged(snapshot, changedPackages, changedUids.toArray(), userId, restrictionFlags); mPm.scheduleWritePackageRestrictions(userId); } Loading Loading @@ -168,7 +171,7 @@ public final class DistractingPackageHelper { if (!changedPackages.isEmpty()) { final String[] packageArray = changedPackages.toArray( new String[changedPackages.size()]); sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId, sendDistractingPackagesChanged(snapshot, packageArray, changedUids.toArray(), userId, RESTRICTION_NONE); mPm.scheduleWritePackageRestrictions(userId); } Loading @@ -181,18 +184,53 @@ public final class DistractingPackageHelper { * @param uidList The uids of packages which have suspension changes. * @param userId The user where packages reside. */ void sendDistractingPackagesChanged(@NonNull String[] pkgList, void sendDistractingPackagesChanged(@NonNull Computer snapshot, @NonNull String[] pkgList, int[] uidList, int userId, int distractionFlags) { final Bundle extras = new Bundle(3); extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList); extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags); final List<List<String>> pkgsToSend = new ArrayList(pkgList.length); final List<IntArray> uidsToSend = new ArrayList(pkgList.length); final List<SparseArray<int[]>> allowListsToSend = new ArrayList(pkgList.length); final int[] userIds = new int[] {userId}; // Get allow lists for the pkg in the pkgList. Merge into the existed pkgs and uids if // allow lists are the same. for (int i = 0; i < pkgList.length; i++) { final String pkgName = pkgList[i]; final int uid = uidList[i]; SparseArray<int[]> allowList = mInjector.getAppsFilter().getVisibilityAllowList( snapshot.getPackageStateInternal(pkgName, SYSTEM_UID), userIds, snapshot.getPackageStates()); if (allowList == null) { allowList = new SparseArray<>(0); } boolean merged = false; for (int j = 0; j < allowListsToSend.size(); j++) { if (Arrays.equals(allowListsToSend.get(j).get(userId), allowList.get(userId))) { pkgsToSend.get(j).add(pkgName); uidsToSend.get(j).add(uid); merged = true; break; } } if (!merged) { pkgsToSend.add(new ArrayList<>(Arrays.asList(pkgName))); uidsToSend.add(IntArray.wrap(new int[] {uid})); allowListsToSend.add(allowList); } } final Handler handler = mInjector.getHandler(); for (int i = 0; i < pkgsToSend.size(); i++) { final Bundle extras = new Bundle(3); extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgsToSend.get(i).toArray(new String[pkgsToSend.get(i).size()])); extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidsToSend.get(i).toArray()); extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags); final SparseArray<int[]> allowList = allowListsToSend.get(i).size() == 0 ? null : allowListsToSend.get(i); handler.post(() -> mBroadcastHelper.sendPackageBroadcast( Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null /* pkg */, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null /* targetPkg */, null /* finishedReceiver */, new int[]{userId}, null /* instantUserIds */, null /* allowList */, null /* bOptions */)); Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null /* pkg */, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null /* targetPkg */, null /* finishedReceiver */, userIds, null /* instantUserIds */, allowList, null /* bOptions */)); } } } services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt +67 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import org.junit.runners.JUnit4 import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.never import org.mockito.Mockito.times import org.mockito.Mockito.verify @RunWith(JUnit4::class) Loading Loading @@ -192,4 +193,70 @@ class DistractingPackageHelperTest : PackageHelperTestBase() { Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), nullable(), anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable()) } @Test fun sendDistractingPackagesChanged_withSameVisibilityAllowList() { mockAllowList(packageSetting1, allowList(10001, 10002, 10003)) mockAllowList(packageSetting2, allowList(10001, 10002, 10003)) distractingPackageHelper.sendDistractingPackagesChanged(pms.snapshotComputer(), packagesToChange, uidsToChange, TEST_USER_ID, PackageManager.RESTRICTION_HIDE_NOTIFICATIONS) testHandler.flush() verify(broadcastHelper).sendPackageBroadcast(eq(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), bundleCaptor.capture(), anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable()) var changedPackages = bundleCaptor.value.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST) var changedUids = bundleCaptor.value.getIntArray(Intent.EXTRA_CHANGED_UID_LIST) assertThat(changedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2) assertThat(changedUids).asList().containsExactly( packageSetting1.appId, packageSetting2.appId) } @Test fun sendDistractingPackagesChanged_withDifferentVisibilityAllowList() { mockAllowList(packageSetting1, allowList(10001, 10002, 10003)) mockAllowList(packageSetting2, allowList(10001, 10002, 10004)) distractingPackageHelper.sendDistractingPackagesChanged(pms.snapshotComputer(), packagesToChange, uidsToChange, TEST_USER_ID, PackageManager.RESTRICTION_HIDE_NOTIFICATIONS) testHandler.flush() verify(broadcastHelper, times(2)).sendPackageBroadcast( eq(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), bundleCaptor.capture(), anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable()) bundleCaptor.allValues.forEach { var changedPackages = it.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST) var changedUids = it.getIntArray(Intent.EXTRA_CHANGED_UID_LIST) assertThat(changedPackages?.size).isEqualTo(1) assertThat(changedUids?.size).isEqualTo(1) assertThat(changedPackages?.get(0)).isAnyOf(TEST_PACKAGE_1, TEST_PACKAGE_2) assertThat(changedUids?.get(0)).isAnyOf(packageSetting1.appId, packageSetting2.appId) } } @Test fun sendDistractingPackagesChanged_withNullVisibilityAllowList() { mockAllowList(packageSetting1, allowList(10001, 10002, 10003)) mockAllowList(packageSetting2, null /* list */) distractingPackageHelper.sendDistractingPackagesChanged(pms.snapshotComputer(), packagesToChange, uidsToChange, TEST_USER_ID, PackageManager.RESTRICTION_HIDE_NOTIFICATIONS) testHandler.flush() verify(broadcastHelper, times(2)).sendPackageBroadcast( eq(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), bundleCaptor.capture(), anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable()) bundleCaptor.allValues.forEach { var changedPackages = it.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST) var changedUids = it.getIntArray(Intent.EXTRA_CHANGED_UID_LIST) assertThat(changedPackages?.size).isEqualTo(1) assertThat(changedUids?.size).isEqualTo(1) assertThat(changedPackages?.get(0)).isAnyOf(TEST_PACKAGE_1, TEST_PACKAGE_2) assertThat(changedUids?.get(0)).isAnyOf(packageSetting1.appId, packageSetting2.appId) } } } No newline at end of file services/tests/mockingservicestests/src/com/android/server/pm/PackageHelperTestBase.kt +14 −1 Original line number Diff line number Diff line Loading @@ -16,11 +16,12 @@ package com.android.server.pm import android.content.pm.PackageManagerInternal import android.os.Build import android.os.Bundle import android.os.UserHandle import android.os.UserManager import android.util.ArrayMap import android.util.SparseArray import com.android.server.pm.pkg.PackageStateInternal import com.android.server.testutils.TestHandler import com.android.server.testutils.any Loading @@ -32,6 +33,7 @@ import org.mockito.ArgumentCaptor import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito import org.mockito.Mockito.argThat import org.mockito.Mockito.spy import org.mockito.MockitoAnnotations Loading Loading @@ -139,4 +141,15 @@ open class PackageHelperTestBase { rule.system().validateFinalState() return pms } protected fun allowList(vararg uids: Int) = SparseArray<IntArray>().apply { this.put(TEST_USER_ID, uids) } protected fun mockAllowList(pkgSetting: PackageStateInternal, list: SparseArray<IntArray>?) { whenever(rule.mocks().appsFilter.getVisibilityAllowList( argThat { it?.packageName == pkgSetting.packageName }, any(IntArray::class.java), any() as ArrayMap<String, out PackageStateInternal> )).thenReturn(list) } } No newline at end of file services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt +0 −18 Original line number Diff line number Diff line Loading @@ -20,20 +20,14 @@ import android.content.Intent import android.content.pm.SuspendDialogInfo import android.os.Binder import android.os.PersistableBundle import android.util.ArrayMap import android.util.SparseArray import com.android.server.pm.KnownPackages import com.android.server.pm.pkg.PackageStateInternal import com.android.server.testutils.any import com.android.server.testutils.eq import com.android.server.testutils.nullable import com.android.server.testutils.whenever import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mockito.argThat import org.mockito.Mockito.times import org.mockito.Mockito.verify Loading Loading @@ -383,16 +377,4 @@ class SuspendPackageHelperTest : PackageHelperTestBase() { assertThat(modifiedUids).asList().containsExactly( packageSetting1.appId, packageSetting2.appId) } private fun allowList(vararg uids: Int) = SparseArray<IntArray>().apply { this.put(TEST_USER_ID, uids) } private fun mockAllowList(pkgSetting: PackageStateInternal, list: SparseArray<IntArray>?) { whenever(rule.mocks().appsFilter.getVisibilityAllowList( argThat { it?.packageName == pkgSetting.packageName }, any(IntArray::class.java), any() as ArrayMap<String, out PackageStateInternal> )) .thenReturn(list) } } Loading
services/core/java/com/android/server/pm/DistractingPackageHelper.java +50 −12 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.pm; import static android.content.pm.PackageManager.RESTRICTION_NONE; import static android.os.Process.SYSTEM_UID; import android.annotation.NonNull; import android.content.Intent; Loading @@ -27,11 +28,13 @@ import android.os.UserHandle; import android.util.ArraySet; import android.util.IntArray; import android.util.Slog; import android.util.SparseArray; import com.android.internal.util.ArrayUtils; import com.android.server.pm.pkg.PackageStateInternal; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** Loading Loading @@ -126,7 +129,7 @@ public final class DistractingPackageHelper { if (!changedPackagesList.isEmpty()) { final String[] changedPackages = changedPackagesList.toArray( new String[changedPackagesList.size()]); sendDistractingPackagesChanged(changedPackages, changedUids.toArray(), userId, sendDistractingPackagesChanged(snapshot, changedPackages, changedUids.toArray(), userId, restrictionFlags); mPm.scheduleWritePackageRestrictions(userId); } Loading Loading @@ -168,7 +171,7 @@ public final class DistractingPackageHelper { if (!changedPackages.isEmpty()) { final String[] packageArray = changedPackages.toArray( new String[changedPackages.size()]); sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId, sendDistractingPackagesChanged(snapshot, packageArray, changedUids.toArray(), userId, RESTRICTION_NONE); mPm.scheduleWritePackageRestrictions(userId); } Loading @@ -181,18 +184,53 @@ public final class DistractingPackageHelper { * @param uidList The uids of packages which have suspension changes. * @param userId The user where packages reside. */ void sendDistractingPackagesChanged(@NonNull String[] pkgList, void sendDistractingPackagesChanged(@NonNull Computer snapshot, @NonNull String[] pkgList, int[] uidList, int userId, int distractionFlags) { final Bundle extras = new Bundle(3); extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList); extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags); final List<List<String>> pkgsToSend = new ArrayList(pkgList.length); final List<IntArray> uidsToSend = new ArrayList(pkgList.length); final List<SparseArray<int[]>> allowListsToSend = new ArrayList(pkgList.length); final int[] userIds = new int[] {userId}; // Get allow lists for the pkg in the pkgList. Merge into the existed pkgs and uids if // allow lists are the same. for (int i = 0; i < pkgList.length; i++) { final String pkgName = pkgList[i]; final int uid = uidList[i]; SparseArray<int[]> allowList = mInjector.getAppsFilter().getVisibilityAllowList( snapshot.getPackageStateInternal(pkgName, SYSTEM_UID), userIds, snapshot.getPackageStates()); if (allowList == null) { allowList = new SparseArray<>(0); } boolean merged = false; for (int j = 0; j < allowListsToSend.size(); j++) { if (Arrays.equals(allowListsToSend.get(j).get(userId), allowList.get(userId))) { pkgsToSend.get(j).add(pkgName); uidsToSend.get(j).add(uid); merged = true; break; } } if (!merged) { pkgsToSend.add(new ArrayList<>(Arrays.asList(pkgName))); uidsToSend.add(IntArray.wrap(new int[] {uid})); allowListsToSend.add(allowList); } } final Handler handler = mInjector.getHandler(); for (int i = 0; i < pkgsToSend.size(); i++) { final Bundle extras = new Bundle(3); extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgsToSend.get(i).toArray(new String[pkgsToSend.get(i).size()])); extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidsToSend.get(i).toArray()); extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags); final SparseArray<int[]> allowList = allowListsToSend.get(i).size() == 0 ? null : allowListsToSend.get(i); handler.post(() -> mBroadcastHelper.sendPackageBroadcast( Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null /* pkg */, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null /* targetPkg */, null /* finishedReceiver */, new int[]{userId}, null /* instantUserIds */, null /* allowList */, null /* bOptions */)); Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null /* pkg */, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null /* targetPkg */, null /* finishedReceiver */, userIds, null /* instantUserIds */, allowList, null /* bOptions */)); } } }
services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt +67 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import org.junit.runners.JUnit4 import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.never import org.mockito.Mockito.times import org.mockito.Mockito.verify @RunWith(JUnit4::class) Loading Loading @@ -192,4 +193,70 @@ class DistractingPackageHelperTest : PackageHelperTestBase() { Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), nullable(), anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable()) } @Test fun sendDistractingPackagesChanged_withSameVisibilityAllowList() { mockAllowList(packageSetting1, allowList(10001, 10002, 10003)) mockAllowList(packageSetting2, allowList(10001, 10002, 10003)) distractingPackageHelper.sendDistractingPackagesChanged(pms.snapshotComputer(), packagesToChange, uidsToChange, TEST_USER_ID, PackageManager.RESTRICTION_HIDE_NOTIFICATIONS) testHandler.flush() verify(broadcastHelper).sendPackageBroadcast(eq(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), bundleCaptor.capture(), anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable()) var changedPackages = bundleCaptor.value.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST) var changedUids = bundleCaptor.value.getIntArray(Intent.EXTRA_CHANGED_UID_LIST) assertThat(changedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2) assertThat(changedUids).asList().containsExactly( packageSetting1.appId, packageSetting2.appId) } @Test fun sendDistractingPackagesChanged_withDifferentVisibilityAllowList() { mockAllowList(packageSetting1, allowList(10001, 10002, 10003)) mockAllowList(packageSetting2, allowList(10001, 10002, 10004)) distractingPackageHelper.sendDistractingPackagesChanged(pms.snapshotComputer(), packagesToChange, uidsToChange, TEST_USER_ID, PackageManager.RESTRICTION_HIDE_NOTIFICATIONS) testHandler.flush() verify(broadcastHelper, times(2)).sendPackageBroadcast( eq(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), bundleCaptor.capture(), anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable()) bundleCaptor.allValues.forEach { var changedPackages = it.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST) var changedUids = it.getIntArray(Intent.EXTRA_CHANGED_UID_LIST) assertThat(changedPackages?.size).isEqualTo(1) assertThat(changedUids?.size).isEqualTo(1) assertThat(changedPackages?.get(0)).isAnyOf(TEST_PACKAGE_1, TEST_PACKAGE_2) assertThat(changedUids?.get(0)).isAnyOf(packageSetting1.appId, packageSetting2.appId) } } @Test fun sendDistractingPackagesChanged_withNullVisibilityAllowList() { mockAllowList(packageSetting1, allowList(10001, 10002, 10003)) mockAllowList(packageSetting2, null /* list */) distractingPackageHelper.sendDistractingPackagesChanged(pms.snapshotComputer(), packagesToChange, uidsToChange, TEST_USER_ID, PackageManager.RESTRICTION_HIDE_NOTIFICATIONS) testHandler.flush() verify(broadcastHelper, times(2)).sendPackageBroadcast( eq(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), bundleCaptor.capture(), anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable()) bundleCaptor.allValues.forEach { var changedPackages = it.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST) var changedUids = it.getIntArray(Intent.EXTRA_CHANGED_UID_LIST) assertThat(changedPackages?.size).isEqualTo(1) assertThat(changedUids?.size).isEqualTo(1) assertThat(changedPackages?.get(0)).isAnyOf(TEST_PACKAGE_1, TEST_PACKAGE_2) assertThat(changedUids?.get(0)).isAnyOf(packageSetting1.appId, packageSetting2.appId) } } } No newline at end of file
services/tests/mockingservicestests/src/com/android/server/pm/PackageHelperTestBase.kt +14 −1 Original line number Diff line number Diff line Loading @@ -16,11 +16,12 @@ package com.android.server.pm import android.content.pm.PackageManagerInternal import android.os.Build import android.os.Bundle import android.os.UserHandle import android.os.UserManager import android.util.ArrayMap import android.util.SparseArray import com.android.server.pm.pkg.PackageStateInternal import com.android.server.testutils.TestHandler import com.android.server.testutils.any Loading @@ -32,6 +33,7 @@ import org.mockito.ArgumentCaptor import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito import org.mockito.Mockito.argThat import org.mockito.Mockito.spy import org.mockito.MockitoAnnotations Loading Loading @@ -139,4 +141,15 @@ open class PackageHelperTestBase { rule.system().validateFinalState() return pms } protected fun allowList(vararg uids: Int) = SparseArray<IntArray>().apply { this.put(TEST_USER_ID, uids) } protected fun mockAllowList(pkgSetting: PackageStateInternal, list: SparseArray<IntArray>?) { whenever(rule.mocks().appsFilter.getVisibilityAllowList( argThat { it?.packageName == pkgSetting.packageName }, any(IntArray::class.java), any() as ArrayMap<String, out PackageStateInternal> )).thenReturn(list) } } No newline at end of file
services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt +0 −18 Original line number Diff line number Diff line Loading @@ -20,20 +20,14 @@ import android.content.Intent import android.content.pm.SuspendDialogInfo import android.os.Binder import android.os.PersistableBundle import android.util.ArrayMap import android.util.SparseArray import com.android.server.pm.KnownPackages import com.android.server.pm.pkg.PackageStateInternal import com.android.server.testutils.any import com.android.server.testutils.eq import com.android.server.testutils.nullable import com.android.server.testutils.whenever import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mockito.argThat import org.mockito.Mockito.times import org.mockito.Mockito.verify Loading Loading @@ -383,16 +377,4 @@ class SuspendPackageHelperTest : PackageHelperTestBase() { assertThat(modifiedUids).asList().containsExactly( packageSetting1.appId, packageSetting2.appId) } private fun allowList(vararg uids: Int) = SparseArray<IntArray>().apply { this.put(TEST_USER_ID, uids) } private fun mockAllowList(pkgSetting: PackageStateInternal, list: SparseArray<IntArray>?) { whenever(rule.mocks().appsFilter.getVisibilityAllowList( argThat { it?.packageName == pkgSetting.packageName }, any(IntArray::class.java), any() as ArrayMap<String, out PackageStateInternal> )) .thenReturn(list) } }