diff options
| author | 2016-12-06 09:45:01 +0000 | |
|---|---|---|
| committer | 2016-12-06 09:45:05 +0000 | |
| commit | abf86385f8ba14d4f4789df59adec619a682b238 (patch) | |
| tree | 151e14c1bca68df60c54cb7f141c42b711f355f4 | |
| parent | 6d62b033e0a8c78f140649dd8560a91511afcffb (diff) | |
| parent | 849fd6f58e92476af3e3eeb802e71fddf372d6f2 (diff) | |
Merge "Return error code from isProvisioningAllowed"
4 files changed, 504 insertions, 95 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 5600da6def4a..36f738d5887a 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -1109,6 +1109,172 @@ public class DevicePolicyManager { public @interface UserProvisioningState {} /** + * Result code for {@link checkProvisioningPreCondition}. + * + * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, + * {@link #ACTION_PROVISION_MANAGED_PROFILE}, {@link #ACTION_PROVISION_MANAGED_USER} and + * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when provisioning is allowed. + * + * @hide + */ + public static final int CODE_OK = 0; + + /** + * Result code for {@link checkProvisioningPreCondition}. + * + * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and + * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when the device already has a device + * owner. + * + * @hide + */ + public static final int CODE_HAS_DEVICE_OWNER = 1; + + /** + * Result code for {@link checkProvisioningPreCondition}. + * + * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, + * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when the user has a profile owner and for + * {@link #ACTION_PROVISION_MANAGED_PROFILE} when the profile owner is already set. + * + * @hide + */ + public static final int CODE_USER_HAS_PROFILE_OWNER = 2; + + /** + * Result code for {@link checkProvisioningPreCondition}. + * + * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and + * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when the user isn't running. + * + * @hide + */ + public static final int CODE_USER_NOT_RUNNING = 3; + + /** + * Result code for {@link checkProvisioningPreCondition}. + * + * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, + * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} if the device has already been setup and + * for {@link #ACTION_PROVISION_MANAGED_USER} if the user has already been setup. + * + * @hide + */ + public static final int CODE_USER_SETUP_COMPLETED = 4; + + /** + * Code used to indicate that the device also has a user other than the system user. + * + * @hide + */ + public static final int CODE_NONSYSTEM_USER_EXISTS = 5; + + /** + * Code used to indicate that device has an account that prevents provisioning. + * + * @hide + */ + public static final int CODE_ACCOUNTS_NOT_EMPTY = 6; + + /** + * Result code for {@link checkProvisioningPreCondition}. + * + * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and + * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} if the user is not a system user. + * + * @hide + */ + public static final int CODE_NOT_SYSTEM_USER = 7; + + /** + * Result code for {@link checkProvisioningPreCondition}. + * + * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, + * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} and {@link #ACTION_PROVISION_MANAGED_USER} + * when the device is a watch and is already paired. + * + * @hide + */ + public static final int CODE_HAS_PAIRED = 8; + + /** + * Result code for {@link checkProvisioningPreCondition}. + * + * <p>Returned for {@link #ACTION_PROVISION_MANAGED_PROFILE} and + * {@link #ACTION_PROVISION_MANAGED_USER} on devices which do not support managed users. + * + * @see {@link PackageManager#FEATURE_MANAGED_USERS} + * @hide + */ + public static final int CODE_MANAGED_USERS_NOT_SUPPORTED = 9; + + /** + * Result code for {@link checkProvisioningPreCondition}. + * + * <p>Returned for {@link #ACTION_PROVISION_MANAGED_USER} if the user is a system user. + * + * @hide + */ + public static final int CODE_SYSTEM_USER = 10; + + /** + * Result code for {@link checkProvisioningPreCondition}. + * + * <p>Returned for {@link #ACTION_PROVISION_MANAGED_PROFILE} when the user cannot have more + * managed profiles. + * + * @hide + */ + public static final int CODE_CANNOT_ADD_MANAGED_PROFILE = 11; + + /** + * Result code for {@link checkProvisioningPreCondition}. + * + * <p>Returned for {@link #ACTION_PROVISION_MANAGED_USER} and + * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} on devices not running with split system + * user. + * + * @hide + */ + public static final int CODE_NOT_SYSTEM_USER_SPLIT = 12; + + /** + * Result code for {@link checkProvisioningPreCondition}. + * + * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, + * {@link #ACTION_PROVISION_MANAGED_PROFILE}, {@link #ACTION_PROVISION_MANAGED_USER} and + * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} on devices which do no support device + * admins. + * + * @hide + */ + public static final int CODE_DEVICE_ADMIN_NOT_SUPPORTED = 13; + + /** + * Result code for {@link checkProvisioningPreCondition}. + * + * <p>Returned for {@link #ACTION_PROVISION_MANAGED_PROFILE} when the device has a device owner + * and the user is a system user on a split system user device. + * + * @hide + */ + public static final int CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14; + + /** + * Result codes for {@link checkProvisioningPreCondition} indicating all the provisioning pre + * conditions. + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({CODE_OK, CODE_HAS_DEVICE_OWNER, CODE_USER_HAS_PROFILE_OWNER, CODE_USER_NOT_RUNNING, + CODE_USER_SETUP_COMPLETED, CODE_NOT_SYSTEM_USER, CODE_HAS_PAIRED, + CODE_MANAGED_USERS_NOT_SUPPORTED, CODE_SYSTEM_USER, CODE_CANNOT_ADD_MANAGED_PROFILE, + CODE_NOT_SYSTEM_USER_SPLIT, CODE_DEVICE_ADMIN_NOT_SUPPORTED, + CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER}) + public @interface ProvisioningPreCondition {} + + /** * Return true if the given administrator component is currently active (enabled) in the system. * * @param admin The administrator component to check for. @@ -5978,6 +6144,24 @@ public class DevicePolicyManager { } /** + * Checks if provisioning a managed profile or device is possible and returns one of the + * {@link ProvisioningPreCondition}. + * + * @param action One of {@link #ACTION_PROVISION_MANAGED_DEVICE}, + * {@link #ACTION_PROVISION_MANAGED_PROFILE}, + * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE}, + * {@link #ACTION_PROVISION_MANAGED_USER} + * @hide + */ + public @ProvisioningPreCondition int checkProvisioningPreCondition(String action) { + try { + return mService.checkProvisioningPreCondition(action); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + /** * Return if this user is a managed profile of another user. An admin can become the profile * owner of a managed profile with {@link #ACTION_PROVISION_MANAGED_PROFILE} and of a managed * user with {@link #createAndManageUser} diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index f303bbcd354f..3e2282550d4d 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -270,6 +270,7 @@ interface IDevicePolicyManager { String permission, int grantState); int getPermissionGrantState(in ComponentName admin, String packageName, String permission); boolean isProvisioningAllowed(String action); + int checkProvisioningPreCondition(String action); void setKeepUninstalledPackages(in ComponentName admin,in List<String> packageList); List<String> getKeepUninstalledPackages(in ComponentName admin); boolean isManagedProfile(in ComponentName admin); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index a2af40c246ab..45f369819ea8 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -17,6 +17,21 @@ package com.android.server.devicepolicy; import static android.Manifest.permission.MANAGE_CA_CERTIFICATES; +import static android.app.admin.DevicePolicyManager.CODE_ACCOUNTS_NOT_EMPTY; +import static android.app.admin.DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE; +import static android.app.admin.DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED; +import static android.app.admin.DevicePolicyManager.CODE_HAS_DEVICE_OWNER; +import static android.app.admin.DevicePolicyManager.CODE_HAS_PAIRED; +import static android.app.admin.DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED; +import static android.app.admin.DevicePolicyManager.CODE_NONSYSTEM_USER_EXISTS; +import static android.app.admin.DevicePolicyManager.CODE_NOT_SYSTEM_USER; +import static android.app.admin.DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT; +import static android.app.admin.DevicePolicyManager.CODE_OK; +import static android.app.admin.DevicePolicyManager.CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER; +import static android.app.admin.DevicePolicyManager.CODE_SYSTEM_USER; +import static android.app.admin.DevicePolicyManager.CODE_USER_HAS_PROFILE_OWNER; +import static android.app.admin.DevicePolicyManager.CODE_USER_NOT_RUNNING; +import static android.app.admin.DevicePolicyManager.CODE_USER_SETUP_COMPLETED; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE; import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA; @@ -310,21 +325,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final int PROFILE_KEYGUARD_FEATURES = PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER | PROFILE_KEYGUARD_FEATURES_PROFILE_ONLY; - private static final int CODE_OK = 0; - private static final int CODE_HAS_DEVICE_OWNER = 1; - private static final int CODE_USER_HAS_PROFILE_OWNER = 2; - private static final int CODE_USER_NOT_RUNNING = 3; - private static final int CODE_USER_SETUP_COMPLETED = 4; - private static final int CODE_NONSYSTEM_USER_EXISTS = 5; - private static final int CODE_ACCOUNTS_NOT_EMPTY = 6; - private static final int CODE_NOT_SYSTEM_USER = 7; - private static final int CODE_HAS_PAIRED = 8; - - @Retention(RetentionPolicy.SOURCE) - @IntDef({ CODE_OK, CODE_HAS_DEVICE_OWNER, CODE_USER_HAS_PROFILE_OWNER, CODE_USER_NOT_RUNNING, - CODE_USER_SETUP_COMPLETED, CODE_NOT_SYSTEM_USER }) - private @interface DeviceOwnerPreConditionCode {} - private static final int DEVICE_ADMIN_DEACTIVATE_TIMEOUT = 10000; /** @@ -6526,7 +6526,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { enforceCanManageProfileAndDeviceOwners(); } - final int code = checkSetDeviceOwnerPreConditionLocked(owner, userId, isAdb()); + final int code = checkDeviceOwnerProvisioningPreConditionLocked(owner, userId, isAdb()); switch (code) { case CODE_OK: return; @@ -6553,7 +6553,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { throw new IllegalStateException("Not allowed to set the device owner because this " + "device has already paired"); default: - throw new IllegalStateException("Unknown @DeviceOwnerPreConditionCode " + code); + throw new IllegalStateException("Unexpected @ProvisioningPreCondition " + code); } } @@ -8761,79 +8761,42 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean isProvisioningAllowed(String action) { + return checkProvisioningPreConditionSkipPermission(action) == CODE_OK; + } + + @Override + public int checkProvisioningPreCondition(String action) { + enforceCanManageProfileAndDeviceOwners(); + return checkProvisioningPreConditionSkipPermission(action); + } + + private int checkProvisioningPreConditionSkipPermission(String action) { if (!mHasFeature) { - return false; + return CODE_DEVICE_ADMIN_NOT_SUPPORTED; } final int callingUserId = mInjector.userHandleGetCallingUserId(); - if (DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE.equals(action)) { - if (!hasFeatureManagedUsers()) { - return false; - } - synchronized (this) { - if (mOwners.hasDeviceOwner()) { - // STOPSHIP Only allow creating a managed profile if allowed by the device - // owner. http://b/31952368 - if (mInjector.userManagerIsSplitSystemUser()) { - if (callingUserId == UserHandle.USER_SYSTEM) { - // Managed-profiles cannot be setup on the system user. - return false; - } - } - } - } - if (getProfileOwner(callingUserId) != null) { - // Managed user cannot have a managed profile. - return false; - } - boolean canRemoveProfile - = !mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER); - final long ident = mInjector.binderClearCallingIdentity(); - try { - if (!mUserManager.canAddMoreManagedProfiles(callingUserId, canRemoveProfile)) { - return false; - } - } finally { - mInjector.binderRestoreCallingIdentity(ident); - } - return true; - } else if (DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE.equals(action)) { - return isDeviceOwnerProvisioningAllowed(callingUserId); - } else if (DevicePolicyManager.ACTION_PROVISION_MANAGED_USER.equals(action)) { - if (!hasFeatureManagedUsers()) { - return false; - } - if (!mInjector.userManagerIsSplitSystemUser()) { - // ACTION_PROVISION_MANAGED_USER only supported on split-user systems. - return false; - } - if (callingUserId == UserHandle.USER_SYSTEM) { - // System user cannot be a managed user. - return false; - } - if (hasUserSetupCompleted(callingUserId)) { - return false; - } - if (mIsWatch && hasPaired(UserHandle.USER_SYSTEM)) { - return false; + if (action != null) { + switch (action) { + case DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE: + return checkManagedProfileProvisioningPreCondition(callingUserId); + case DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE: + return checkDeviceOwnerProvisioningPreCondition(callingUserId); + case DevicePolicyManager.ACTION_PROVISION_MANAGED_USER: + return checkManagedUserProvisioningPreCondition(callingUserId); + case DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE: + return checkManagedShareableDeviceProvisioningPreCondition(callingUserId); } - return true; - } else if (DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE.equals(action)) { - if (!mInjector.userManagerIsSplitSystemUser()) { - // ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE only supported on split-user systems. - return false; - } - return isDeviceOwnerProvisioningAllowed(callingUserId); } throw new IllegalArgumentException("Unknown provisioning action " + action); } - /* + /** * The device owner can only be set before the setup phase of the primary user has completed, * except for adb command if no accounts or additional users are present on the device. */ - private synchronized @DeviceOwnerPreConditionCode int checkSetDeviceOwnerPreConditionLocked( - @Nullable ComponentName owner, int deviceOwnerUserId, boolean isAdb) { + private int checkDeviceOwnerProvisioningPreConditionLocked(@Nullable ComponentName owner, + int deviceOwnerUserId, boolean isAdb) { if (mOwners.hasDeviceOwner()) { return CODE_HAS_DEVICE_OWNER; } @@ -8878,11 +8841,73 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } - private boolean isDeviceOwnerProvisioningAllowed(int deviceOwnerUserId) { + private int checkDeviceOwnerProvisioningPreCondition(int deviceOwnerUserId) { + synchronized (this) { + return checkDeviceOwnerProvisioningPreConditionLocked(/* owner unknown */ null, + deviceOwnerUserId, /* isAdb= */ false); + } + } + + private int checkManagedProfileProvisioningPreCondition(int callingUserId) { + if (!hasFeatureManagedUsers()) { + return CODE_MANAGED_USERS_NOT_SUPPORTED; + } synchronized (this) { - return CODE_OK == checkSetDeviceOwnerPreConditionLocked( - /* owner unknown */ null, deviceOwnerUserId, /* isAdb */ false); + if (mOwners.hasDeviceOwner()) { + // STOPSHIP Only allow creating a managed profile if allowed by the device + // owner. http://b/31952368 + if (mInjector.userManagerIsSplitSystemUser()) { + if (callingUserId == UserHandle.USER_SYSTEM) { + // Managed-profiles cannot be setup on the system user. + return CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER; + } + } + } + } + if (getProfileOwner(callingUserId) != null) { + // Managed user cannot have a managed profile. + return CODE_USER_HAS_PROFILE_OWNER; + } + boolean canRemoveProfile = + !mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER); + final long ident = mInjector.binderClearCallingIdentity(); + try { + if (!mUserManager.canAddMoreManagedProfiles(callingUserId, canRemoveProfile)) { + return CODE_CANNOT_ADD_MANAGED_PROFILE; + } + } finally { + mInjector.binderRestoreCallingIdentity(ident); + } + return CODE_OK; + } + + private int checkManagedUserProvisioningPreCondition(int callingUserId) { + if (!hasFeatureManagedUsers()) { + return CODE_MANAGED_USERS_NOT_SUPPORTED; + } + if (!mInjector.userManagerIsSplitSystemUser()) { + // ACTION_PROVISION_MANAGED_USER only supported on split-user systems. + return CODE_NOT_SYSTEM_USER_SPLIT; + } + if (callingUserId == UserHandle.USER_SYSTEM) { + // System user cannot be a managed user. + return CODE_SYSTEM_USER; + } + if (hasUserSetupCompleted(callingUserId)) { + return CODE_USER_SETUP_COMPLETED; + } + if (mIsWatch && hasPaired(UserHandle.USER_SYSTEM)) { + return CODE_HAS_PAIRED; + } + return CODE_OK; + } + + private int checkManagedShareableDeviceProvisioningPreCondition(int callingUserId) { + if (!mInjector.userManagerIsSplitSystemUser()) { + // ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE only supported on split-user systems. + return CODE_NOT_SYSTEM_USER_SPLIT; } + return checkDeviceOwnerProvisioningPreCondition(callingUserId); } private boolean hasFeatureManagedUsers() { 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 3ad40758aff6..0c008861b346 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -1993,7 +1993,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // UnfinishedVerificationException. } - public void testIsProvisioningAllowed_DeviceAdminFeatureOff() throws Exception { + public void setup_DeviceAdminFeatureOff() throws Exception { when(mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) .thenReturn(false); when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) @@ -2005,7 +2005,10 @@ public class DevicePolicyManagerTest extends DpmTestBase { setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM); mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; + } + public void testIsProvisioningAllowed_DeviceAdminFeatureOff() throws Exception { + setup_DeviceAdminFeatureOff(); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, false); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, @@ -2013,7 +2016,21 @@ public class DevicePolicyManagerTest extends DpmTestBase { assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false); } - public void testIsProvisioningAllowed_ManagedProfileFeatureOff() throws Exception { + public void testCheckProvisioningPreCondition_DeviceAdminFeatureOff() throws Exception { + setup_DeviceAdminFeatureOff(); + mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, + DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, + DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED); + assertCheckProvisioningPreCondition( + DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, + DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, + DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED); + } + + public void setup_ManagedProfileFeatureOff() throws Exception { when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) .thenReturn(false); initializeDpms(); @@ -2023,7 +2040,10 @@ public class DevicePolicyManagerTest extends DpmTestBase { setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM); mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; + } + public void testIsProvisioningAllowed_ManagedProfileFeatureOff() throws Exception { + setup_ManagedProfileFeatureOff(); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, @@ -2039,7 +2059,33 @@ public class DevicePolicyManagerTest extends DpmTestBase { assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false); } - public void testIsProvisioningAllowed_nonSplitUser_firstBoot_primaryUser() throws Exception { + public void testCheckProvisioningPreCondition_ManagedProfileFeatureOff() throws Exception { + setup_ManagedProfileFeatureOff(); + mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, + DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED); + assertCheckProvisioningPreCondition( + DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, + DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, + DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED); + + // Test again when split user is on + when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, + DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED); + assertCheckProvisioningPreCondition( + DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, + DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED); + } + + public void setup_nonSplitUser_firstBoot_primaryUser() throws Exception { when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) .thenReturn(true); when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false); @@ -2048,7 +2094,10 @@ public class DevicePolicyManagerTest extends DpmTestBase { setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM); mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; + } + public void testIsProvisioningAllowed_nonSplitUser_firstBoot_primaryUser() throws Exception { + setup_nonSplitUser_firstBoot_primaryUser(); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, @@ -2057,8 +2106,22 @@ public class DevicePolicyManagerTest extends DpmTestBase { false /* because of non-split user */); } - public void testIsProvisioningAllowed_nonSplitUser_afterDeviceSetup_primaryUser() + public void testCheckProvisioningPreCondition_nonSplitUser_firstBoot_primaryUser() throws Exception { + setup_nonSplitUser_firstBoot_primaryUser(); + mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition( + DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, + DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, + DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT); + } + + public void setup_nonSplitUser_afterDeviceSetup_primaryUser() throws Exception { when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) .thenReturn(true); when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false); @@ -2067,7 +2130,11 @@ public class DevicePolicyManagerTest extends DpmTestBase { setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM); mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; + } + public void testIsProvisioningAllowed_nonSplitUser_afterDeviceSetup_primaryUser() + throws Exception { + setup_nonSplitUser_afterDeviceSetup_primaryUser(); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, false/* because of completed device setup */); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); @@ -2077,7 +2144,22 @@ public class DevicePolicyManagerTest extends DpmTestBase { false/* because of non-split user */); } - public void testIsProvisioningAllowed_splitUser_firstBoot_systemUser() throws Exception { + public void testCheckProvisioningPreCondition_nonSplitUser_afterDeviceSetup_primaryUser() + throws Exception { + setup_nonSplitUser_afterDeviceSetup_primaryUser(); + mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, + DevicePolicyManager.CODE_USER_SETUP_COMPLETED); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition( + DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, + DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, + DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT); + } + + public void setup_splitUser_firstBoot_systemUser() throws Exception { when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) .thenReturn(true); when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true); @@ -2086,7 +2168,10 @@ public class DevicePolicyManagerTest extends DpmTestBase { setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM); mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; + } + public void testIsProvisioningAllowed_splitUser_firstBoot_systemUser() throws Exception { + setup_splitUser_firstBoot_systemUser(); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false /* because canAddMoreManagedProfiles returns false */); @@ -2094,10 +2179,24 @@ public class DevicePolicyManagerTest extends DpmTestBase { true); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false/* because calling uid is system user */); - } - public void testIsProvisioningAllowed_splitUser_afterDeviceSetup_systemUser() throws Exception { + public void testCheckProvisioningPreCondition_splitUser_firstBoot_systemUser() + throws Exception { + setup_splitUser_firstBoot_systemUser(); + mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, + DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); + assertCheckProvisioningPreCondition( + DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, + DevicePolicyManager.CODE_SYSTEM_USER); + } + + public void setup_splitUser_afterDeviceSetup_systemUser() throws Exception { when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) .thenReturn(true); when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true); @@ -2106,7 +2205,10 @@ public class DevicePolicyManagerTest extends DpmTestBase { setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM); mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; + } + public void testIsProvisioningAllowed_splitUser_afterDeviceSetup_systemUser() throws Exception { + setup_splitUser_afterDeviceSetup_systemUser(); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true/* it's undefined behavior. Can be changed into false in the future */); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, @@ -2117,7 +2219,22 @@ public class DevicePolicyManagerTest extends DpmTestBase { false/* because calling uid is system user */); } - public void testIsProvisioningAllowed_splitUser_firstBoot_primaryUser() throws Exception { + public void testCheckProvisioningPreCondition_splitUser_afterDeviceSetup_systemUser() + throws Exception { + setup_splitUser_afterDeviceSetup_systemUser(); + mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, + DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); + assertCheckProvisioningPreCondition( + DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, + DevicePolicyManager.CODE_SYSTEM_USER); + } + + public void setup_splitUser_firstBoot_primaryUser() throws Exception { when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) .thenReturn(true); when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true); @@ -2126,17 +2243,33 @@ public class DevicePolicyManagerTest extends DpmTestBase { setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.callingUid = DpmMockContext.CALLER_UID; + } + public void testIsProvisioningAllowed_splitUser_firstBoot_primaryUser() throws Exception { + setup_splitUser_firstBoot_primaryUser(); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, true); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, true); - } - public void testIsProvisioningAllowed_splitUser_afterDeviceSetup_primaryUser() + public void testCheckProvisioningPreCondition_splitUser_firstBoot_primaryUser() throws Exception { + setup_splitUser_firstBoot_primaryUser(); + mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition( + DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, + DevicePolicyManager.CODE_OK); + } + + public void setup_splitUser_afterDeviceSetup_primaryUser() throws Exception { when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) .thenReturn(true); when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true); @@ -2145,7 +2278,11 @@ public class DevicePolicyManagerTest extends DpmTestBase { setUserSetupCompleteForUser(true, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.callingUid = DpmMockContext.CALLER_UID; + } + public void testIsProvisioningAllowed_splitUser_afterDeviceSetup_primaryUser() + throws Exception { + setup_splitUser_afterDeviceSetup_primaryUser(); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true/* it's undefined behavior. Can be changed into false in the future */); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); @@ -2155,8 +2292,22 @@ public class DevicePolicyManagerTest extends DpmTestBase { false/* because user setup completed */); } - public void testIsProvisioningAllowed_provisionManagedProfileWithDeviceOwner_systemUser() + public void testCheckProvisioningPreCondition_splitUser_afterDeviceSetup_primaryUser() throws Exception { + setup_splitUser_afterDeviceSetup_primaryUser(); + mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition( + DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, + DevicePolicyManager.CODE_OK); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, + DevicePolicyManager.CODE_USER_SETUP_COMPLETED); + } + + public void setup_provisionManagedProfileWithDeviceOwner_systemUser() throws Exception { setDeviceOwner(); when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) @@ -2167,13 +2318,24 @@ public class DevicePolicyManagerTest extends DpmTestBase { setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM); mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; + } + public void testIsProvisioningAllowed_provisionManagedProfileWithDeviceOwner_systemUser() + throws Exception { + setup_provisionManagedProfileWithDeviceOwner_systemUser(); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false /* can't provision managed profile on system user */); } - public void testIsProvisioningAllowed_provisionManagedProfileWithDeviceOwner_primaryUser() + public void testCheckProvisioningPreCondition_provisionManagedProfileWithDeviceOwner_systemUser() throws Exception { + setup_provisionManagedProfileWithDeviceOwner_systemUser(); + mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, + DevicePolicyManager.CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER); + } + + private void setup_provisionManagedProfileWithDeviceOwner_primaryUser() throws Exception { setDeviceOwner(); when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) @@ -2184,12 +2346,23 @@ public class DevicePolicyManagerTest extends DpmTestBase { setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.callingUid = DpmMockContext.CALLER_UID; + } + public void testIsProvisioningAllowed_provisionManagedProfileWithDeviceOwner_primaryUser() + throws Exception { + setup_provisionManagedProfileWithDeviceOwner_primaryUser(); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); } - public void testIsProvisioningAllowed_provisionManagedProfileCantRemoveUser_primaryUser() + public void testCheckProvisioningPreCondition_provisionManagedProfileWithDeviceOwner_primaryUser() throws Exception { + setup_provisionManagedProfileWithDeviceOwner_primaryUser(); + mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, + DevicePolicyManager.CODE_OK); + } + + private void setup_provisionManagedProfileCantRemoveUser_primaryUser() throws Exception { setDeviceOwner(); when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) @@ -2198,16 +2371,37 @@ public class DevicePolicyManagerTest extends DpmTestBase { when(mContext.userManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)) .thenReturn(true); when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE, - false /* we can't remove a managed profile*/)).thenReturn(false); + false /* we can't remove a managed profile */)).thenReturn(false); when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE, true)).thenReturn(true); setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.callingUid = DpmMockContext.CALLER_UID; + } + public void testIsProvisioningAllowed_provisionManagedProfileCantRemoveUser_primaryUser() + throws Exception { + setup_provisionManagedProfileCantRemoveUser_primaryUser(); assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); } + public void testCheckProvisioningPreCondition_provisionManagedProfileCantRemoveUser_primaryUser() + throws Exception { + setup_provisionManagedProfileCantRemoveUser_primaryUser(); + mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); + assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, + DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); + } + + public void testCheckProvisioningPreCondition_permission() { + // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted + try { + dpm.checkProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE); + fail("Didn't throw SecurityException"); + } catch (SecurityException expected) { + } + } + public void testForceUpdateUserSetupComplete_permission() { // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted try { @@ -2568,6 +2762,11 @@ public class DevicePolicyManagerTest extends DpmTestBase { dpm.isProvisioningAllowed(action)); } + private void assertCheckProvisioningPreCondition(String action, int provisioningCondition) { + assertEquals("checkProvisioningPreCondition(" + action + ") returning unexpected result", + provisioningCondition, dpm.checkProvisioningPreCondition(action)); + } + /** * Setup a managed profile with the specified admin and its uid. * @param admin ComponentName that's visible to the test code, which doesn't have to exist. |