diff options
11 files changed, 326 insertions, 41 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 24d3bb63fe7e..0def81445d07 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1095,7 +1095,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { String globalProxySpec = null; String globalProxyExclusionList = null; - ArrayMap<String, TrustAgentInfo> trustAgentInfos = new ArrayMap<>(); + @NonNull ArrayMap<String, TrustAgentInfo> trustAgentInfos = new ArrayMap<>(); List<String> crossProfileWidgetProviders; @@ -1650,6 +1650,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } + @NonNull private ArrayMap<String, TrustAgentInfo> getAllTrustAgentInfos( XmlPullParser parser, String tag) throws XmlPullParserException, IOException { int outerDepthDAM = parser.getDepth(); @@ -2434,11 +2435,133 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { migrateUserRestrictionsIfNecessaryLocked(); // TODO PO may not have a class name either due to b/17652534. Address that too. - updateDeviceOwnerLocked(); } } + /** + * Checks if the device is in COMP mode, and if so migrates it to managed profile on a + * corporate owned device. + */ + @GuardedBy("getLockObject()") + private void maybeMigrateToProfileOnOrganizationOwnedDeviceLocked() { + logIfVerbose("Checking whether we need to migrate COMP "); + final int doUserId = mOwners.getDeviceOwnerUserId(); + if (doUserId == UserHandle.USER_NULL) { + logIfVerbose("No DO found, skipping migration."); + return; + } + + final List<UserInfo> profiles = mUserManager.getProfiles(doUserId); + if (profiles.size() != 2) { + if (profiles.size() == 1) { + logIfVerbose("Profile not found, skipping migration."); + } else { + Slog.wtf(LOG_TAG, "Found " + profiles.size() + " profiles, skipping migration"); + } + return; + } + + final int poUserId = getManagedUserId(doUserId); + if (poUserId < 0) { + Slog.wtf(LOG_TAG, "Found DO and a profile, but it is not managed, skipping migration"); + return; + } + + final ActiveAdmin doAdmin = getDeviceOwnerAdminLocked(); + final ActiveAdmin poAdmin = getProfileOwnerAdminLocked(poUserId); + if (doAdmin == null || poAdmin == null) { + Slog.wtf(LOG_TAG, "Failed to get either PO or DO admin, aborting migration."); + return; + } + + final ComponentName doAdminComponent = mOwners.getDeviceOwnerComponent(); + final ComponentName poAdminComponent = mOwners.getProfileOwnerComponent(poUserId); + if (doAdminComponent == null || poAdminComponent == null) { + Slog.wtf(LOG_TAG, "Cannot find PO or DO component name, aborting migration."); + return; + } + if (!doAdminComponent.getPackageName().equals(poAdminComponent.getPackageName())) { + Slog.e(LOG_TAG, "DO and PO are different packages, aborting migration."); + return; + } + + Slog.i(LOG_TAG, String.format( + "Migrating COMP to PO on a corp owned device; primary user: %d; profile: %d", + doUserId, poUserId)); + + 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()); + saveSettingsLocked(poUserId); + Slog.i(LOG_TAG, "Clearing the DO..."); + final ComponentName doAdminReceiver = doAdmin.info.getComponent(); + clearDeviceOwnerLocked(doAdmin, doUserId); + // TODO(b/143516163): If we have a power cut here, we might leave active admin. Consider if + // it is worth the complexity to make it more robust. + Slog.i(LOG_TAG, "Removing admin artifacts..."); + // TODO(b/143516163): Clean up application restrictions in UserManager. + removeAdminArtifacts(doAdminReceiver, doUserId); + Slog.i(LOG_TAG, "Migration complete."); + + // Note: KeyChain keys are not removed and will remain accessible for the apps that have + // been given grants to use them. + } + + private void moveDoPoliciesToProfileParentAdmin(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; + } + if (parentAdmin.passwordHistoryLength == ActiveAdmin.DEF_PASSWORD_HISTORY_LENGTH) { + parentAdmin.passwordHistoryLength = doAdmin.passwordHistoryLength; + } + if (parentAdmin.passwordExpirationTimeout == ActiveAdmin.DEF_PASSWORD_HISTORY_LENGTH) { + parentAdmin.passwordExpirationTimeout = doAdmin.passwordExpirationTimeout; + } + if (parentAdmin.maximumFailedPasswordsForWipe + == ActiveAdmin.DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) { + parentAdmin.maximumFailedPasswordsForWipe = doAdmin.maximumFailedPasswordsForWipe; + } + if (parentAdmin.maximumTimeToUnlock == ActiveAdmin.DEF_MAXIMUM_TIME_TO_UNLOCK) { + parentAdmin.maximumTimeToUnlock = doAdmin.maximumTimeToUnlock; + } + if (parentAdmin.strongAuthUnlockTimeout + == DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS) { + parentAdmin.strongAuthUnlockTimeout = doAdmin.strongAuthUnlockTimeout; + } + parentAdmin.disabledKeyguardFeatures |= + doAdmin.disabledKeyguardFeatures & PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER; + + parentAdmin.trustAgentInfos.putAll(doAdmin.trustAgentInfos); + + // The following policies weren't available to PO, but will be available after migration. + parentAdmin.disableCamera = doAdmin.disableCamera; + + // TODO(b/143516163): Uncomment once corresponding APIs are available via parent instance. + // parentAdmin.disableScreenCapture = doAdmin.disableScreenCapture; + // parentAdmin.accountTypesWithManagementDisabled.addAll( + // doAdmin.accountTypesWithManagementDisabled); + + moveDoUserRestrictionsToCopeParent(doAdmin, parentAdmin); + + // TODO(b/143516163): migrate network and security logging state, currently they are + // turned off when DO is removed. + } + + private void moveDoUserRestrictionsToCopeParent(ActiveAdmin doAdmin, ActiveAdmin parentAdmin) { + if (doAdmin.userRestrictions == null) { + return; + } + for (final String restriction : doAdmin.userRestrictions.keySet()) { + if (UserRestrictionsUtils.canProfileOwnerOfOrganizationOwnedDeviceChange(restriction)) { + parentAdmin.userRestrictions.putBoolean( + restriction, doAdmin.userRestrictions.getBoolean(restriction)); + } + } + } + /** Apply default restrictions that haven't been applied to profile owners yet. */ private void maybeSetDefaultProfileOwnerUserRestrictions() { synchronized (getLockObject()) { @@ -3625,6 +3748,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { break; case SystemService.PHASE_ACTIVITY_MANAGER_READY: maybeStartSecurityLogMonitorOnActivityManagerReady(); + synchronized (getLockObject()) { + maybeMigrateToProfileOnOrganizationOwnedDeviceLocked(); + } break; case SystemService.PHASE_BOOT_COMPLETED: ensureDeviceOwnerUserStarted(); // TODO Consider better place to do this. @@ -12923,37 +13049,43 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // Grant access under lock. synchronized (getLockObject()) { - // Sanity check: Make sure that the user has a profile owner and that the specified - // component is the profile owner of that user. - if (!isProfileOwner(who, userId)) { - throw new IllegalArgumentException(String.format( - "Component %s is not a Profile Owner of user %d", - who.flattenToString(), userId)); - } + markProfileOwnerOnOrganizationOwnedDeviceUncheckedLocked(who, userId); + } + } - Slog.i(LOG_TAG, String.format( - "Marking %s as profile owner on organization-owned device for user %d", + @GuardedBy("getLockObject()") + private void markProfileOwnerOnOrganizationOwnedDeviceUncheckedLocked( + ComponentName who, int userId) { + // Sanity check: Make sure that the user has a profile owner and that the specified + // component is the profile owner of that user. + if (!isProfileOwner(who, userId)) { + throw new IllegalArgumentException(String.format( + "Component %s is not a Profile Owner of user %d", who.flattenToString(), userId)); + } - // First, set restriction on removing the profile. - mInjector.binderWithCleanCallingIdentity(() -> { - // Clear restriction as user. - UserHandle parentUser = mUserManager.getProfileParent(UserHandle.of(userId)); - if (!parentUser.isSystem()) { - throw new IllegalStateException( - String.format("Only the profile owner of a managed profile on the" + Slog.i(LOG_TAG, String.format( + "Marking %s as profile owner on organization-owned device for user %d", + who.flattenToString(), userId)); + + // First, set restriction on removing the profile. + mInjector.binderWithCleanCallingIdentity(() -> { + // Clear restriction as user. + final UserHandle parentUser = mUserManager.getProfileParent(UserHandle.of(userId)); + if (!parentUser.isSystem()) { + throw new IllegalStateException( + String.format("Only the profile owner of a managed profile on the" + " primary user can be granted access to device identifiers, not" + " on user %d", parentUser.getIdentifier())); - } + } - mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, true, - parentUser); - }); + mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, true, + parentUser); + }); - // markProfileOwnerOfOrganizationOwnedDevice will trigger writing of the profile owner - // data, no need to do it manually. - mOwners.markProfileOwnerOfOrganizationOwnedDevice(userId); - } + // markProfileOwnerOfOrganizationOwnedDevice will trigger writing of the profile owner + // data, no need to do it manually. + mOwners.markProfileOwnerOfOrganizationOwnedDevice(userId); } private void pushMeteredDisabledPackagesLocked(int userId) { @@ -14917,4 +15049,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return packages == null ? Collections.EMPTY_LIST : packages; } } + + private void logIfVerbose(String message) { + if (VERBOSE_LOG) { + Slog.d(LOG_TAG, message); + } + } } diff --git a/services/tests/servicestests/res/raw/comp_device_owner.xml b/services/tests/servicestests/res/raw/comp_device_owner.xml new file mode 100644 index 000000000000..0a10242ec59d --- /dev/null +++ b/services/tests/servicestests/res/raw/comp_device_owner.xml @@ -0,0 +1,8 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes' ?> +<root> + <device-owner package="com.android.frameworks.servicestests" + name="" + component="com.android.frameworks.servicestests/com.android.server.devicepolicy.DummyDeviceAdmins$Admin1" + userRestrictionsMigrated="true" /> + <device-owner-context userId="0" /> +</root> diff --git a/services/tests/servicestests/res/raw/comp_policies_primary.xml b/services/tests/servicestests/res/raw/comp_policies_primary.xml new file mode 100644 index 000000000000..1e1a0eff874c --- /dev/null +++ b/services/tests/servicestests/res/raw/comp_policies_primary.xml @@ -0,0 +1,7 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes' ?> +<policies setup-complete="true" provisioning-state="3"> + <admin name="com.android.frameworks.servicestests/com.android.server.devicepolicy.DummyDeviceAdmins$Admin1"> + <policies flags="991"/> + <password-history-length value="33" /> + </admin> +</policies> diff --git a/services/tests/servicestests/res/raw/comp_policies_profile_another_package.xml b/services/tests/servicestests/res/raw/comp_policies_profile_another_package.xml new file mode 100644 index 000000000000..141315e6c2d2 --- /dev/null +++ b/services/tests/servicestests/res/raw/comp_policies_profile_another_package.xml @@ -0,0 +1,6 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes' ?> +<policies setup-complete="true" provisioning-state="3"> + <admin name="com.another.package.name/whatever.random.class"> + <policies flags="991"/> + </admin> +</policies> diff --git a/services/tests/servicestests/res/raw/comp_policies_profile_same_package.xml b/services/tests/servicestests/res/raw/comp_policies_profile_same_package.xml new file mode 100644 index 000000000000..c874dcca2c73 --- /dev/null +++ b/services/tests/servicestests/res/raw/comp_policies_profile_same_package.xml @@ -0,0 +1,6 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes' ?> +<policies setup-complete="true" provisioning-state="3"> + <admin name="com.android.frameworks.servicestests/com.android.server.devicepolicy.DummyDeviceAdmins$Admin1"> + <policies flags="991"/> + </admin> +</policies> diff --git a/services/tests/servicestests/res/raw/comp_profile_owner_another_package.xml b/services/tests/servicestests/res/raw/comp_profile_owner_another_package.xml new file mode 100644 index 000000000000..d65ba7826fef --- /dev/null +++ b/services/tests/servicestests/res/raw/comp_profile_owner_another_package.xml @@ -0,0 +1,7 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes' ?> +<root> + <profile-owner package="com.another.package.name" + name="com.another.package.name" + component="com.another.package.name/whatever.random.class" + userRestrictionsMigrated="true"/> +</root> diff --git a/services/tests/servicestests/res/raw/comp_profile_owner_same_package.xml b/services/tests/servicestests/res/raw/comp_profile_owner_same_package.xml new file mode 100644 index 000000000000..7f98c91c0a94 --- /dev/null +++ b/services/tests/servicestests/res/raw/comp_profile_owner_same_package.xml @@ -0,0 +1,7 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes' ?> +<root> + <profile-owner package="com.android.frameworks.servicestests" + name="com.android.frameworks.servicestests" + component="com.android.frameworks.servicestests/com.android.server.devicepolicy.DummyDeviceAdmins$Admin1" + userRestrictionsMigrated="true"/> +</root> diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java index 5f1f3083361b..46b83713c159 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java @@ -15,6 +15,10 @@ */ package com.android.server.devicepolicy; +import static android.os.UserHandle.USER_SYSTEM; + +import static com.android.server.devicepolicy.DpmTestUtils.writeInputStreamToFile; + import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; @@ -22,12 +26,14 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.when; import android.app.admin.DevicePolicyManagerInternal; +import android.content.ComponentName; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; +import com.android.frameworks.servicestests.R; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.devicepolicy.DevicePolicyManagerServiceTestable.OwnersTestable; @@ -37,9 +43,13 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +// TODO (b/143516163): Fix old test cases and put into presubmit. public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { private static final String USER_TYPE_EMPTY = ""; + private static final int COPE_ADMIN1_APP_ID = 123; + private static final int COPE_ANOTHER_ADMIN_APP_ID = 125; + private static final int COPE_PROFILE_USER_ID = 11; private DpmMockContext mContext; @@ -85,7 +95,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { // Set up UserManager when(getServices().userManagerInternal.getBaseUserRestrictions( - eq(UserHandle.USER_SYSTEM))).thenReturn(DpmTestUtils.newRestrictions( + eq(USER_SYSTEM))).thenReturn(DpmTestUtils.newRestrictions( UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_RECORD_AUDIO)); @@ -137,7 +147,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { } assertTrue(dpms.mOwners.hasDeviceOwner()); - assertFalse(dpms.mOwners.hasProfileOwner(UserHandle.USER_SYSTEM)); + assertFalse(dpms.mOwners.hasProfileOwner(USER_SYSTEM)); assertTrue(dpms.mOwners.hasProfileOwner(10)); assertTrue(dpms.mOwners.hasProfileOwner(11)); assertFalse(dpms.mOwners.hasProfileOwner(12)); @@ -145,7 +155,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { // Now all information should be migrated. assertFalse(dpms.mOwners.getDeviceOwnerUserRestrictionsNeedsMigration()); assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration( - UserHandle.USER_SYSTEM)); + USER_SYSTEM)); assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(10)); assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(11)); assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(12)); @@ -155,7 +165,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { DpmTestUtils.newRestrictions( UserManager.DISALLOW_RECORD_AUDIO ), - newBaseRestrictions.get(UserHandle.USER_SYSTEM)); + newBaseRestrictions.get(USER_SYSTEM)); DpmTestUtils.assertRestrictions( DpmTestUtils.newRestrictions( @@ -214,7 +224,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { // Set up UserManager when(getServices().userManagerInternal.getBaseUserRestrictions( - eq(UserHandle.USER_SYSTEM))).thenReturn(DpmTestUtils.newRestrictions( + eq(USER_SYSTEM))).thenReturn(DpmTestUtils.newRestrictions( UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_RECORD_AUDIO, UserManager.DISALLOW_SMS, @@ -249,19 +259,19 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { mContext.binder.restoreCallingIdentity(ident); } assertFalse(dpms.mOwners.hasDeviceOwner()); - assertTrue(dpms.mOwners.hasProfileOwner(UserHandle.USER_SYSTEM)); + assertTrue(dpms.mOwners.hasProfileOwner(USER_SYSTEM)); // Now all information should be migrated. assertFalse(dpms.mOwners.getDeviceOwnerUserRestrictionsNeedsMigration()); assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration( - UserHandle.USER_SYSTEM)); + USER_SYSTEM)); // Check the new base restrictions. DpmTestUtils.assertRestrictions( DpmTestUtils.newRestrictions( UserManager.DISALLOW_RECORD_AUDIO ), - newBaseRestrictions.get(UserHandle.USER_SYSTEM)); + newBaseRestrictions.get(USER_SYSTEM)); // Check the new owner restrictions. DpmTestUtils.assertRestrictions( @@ -270,7 +280,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { UserManager.DISALLOW_SMS, UserManager.DISALLOW_OUTGOING_CALLS ), - dpms.getProfileOwnerAdminLocked(UserHandle.USER_SYSTEM).ensureUserRestrictions()); + dpms.getProfileOwnerAdminLocked(USER_SYSTEM).ensureUserRestrictions()); } // Test setting default restrictions for managed profile. @@ -332,4 +342,92 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { assertEquals(alreadySet.size(), 1); assertTrue(alreadySet.contains(UserManager.DISALLOW_BLUETOOTH_SHARING)); } + + public void testCompMigrationUnAffiliated_skipped() throws Exception { + prepareAdmin1AsDo(); + prepareAdminAnotherPackageAsPo(COPE_PROFILE_USER_ID); + + final DevicePolicyManagerServiceTestable dpms; + dpms = bootDpmsUp(); + + // DO should still be DO since no migration should happen. + assertTrue(dpms.mOwners.hasDeviceOwner()); + } + + public void testCompMigrationAffiliated() throws Exception { + prepareAdmin1AsDo(); + prepareAdmin1AsPo(COPE_PROFILE_USER_ID); + + // Secure lock screen is needed for password policy APIs to work. + when(getServices().lockPatternUtils.hasSecureLockScreen()).thenReturn(true); + + final DevicePolicyManagerServiceTestable dpms; + dpms = bootDpmsUp(); + + // DO should cease to be DO. + assertFalse(dpms.mOwners.hasDeviceOwner()); + + final DpmMockContext poContext = new DpmMockContext(getServices(), mRealTestContext); + poContext.binder.callingUid = UserHandle.getUid(COPE_PROFILE_USER_ID, COPE_ADMIN1_APP_ID); + + runAsCaller(poContext, dpms, dpm -> { + // Check that DO policy is now set on parent instance. + assertEquals(33, dpm.getParentProfileInstance(admin1).getPasswordHistoryLength(admin1)); + // And NOT set on profile instance. + assertEquals(0, dpm.getPasswordHistoryLength(admin1)); + + // TODO(b/143516163): verify more policies. + }); + } + + private DevicePolicyManagerServiceTestable bootDpmsUp() { + DevicePolicyManagerServiceTestable dpms; + final long ident = mContext.binder.clearCallingIdentity(); + try { + LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); + + dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext); + + dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY); + dpms.systemReady(SystemService.PHASE_ACTIVITY_MANAGER_READY); + dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED); + } finally { + mContext.binder.restoreCallingIdentity(ident); + } + return dpms; + } + + private void prepareAdmin1AsDo() throws Exception { + setUpPackageManagerForAdmin(admin1, UserHandle.getUid(USER_SYSTEM, COPE_ADMIN1_APP_ID)); + final int xmlResource = R.raw.comp_policies_primary; + writeInputStreamToFile(getRawStream(xmlResource), + (new File(getServices().systemUserDataDir, "device_policies.xml")) + .getAbsoluteFile()); + writeInputStreamToFile(getRawStream(R.raw.comp_device_owner), + (new File(getServices().dataDir, "device_owner_2.xml")) + .getAbsoluteFile()); + } + + private void prepareAdmin1AsPo(int profileUserId) throws Exception { + preparePo(profileUserId, admin1, R.raw.comp_profile_owner_same_package, + R.raw.comp_policies_profile_same_package, COPE_ADMIN1_APP_ID); + } + + 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); + } + + private void preparePo(int profileUserId, ComponentName admin, int profileOwnerXmlResId, + int policyXmlResId, int adminAppId) 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); + writeInputStreamToFile(getRawStream(policyXmlResId), + (new File(profileDir, "device_policies.xml")).getAbsoluteFile()); + writeInputStreamToFile(getRawStream(profileOwnerXmlResId), + (new File(profileDir, "profile_owner.xml")).getAbsoluteFile()); + } + } diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 45729e5fd41f..c4d0f50fa308 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -58,7 +58,6 @@ import static org.mockito.hamcrest.MockitoHamcrest.argThat; import static org.testng.Assert.assertThrows; import android.Manifest.permission; -import android.annotation.RawRes; import android.app.Activity; import android.app.AppOpsManager; import android.app.Notification; @@ -112,7 +111,6 @@ import org.mockito.internal.util.collections.Sets; import org.mockito.stubbing.Answer; import java.io.File; -import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -5783,10 +5781,6 @@ public class DevicePolicyManagerTest extends DpmTestBase { return new File(parentDir, "device_policies.xml"); } - private InputStream getRawStream(@RawRes int id) { - return mRealTestContext.getResources().openRawResource(id); - } - private void setUserSetupCompleteForUser(boolean isUserSetupComplete, int userhandle) { when(getServices().settings.settingsSecureGetIntForUser(Settings.Secure.USER_SETUP_COMPLETE, 0, userhandle)).thenReturn(isUserSetupComplete ? 1 : 0); diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java index a34c2ff8ce07..9a1a5fbfd186 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java @@ -24,6 +24,7 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; +import android.annotation.RawRes; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; @@ -36,6 +37,7 @@ import android.content.pm.ResolveInfo; import android.os.UserHandle; import android.test.AndroidTestCase; +import java.io.InputStream; import java.util.List; public abstract class DpmTestBase extends AndroidTestCase { @@ -256,4 +258,8 @@ public abstract class DpmTestBase extends AndroidTestCase { invocation -> invocation.getArguments()[1] ); } + + protected InputStream getRawStream(@RawRes int id) { + return mRealTestContext.getResources().openRawResource(id); + } } diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java index 6c2c1446a459..068daf5ee310 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java @@ -15,6 +15,7 @@ */ package com.android.server.devicepolicy; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -236,6 +237,13 @@ public class MockSystemServices { return ui == null ? null : getUserInfo(ui.profileGroupId); } ); + when(userManager.getProfileParent(any(UserHandle.class))).thenAnswer( + invocation -> { + final UserHandle userHandle = (UserHandle) invocation.getArguments()[0]; + final UserInfo ui = getUserInfo(userHandle.getIdentifier()); + return ui == null ? UserHandle.USER_NULL : UserHandle.of(ui.profileGroupId); + } + ); when(userManager.getProfiles(anyInt())).thenAnswer( invocation -> { final int userId12 = (int) invocation.getArguments()[0]; |