diff options
6 files changed, 62 insertions, 9 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index bba8043af5be..db47306ad58e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3409,7 +3409,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService } @Nullable - private String getDevicePolicyManagementRoleHolderPackageName(int userId) { + public String getDevicePolicyManagementRoleHolderPackageName(int userId) { return Binder.withCleanCallingIdentity(() -> { RoleManager roleManager = mContext.getSystemService(RoleManager.class); List<String> roleHolders = diff --git a/services/core/java/com/android/server/pm/SuspendPackageHelper.java b/services/core/java/com/android/server/pm/SuspendPackageHelper.java index ba825774daf6..08934c69e099 100644 --- a/services/core/java/com/android/server/pm/SuspendPackageHelper.java +++ b/services/core/java/com/android/server/pm/SuspendPackageHelper.java @@ -724,6 +724,10 @@ public final class SuspendPackageHelper { for (PackageInfo info : pkgInfos) { result.add(info.packageName); } + + // Role holder may be null, but ArraySet handles it correctly. + result.remove(mPm.getDevicePolicyManagementRoleHolderPackageName(userId)); + return result; } diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java index 90af4c6236aa..1eb56f1b7d1c 100644 --- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java +++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java @@ -280,6 +280,10 @@ class ActivityStartInterceptor { return false; } + if (isKeepProfilesRunningEnabled() && !isPackageSuspended()) { + return false; + } + IntentSender target = createIntentSenderForOriginalIntent(mCallingUid, FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT); @@ -322,8 +326,7 @@ class ActivityStartInterceptor { private boolean interceptSuspendedPackageIfNeeded() { // Do not intercept if the package is not suspended - if (mAInfo == null || mAInfo.applicationInfo == null || - (mAInfo.applicationInfo.flags & FLAG_SUSPENDED) == 0) { + if (!isPackageSuspended()) { return false; } final PackageManagerInternal pmi = mService.getPackageManagerInternalLocked(); @@ -467,6 +470,17 @@ class ActivityStartInterceptor { return true; } + private boolean isPackageSuspended() { + return mAInfo != null && mAInfo.applicationInfo != null + && (mAInfo.applicationInfo.flags & FLAG_SUSPENDED) != 0; + } + + private static boolean isKeepProfilesRunningEnabled() { + DevicePolicyManagerInternal dpmi = + LocalServices.getService(DevicePolicyManagerInternal.class); + return dpmi == null || dpmi.isKeepProfilesRunningEnabled(); + } + /** * Called when an activity is successfully launched. */ diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageHelperTestBase.kt b/services/tests/mockingservicestests/src/com/android/server/pm/PackageHelperTestBase.kt index cfef0b23b3e7..5fd270ecb2b4 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageHelperTestBase.kt +++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageHelperTestBase.kt @@ -48,6 +48,7 @@ open class PackageHelperTestBase { const val UNINSTALLER_PACKAGE = "com.android.test.known.uninstaller" const val VERIFIER_PACKAGE = "com.android.test.known.verifier" const val PERMISSION_CONTROLLER_PACKAGE = "com.android.test.known.permission" + const val MGMT_ROLE_HOLDER_PACKAGE = "com.android.test.know.device_management" const val TEST_USER_ID = 0 } @@ -119,6 +120,8 @@ open class PackageHelperTestBase { Mockito.doReturn(arrayOf(PERMISSION_CONTROLLER_PACKAGE)).`when`(pms) .getKnownPackageNamesInternal(any(), eq(KnownPackages.PACKAGE_PERMISSION_CONTROLLER), eq(TEST_USER_ID)) + Mockito.doReturn(MGMT_ROLE_HOLDER_PACKAGE).`when`(pms) + .getDevicePolicyManagementRoleHolderPackageName(eq(TEST_USER_ID)) } private fun createPackageManagerService(vararg stageExistingPackages: String): diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt index f9a8ead9cd4a..5cca5fa8ea0b 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt +++ b/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt @@ -128,13 +128,14 @@ class SuspendPackageHelperTest : PackageHelperTestBase() { fun setPackagesSuspended_forQuietMode() { val knownPackages = arrayOf(DEVICE_ADMIN_PACKAGE, DEFAULT_HOME_PACKAGE, DIALER_PACKAGE, INSTALLER_PACKAGE, UNINSTALLER_PACKAGE, VERIFIER_PACKAGE, - PERMISSION_CONTROLLER_PACKAGE) + PERMISSION_CONTROLLER_PACKAGE, MGMT_ROLE_HOLDER_PACKAGE) val failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), knownPackages, true /* suspended */, null /* appExtras */, null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid, true /* forQuietMode */)!! - assertThat(failedNames.size).isEqualTo(0) + assertThat(failedNames.size).isEqualTo(1) + assertThat(failedNames[0]).isEqualTo(MGMT_ROLE_HOLDER_PACKAGE) } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java index 4890f3e6cbf1..bcb0c6b5c269 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java @@ -250,9 +250,22 @@ public class ActivityStartInterceptorTest { } @Test - public void testInterceptQuietProfile() { - // GIVEN that the user the activity is starting as is currently in quiet mode + public void testInterceptQuietProfile_keepProfilesRunningEnabled() { + // GIVEN that the user the activity is starting as is currently in quiet mode and + // profiles are kept running when in quiet mode. when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true); + when(mDevicePolicyManager.isKeepProfilesRunningEnabled()).thenReturn(true); + + // THEN calling intercept returns false because package also has to be suspended. + assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); + } + + @Test + public void testInterceptQuietProfile_keepProfilesRunningDisabled() { + // GIVEN that the user the activity is starting as is currently in quiet mode and + // profiles are stopped when in quiet mode (pre-U behavior, no profile app suspension). + when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true); + when(mDevicePolicyManager.isKeepProfilesRunningEnabled()).thenReturn(false); // THEN calling intercept returns true assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); @@ -263,10 +276,28 @@ public class ActivityStartInterceptorTest { } @Test - public void testInterceptQuietProfileWhenPackageSuspended() { + public void testInterceptQuietProfileWhenPackageSuspended_keepProfilesRunningEnabled() { + // GIVEN that the user the activity is starting as is currently in quiet mode, + // the package is suspended and profiles are kept running while in quiet mode. + suspendPackage("com.test.suspending.package"); + when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true); + when(mDevicePolicyManager.isKeepProfilesRunningEnabled()).thenReturn(true); + + // THEN calling intercept returns true + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); + + // THEN the returned intent is the quiet mode intent + assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID) + .filterEquals(mInterceptor.mIntent)); + } + + @Test + public void testInterceptQuietProfileWhenPackageSuspended_keepProfilesRunningDisabled() { + // GIVEN that the user the activity is starting as is currently in quiet mode, + // the package is suspended and profiles are stopped while in quiet mode. suspendPackage("com.test.suspending.package"); - // GIVEN that the user the activity is starting as is currently in quiet mode when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true); + when(mDevicePolicyManager.isKeepProfilesRunningEnabled()).thenReturn(false); // THEN calling intercept returns true assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); |