Exempt mgmt role holder from quiet mode suspension
This is accomplished via two changes: 1. SuspendPackageHelper now filter mgmt role holder out from the list of packages to suspend for quiet mode. 2. When "Keep profiles running" feature is enabled, ActivityStartInterceptor checks suspended state in addition to quiet mode, so if package is not suspended, its activities can be launched. Bug: 284108214 Test: atest SuspendPackageHelperTest Test: atest WmTests:ActivityStartInterceptorTest Test: atest CtsDevicePolicyTestCases:android.devicepolicy.cts.QuietModeTest Change-Id: I9b70a548db8dd5d3e1ade66464a5d05e2118025a
This commit is contained in:
@@ -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 =
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
// 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(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");
|
||||
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));
|
||||
|
||||
Reference in New Issue
Block a user