Loading services/core/java/android/content/pm/PackageManagerInternal.java +10 −0 Original line number Diff line number Diff line Loading @@ -988,4 +988,14 @@ public abstract class PackageManagerInternal { * Unblocks uninstall for all packages for the user. */ public abstract void clearBlockUninstallForUser(@UserIdInt int userId); /** * Unsuspends all packages suspended by the given package for the user. */ public abstract void unsuspendForSuspendingPackage(String suspendingPackage, int userId); /** * Returns {@code true} if the package is suspending any packages for the user. */ public abstract boolean isSuspendingAnyPackages(String suspendingPackage, int userId); } services/core/java/com/android/server/pm/PackageManagerService.java +21 −1 Original line number Diff line number Diff line Loading @@ -13518,6 +13518,17 @@ public class PackageManagerService extends IPackageManager.Stub removeSuspensionsBySuspendingPackage(allPackages, suspendingPackage::equals, userId); } boolean isSuspendingAnyPackages(String suspendingPackage, int userId) { synchronized (mLock) { for (final PackageSetting ps : mSettings.mPackages.values()) { if (ps.isSuspendedBy(suspendingPackage, userId)) { return true; } } } return false; } /** * Removes any suspensions on given packages that were added by packages that pass the given * predicate. Loading Loading @@ -23913,7 +23924,6 @@ public class PackageManagerService extends IPackageManager.Stub callingUid); } @Override public boolean isPlatformSigned(String packageName) { PackageSetting packageSetting = mSettings.mPackages.get(packageName); Loading Loading @@ -25018,6 +25028,16 @@ public class PackageManagerService extends IPackageManager.Stub mSettings.writePackageRestrictionsLPr(userId); } } @Override public void unsuspendForSuspendingPackage(final String packageName, int affectedUser) { PackageManagerService.this.unsuspendForSuspendingPackage(packageName, affectedUser); } @Override public boolean isSuspendingAnyPackages(String suspendingPackage, int userId) { return PackageManagerService.this.isSuspendingAnyPackages(suspendingPackage, userId); } } @GuardedBy("mLock") services/core/java/com/android/server/pm/PackageSettingBase.java +5 −0 Original line number Diff line number Diff line Loading @@ -422,6 +422,11 @@ public abstract class PackageSettingBase extends SettingBase { return readUserState(userId).suspended; } boolean isSuspendedBy(String suspendingPackage, int userId) { final PackageUserState state = readUserState(userId); return state.suspendParams != null && state.suspendParams.containsKey(suspendingPackage); } void addOrUpdateSuspension(String suspendingPackage, SuspendDialogInfo dialogInfo, PersistableBundle appExtras, PersistableBundle launcherExtras, int userId) { final PackageUserState existingUserState = modifyUserState(userId); Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +43 −12 Original line number Diff line number Diff line Loading @@ -2755,7 +2755,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Slog.i(LOG_TAG, "Giving the PO additional power..."); markProfileOwnerOnOrganizationOwnedDeviceUncheckedLocked(poAdminComponent, poUserId); Slog.i(LOG_TAG, "Migrating DO policies to PO..."); moveDoPoliciesToProfileParentAdmin(doAdmin, poAdmin.getParentActiveAdmin()); moveDoPoliciesToProfileParentAdminLocked(doAdmin, poAdmin.getParentActiveAdmin()); migratePersonalAppSuspensionLocked(doUserId, poUserId, poAdmin); saveSettingsLocked(poUserId); Slog.i(LOG_TAG, "Clearing the DO..."); final ComponentName doAdminReceiver = doAdmin.info.getComponent(); Loading @@ -2775,6 +2776,25 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .write(); } @GuardedBy("getLockObject()") private void migratePersonalAppSuspensionLocked( int doUserId, int poUserId, ActiveAdmin poAdmin) { final PackageManagerInternal pmi = mInjector.getPackageManagerInternal(); if (!pmi.isSuspendingAnyPackages(PLATFORM_PACKAGE_NAME, doUserId)) { Slog.i(LOG_TAG, "DO is not suspending any apps."); return; } if (getTargetSdk(poAdmin.info.getPackageName(), poUserId) >= Build.VERSION_CODES.R) { Slog.i(LOG_TAG, "PO is targeting R+, keeping personal apps suspended."); getUserData(doUserId).mAppsSuspended = true; poAdmin.mSuspendPersonalApps = true; } else { Slog.i(LOG_TAG, "PO isn't targeting R+, unsuspending personal apps."); pmi.unsuspendForSuspendingPackage(PLATFORM_PACKAGE_NAME, doUserId); } } private void uninstallOrDisablePackage(String packageName, int userHandle) { final ApplicationInfo appInfo; try { Loading Loading @@ -2816,7 +2836,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { pi.uninstall(packageName, 0 /* flags */, new IntentSender((IIntentSender) mLocalSender)); } private void moveDoPoliciesToProfileParentAdmin(ActiveAdmin doAdmin, ActiveAdmin parentAdmin) { @GuardedBy("getLockObject()") private void moveDoPoliciesToProfileParentAdminLocked( ActiveAdmin doAdmin, ActiveAdmin parentAdmin) { // The following policies can be already controlled via parent instance, skip if so. if (parentAdmin.mPasswordPolicy.quality == PASSWORD_QUALITY_UNSPECIFIED) { parentAdmin.mPasswordPolicy = doAdmin.mPasswordPolicy; Loading Loading @@ -16147,25 +16169,34 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } Slog.i(LOG_TAG, String.format("%s personal apps for user %d", suspended ? "Suspending" : "Unsuspending", userId)); if (suspended) { suspendPersonalAppsInPackageManager(userId); } else { mInjector.getPackageManagerInternal().unsuspendForSuspendingPackage( PLATFORM_PACKAGE_NAME, userId); } synchronized (getLockObject()) { getUserData(userId).mAppsSuspended = suspended; saveSettingsLocked(userId); } } private void suspendPersonalAppsInPackageManager(int userId) { mInjector.binderWithCleanCallingIdentity(() -> { try { final String[] appsToSuspend = mInjector.getPersonalAppsForSuspension(userId); final String[] failedPackages = mIPackageManager.setPackagesSuspendedAsUser( appsToSuspend, suspended, null, null, null, PLATFORM_PACKAGE_NAME, userId); if (!ArrayUtils.isEmpty(failedPackages)) { Slog.wtf(LOG_TAG, String.format("Failed to %s packages: %s", suspended ? "suspend" : "unsuspend", String.join(",", failedPackages))); final String[] failedApps = mIPackageManager.setPackagesSuspendedAsUser( appsToSuspend, true, null, null, null, PLATFORM_PACKAGE_NAME, userId); if (!ArrayUtils.isEmpty(failedApps)) { Slog.wtf(LOG_TAG, "Failed to suspend apps: " + String.join(",", failedApps)); } } catch (RemoteException re) { // Shouldn't happen. Slog.e(LOG_TAG, "Failed talking to the package manager", re); } }); synchronized (getLockObject()) { getUserData(userId).mAppsSuspended = suspended; saveSettingsLocked(userId); } } @GuardedBy("getLockObject()") services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java +77 −11 Original line number Diff line number Diff line Loading @@ -18,17 +18,24 @@ package com.android.server.devicepolicy; import static android.os.UserHandle.USER_SYSTEM; import static com.android.server.devicepolicy.DpmTestUtils.writeInputStreamToFile; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import static org.junit.Assert.assertArrayEquals; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; import android.content.ComponentName; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; Loading Loading @@ -354,8 +361,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { prepareAdmin1AsDo(); prepareAdminAnotherPackageAsPo(COPE_PROFILE_USER_ID); final DevicePolicyManagerServiceTestable dpms; dpms = bootDpmsUp(); final DevicePolicyManagerServiceTestable dpms = bootDpmsUp(); // DO should still be DO since no migration should happen. assertTrue(dpms.mOwners.hasDeviceOwner()); Loading @@ -364,13 +370,12 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { @SmallTest public void testCompMigrationAffiliated() throws Exception { prepareAdmin1AsDo(); prepareAdmin1AsPo(COPE_PROFILE_USER_ID); prepareAdmin1AsPo(COPE_PROFILE_USER_ID, Build.VERSION_CODES.R); // Secure lock screen is needed for password policy APIs to work. when(getServices().lockPatternUtils.hasSecureLockScreen()).thenReturn(true); final DevicePolicyManagerServiceTestable dpms; dpms = bootDpmsUp(); final DevicePolicyManagerServiceTestable dpms = bootDpmsUp(); // DO should cease to be DO. assertFalse(dpms.mOwners.hasDeviceOwner()); Loading Loading @@ -408,6 +413,66 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { dpms.getProfileOwnerAdminLocked(COPE_PROFILE_USER_ID) .getEffectiveRestrictions() .containsKey(UserManager.DISALLOW_CONFIG_DATE_TIME)); assertEquals("Personal apps suspension wasn't migrated", DevicePolicyManager.PERSONAL_APPS_NOT_SUSPENDED, dpm.getPersonalAppsSuspendedReasons(admin1)); }); } @SmallTest public void testCompMigration_keepSuspendedAppsWhenDpcIsRPlus() throws Exception { prepareAdmin1AsDo(); prepareAdmin1AsPo(COPE_PROFILE_USER_ID, Build.VERSION_CODES.R); // Pretend some packages are suspended. when(getServices().packageManagerInternal.isSuspendingAnyPackages( PLATFORM_PACKAGE_NAME, USER_SYSTEM)).thenReturn(true); final DevicePolicyManagerServiceTestable dpms = bootDpmsUp(); verify(getServices().packageManagerInternal, never()) .unsuspendForSuspendingPackage(PLATFORM_PACKAGE_NAME, USER_SYSTEM); sendBroadcastWithUser(dpms, Intent.ACTION_USER_STARTED, USER_SYSTEM); // Verify that actual package suspension state is not modified after user start verify(getServices().packageManagerInternal, never()) .unsuspendForSuspendingPackage(PLATFORM_PACKAGE_NAME, USER_SYSTEM); verify(getServices().ipackageManager, never()).setPackagesSuspendedAsUser( any(), anyBoolean(), any(), any(), any(), any(), anyInt()); final DpmMockContext poContext = new DpmMockContext(getServices(), mRealTestContext); poContext.binder.callingUid = UserHandle.getUid(COPE_PROFILE_USER_ID, COPE_ADMIN1_APP_ID); runAsCaller(poContext, dpms, dpm -> { assertEquals("Personal apps suspension wasn't migrated", DevicePolicyManager.PERSONAL_APPS_SUSPENDED_EXPLICITLY, dpm.getPersonalAppsSuspendedReasons(admin1)); }); } @SmallTest public void testCompMigration_unsuspendAppsWhenDpcNotRPlus() throws Exception { prepareAdmin1AsDo(); prepareAdmin1AsPo(COPE_PROFILE_USER_ID, Build.VERSION_CODES.Q); // Pretend some packages are suspended. when(getServices().packageManagerInternal.isSuspendingAnyPackages( PLATFORM_PACKAGE_NAME, USER_SYSTEM)).thenReturn(true); final DevicePolicyManagerServiceTestable dpms = bootDpmsUp(); // Verify that apps get unsuspended. verify(getServices().packageManagerInternal) .unsuspendForSuspendingPackage(PLATFORM_PACKAGE_NAME, USER_SYSTEM); final DpmMockContext poContext = new DpmMockContext(getServices(), mRealTestContext); poContext.binder.callingUid = UserHandle.getUid(COPE_PROFILE_USER_ID, COPE_ADMIN1_APP_ID); runAsCaller(poContext, dpms, dpm -> { assertEquals("Personal apps weren't unsuspended", DevicePolicyManager.PERSONAL_APPS_NOT_SUSPENDED, dpm.getPersonalAppsSuspendedReasons(admin1)); }); } Loading Loading @@ -439,22 +504,23 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { .getAbsoluteFile()); } private void prepareAdmin1AsPo(int profileUserId) throws Exception { private void prepareAdmin1AsPo(int profileUserId, int targetSdk) throws Exception { preparePo(profileUserId, admin1, R.raw.comp_profile_owner_same_package, R.raw.comp_policies_profile_same_package, COPE_ADMIN1_APP_ID); R.raw.comp_policies_profile_same_package, COPE_ADMIN1_APP_ID, targetSdk); } private void prepareAdminAnotherPackageAsPo(int profileUserId) throws Exception { preparePo(profileUserId, adminAnotherPackage, R.raw.comp_profile_owner_another_package, R.raw.comp_policies_profile_another_package, COPE_ANOTHER_ADMIN_APP_ID); R.raw.comp_policies_profile_another_package, COPE_ANOTHER_ADMIN_APP_ID, Build.VERSION.SDK_INT); } private void preparePo(int profileUserId, ComponentName admin, int profileOwnerXmlResId, int policyXmlResId, int adminAppId) throws Exception { int policyXmlResId, int adminAppId, int targetSdk) throws Exception { final File profileDir = getServices().addUser(profileUserId, 0, UserManager.USER_TYPE_PROFILE_MANAGED, USER_SYSTEM /* profile group */); setUpPackageManagerForFakeAdmin( admin, UserHandle.getUid(profileUserId, adminAppId), admin1); setUpPackageManagerForFakeAdmin(admin, UserHandle.getUid(profileUserId, adminAppId), /* enabledSetting =*/ null, targetSdk, admin1); writeInputStreamToFile(getRawStream(policyXmlResId), (new File(profileDir, "device_policies.xml")).getAbsoluteFile()); writeInputStreamToFile(getRawStream(profileOwnerXmlResId), Loading Loading
services/core/java/android/content/pm/PackageManagerInternal.java +10 −0 Original line number Diff line number Diff line Loading @@ -988,4 +988,14 @@ public abstract class PackageManagerInternal { * Unblocks uninstall for all packages for the user. */ public abstract void clearBlockUninstallForUser(@UserIdInt int userId); /** * Unsuspends all packages suspended by the given package for the user. */ public abstract void unsuspendForSuspendingPackage(String suspendingPackage, int userId); /** * Returns {@code true} if the package is suspending any packages for the user. */ public abstract boolean isSuspendingAnyPackages(String suspendingPackage, int userId); }
services/core/java/com/android/server/pm/PackageManagerService.java +21 −1 Original line number Diff line number Diff line Loading @@ -13518,6 +13518,17 @@ public class PackageManagerService extends IPackageManager.Stub removeSuspensionsBySuspendingPackage(allPackages, suspendingPackage::equals, userId); } boolean isSuspendingAnyPackages(String suspendingPackage, int userId) { synchronized (mLock) { for (final PackageSetting ps : mSettings.mPackages.values()) { if (ps.isSuspendedBy(suspendingPackage, userId)) { return true; } } } return false; } /** * Removes any suspensions on given packages that were added by packages that pass the given * predicate. Loading Loading @@ -23913,7 +23924,6 @@ public class PackageManagerService extends IPackageManager.Stub callingUid); } @Override public boolean isPlatformSigned(String packageName) { PackageSetting packageSetting = mSettings.mPackages.get(packageName); Loading Loading @@ -25018,6 +25028,16 @@ public class PackageManagerService extends IPackageManager.Stub mSettings.writePackageRestrictionsLPr(userId); } } @Override public void unsuspendForSuspendingPackage(final String packageName, int affectedUser) { PackageManagerService.this.unsuspendForSuspendingPackage(packageName, affectedUser); } @Override public boolean isSuspendingAnyPackages(String suspendingPackage, int userId) { return PackageManagerService.this.isSuspendingAnyPackages(suspendingPackage, userId); } } @GuardedBy("mLock")
services/core/java/com/android/server/pm/PackageSettingBase.java +5 −0 Original line number Diff line number Diff line Loading @@ -422,6 +422,11 @@ public abstract class PackageSettingBase extends SettingBase { return readUserState(userId).suspended; } boolean isSuspendedBy(String suspendingPackage, int userId) { final PackageUserState state = readUserState(userId); return state.suspendParams != null && state.suspendParams.containsKey(suspendingPackage); } void addOrUpdateSuspension(String suspendingPackage, SuspendDialogInfo dialogInfo, PersistableBundle appExtras, PersistableBundle launcherExtras, int userId) { final PackageUserState existingUserState = modifyUserState(userId); Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +43 −12 Original line number Diff line number Diff line Loading @@ -2755,7 +2755,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Slog.i(LOG_TAG, "Giving the PO additional power..."); markProfileOwnerOnOrganizationOwnedDeviceUncheckedLocked(poAdminComponent, poUserId); Slog.i(LOG_TAG, "Migrating DO policies to PO..."); moveDoPoliciesToProfileParentAdmin(doAdmin, poAdmin.getParentActiveAdmin()); moveDoPoliciesToProfileParentAdminLocked(doAdmin, poAdmin.getParentActiveAdmin()); migratePersonalAppSuspensionLocked(doUserId, poUserId, poAdmin); saveSettingsLocked(poUserId); Slog.i(LOG_TAG, "Clearing the DO..."); final ComponentName doAdminReceiver = doAdmin.info.getComponent(); Loading @@ -2775,6 +2776,25 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .write(); } @GuardedBy("getLockObject()") private void migratePersonalAppSuspensionLocked( int doUserId, int poUserId, ActiveAdmin poAdmin) { final PackageManagerInternal pmi = mInjector.getPackageManagerInternal(); if (!pmi.isSuspendingAnyPackages(PLATFORM_PACKAGE_NAME, doUserId)) { Slog.i(LOG_TAG, "DO is not suspending any apps."); return; } if (getTargetSdk(poAdmin.info.getPackageName(), poUserId) >= Build.VERSION_CODES.R) { Slog.i(LOG_TAG, "PO is targeting R+, keeping personal apps suspended."); getUserData(doUserId).mAppsSuspended = true; poAdmin.mSuspendPersonalApps = true; } else { Slog.i(LOG_TAG, "PO isn't targeting R+, unsuspending personal apps."); pmi.unsuspendForSuspendingPackage(PLATFORM_PACKAGE_NAME, doUserId); } } private void uninstallOrDisablePackage(String packageName, int userHandle) { final ApplicationInfo appInfo; try { Loading Loading @@ -2816,7 +2836,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { pi.uninstall(packageName, 0 /* flags */, new IntentSender((IIntentSender) mLocalSender)); } private void moveDoPoliciesToProfileParentAdmin(ActiveAdmin doAdmin, ActiveAdmin parentAdmin) { @GuardedBy("getLockObject()") private void moveDoPoliciesToProfileParentAdminLocked( ActiveAdmin doAdmin, ActiveAdmin parentAdmin) { // The following policies can be already controlled via parent instance, skip if so. if (parentAdmin.mPasswordPolicy.quality == PASSWORD_QUALITY_UNSPECIFIED) { parentAdmin.mPasswordPolicy = doAdmin.mPasswordPolicy; Loading Loading @@ -16147,25 +16169,34 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } Slog.i(LOG_TAG, String.format("%s personal apps for user %d", suspended ? "Suspending" : "Unsuspending", userId)); if (suspended) { suspendPersonalAppsInPackageManager(userId); } else { mInjector.getPackageManagerInternal().unsuspendForSuspendingPackage( PLATFORM_PACKAGE_NAME, userId); } synchronized (getLockObject()) { getUserData(userId).mAppsSuspended = suspended; saveSettingsLocked(userId); } } private void suspendPersonalAppsInPackageManager(int userId) { mInjector.binderWithCleanCallingIdentity(() -> { try { final String[] appsToSuspend = mInjector.getPersonalAppsForSuspension(userId); final String[] failedPackages = mIPackageManager.setPackagesSuspendedAsUser( appsToSuspend, suspended, null, null, null, PLATFORM_PACKAGE_NAME, userId); if (!ArrayUtils.isEmpty(failedPackages)) { Slog.wtf(LOG_TAG, String.format("Failed to %s packages: %s", suspended ? "suspend" : "unsuspend", String.join(",", failedPackages))); final String[] failedApps = mIPackageManager.setPackagesSuspendedAsUser( appsToSuspend, true, null, null, null, PLATFORM_PACKAGE_NAME, userId); if (!ArrayUtils.isEmpty(failedApps)) { Slog.wtf(LOG_TAG, "Failed to suspend apps: " + String.join(",", failedApps)); } } catch (RemoteException re) { // Shouldn't happen. Slog.e(LOG_TAG, "Failed talking to the package manager", re); } }); synchronized (getLockObject()) { getUserData(userId).mAppsSuspended = suspended; saveSettingsLocked(userId); } } @GuardedBy("getLockObject()")
services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java +77 −11 Original line number Diff line number Diff line Loading @@ -18,17 +18,24 @@ package com.android.server.devicepolicy; import static android.os.UserHandle.USER_SYSTEM; import static com.android.server.devicepolicy.DpmTestUtils.writeInputStreamToFile; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import static org.junit.Assert.assertArrayEquals; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; import android.content.ComponentName; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; Loading Loading @@ -354,8 +361,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { prepareAdmin1AsDo(); prepareAdminAnotherPackageAsPo(COPE_PROFILE_USER_ID); final DevicePolicyManagerServiceTestable dpms; dpms = bootDpmsUp(); final DevicePolicyManagerServiceTestable dpms = bootDpmsUp(); // DO should still be DO since no migration should happen. assertTrue(dpms.mOwners.hasDeviceOwner()); Loading @@ -364,13 +370,12 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { @SmallTest public void testCompMigrationAffiliated() throws Exception { prepareAdmin1AsDo(); prepareAdmin1AsPo(COPE_PROFILE_USER_ID); prepareAdmin1AsPo(COPE_PROFILE_USER_ID, Build.VERSION_CODES.R); // Secure lock screen is needed for password policy APIs to work. when(getServices().lockPatternUtils.hasSecureLockScreen()).thenReturn(true); final DevicePolicyManagerServiceTestable dpms; dpms = bootDpmsUp(); final DevicePolicyManagerServiceTestable dpms = bootDpmsUp(); // DO should cease to be DO. assertFalse(dpms.mOwners.hasDeviceOwner()); Loading Loading @@ -408,6 +413,66 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { dpms.getProfileOwnerAdminLocked(COPE_PROFILE_USER_ID) .getEffectiveRestrictions() .containsKey(UserManager.DISALLOW_CONFIG_DATE_TIME)); assertEquals("Personal apps suspension wasn't migrated", DevicePolicyManager.PERSONAL_APPS_NOT_SUSPENDED, dpm.getPersonalAppsSuspendedReasons(admin1)); }); } @SmallTest public void testCompMigration_keepSuspendedAppsWhenDpcIsRPlus() throws Exception { prepareAdmin1AsDo(); prepareAdmin1AsPo(COPE_PROFILE_USER_ID, Build.VERSION_CODES.R); // Pretend some packages are suspended. when(getServices().packageManagerInternal.isSuspendingAnyPackages( PLATFORM_PACKAGE_NAME, USER_SYSTEM)).thenReturn(true); final DevicePolicyManagerServiceTestable dpms = bootDpmsUp(); verify(getServices().packageManagerInternal, never()) .unsuspendForSuspendingPackage(PLATFORM_PACKAGE_NAME, USER_SYSTEM); sendBroadcastWithUser(dpms, Intent.ACTION_USER_STARTED, USER_SYSTEM); // Verify that actual package suspension state is not modified after user start verify(getServices().packageManagerInternal, never()) .unsuspendForSuspendingPackage(PLATFORM_PACKAGE_NAME, USER_SYSTEM); verify(getServices().ipackageManager, never()).setPackagesSuspendedAsUser( any(), anyBoolean(), any(), any(), any(), any(), anyInt()); final DpmMockContext poContext = new DpmMockContext(getServices(), mRealTestContext); poContext.binder.callingUid = UserHandle.getUid(COPE_PROFILE_USER_ID, COPE_ADMIN1_APP_ID); runAsCaller(poContext, dpms, dpm -> { assertEquals("Personal apps suspension wasn't migrated", DevicePolicyManager.PERSONAL_APPS_SUSPENDED_EXPLICITLY, dpm.getPersonalAppsSuspendedReasons(admin1)); }); } @SmallTest public void testCompMigration_unsuspendAppsWhenDpcNotRPlus() throws Exception { prepareAdmin1AsDo(); prepareAdmin1AsPo(COPE_PROFILE_USER_ID, Build.VERSION_CODES.Q); // Pretend some packages are suspended. when(getServices().packageManagerInternal.isSuspendingAnyPackages( PLATFORM_PACKAGE_NAME, USER_SYSTEM)).thenReturn(true); final DevicePolicyManagerServiceTestable dpms = bootDpmsUp(); // Verify that apps get unsuspended. verify(getServices().packageManagerInternal) .unsuspendForSuspendingPackage(PLATFORM_PACKAGE_NAME, USER_SYSTEM); final DpmMockContext poContext = new DpmMockContext(getServices(), mRealTestContext); poContext.binder.callingUid = UserHandle.getUid(COPE_PROFILE_USER_ID, COPE_ADMIN1_APP_ID); runAsCaller(poContext, dpms, dpm -> { assertEquals("Personal apps weren't unsuspended", DevicePolicyManager.PERSONAL_APPS_NOT_SUSPENDED, dpm.getPersonalAppsSuspendedReasons(admin1)); }); } Loading Loading @@ -439,22 +504,23 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { .getAbsoluteFile()); } private void prepareAdmin1AsPo(int profileUserId) throws Exception { private void prepareAdmin1AsPo(int profileUserId, int targetSdk) throws Exception { preparePo(profileUserId, admin1, R.raw.comp_profile_owner_same_package, R.raw.comp_policies_profile_same_package, COPE_ADMIN1_APP_ID); R.raw.comp_policies_profile_same_package, COPE_ADMIN1_APP_ID, targetSdk); } private void prepareAdminAnotherPackageAsPo(int profileUserId) throws Exception { preparePo(profileUserId, adminAnotherPackage, R.raw.comp_profile_owner_another_package, R.raw.comp_policies_profile_another_package, COPE_ANOTHER_ADMIN_APP_ID); R.raw.comp_policies_profile_another_package, COPE_ANOTHER_ADMIN_APP_ID, Build.VERSION.SDK_INT); } private void preparePo(int profileUserId, ComponentName admin, int profileOwnerXmlResId, int policyXmlResId, int adminAppId) throws Exception { int policyXmlResId, int adminAppId, int targetSdk) throws Exception { final File profileDir = getServices().addUser(profileUserId, 0, UserManager.USER_TYPE_PROFILE_MANAGED, USER_SYSTEM /* profile group */); setUpPackageManagerForFakeAdmin( admin, UserHandle.getUid(profileUserId, adminAppId), admin1); setUpPackageManagerForFakeAdmin(admin, UserHandle.getUid(profileUserId, adminAppId), /* enabledSetting =*/ null, targetSdk, admin1); writeInputStreamToFile(getRawStream(policyXmlResId), (new File(profileDir, "device_policies.xml")).getAbsoluteFile()); writeInputStreamToFile(getRawStream(profileOwnerXmlResId), Loading