Loading core/java/android/app/admin/DevicePolicyManager.java +184 −0 Original line number Diff line number Diff line Loading @@ -1108,6 +1108,172 @@ public class DevicePolicyManager { @Retention(RetentionPolicy.SOURCE) 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. * Loading Loading @@ -5977,6 +6143,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 Loading core/java/android/app/admin/IDevicePolicyManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +106 −81 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; /** Loading Loading @@ -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; Loading @@ -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); } } Loading Loading @@ -8761,79 +8761,42 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean isProvisioningAllowed(String action) { if (!mHasFeature) { return false; return checkProvisioningPreConditionSkipPermission(action) == CODE_OK; } 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; @Override public int checkProvisioningPreCondition(String action) { enforceCanManageProfileAndDeviceOwners(); return checkProvisioningPreConditionSkipPermission(action); } if (mIsWatch && hasPaired(UserHandle.USER_SYSTEM)) { return false; private int checkProvisioningPreConditionSkipPermission(String action) { if (!mHasFeature) { return CODE_DEVICE_ADMIN_NOT_SUPPORTED; } 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; final int callingUserId = mInjector.userHandleGetCallingUserId(); 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 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; } Loading Loading @@ -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() { Loading services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +213 −14 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/app/admin/DevicePolicyManager.java +184 −0 Original line number Diff line number Diff line Loading @@ -1108,6 +1108,172 @@ public class DevicePolicyManager { @Retention(RetentionPolicy.SOURCE) 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. * Loading Loading @@ -5977,6 +6143,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 Loading
core/java/android/app/admin/IDevicePolicyManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +106 −81 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; /** Loading Loading @@ -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; Loading @@ -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); } } Loading Loading @@ -8761,79 +8761,42 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean isProvisioningAllowed(String action) { if (!mHasFeature) { return false; return checkProvisioningPreConditionSkipPermission(action) == CODE_OK; } 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; @Override public int checkProvisioningPreCondition(String action) { enforceCanManageProfileAndDeviceOwners(); return checkProvisioningPreConditionSkipPermission(action); } if (mIsWatch && hasPaired(UserHandle.USER_SYSTEM)) { return false; private int checkProvisioningPreConditionSkipPermission(String action) { if (!mHasFeature) { return CODE_DEVICE_ADMIN_NOT_SUPPORTED; } 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; final int callingUserId = mInjector.userHandleGetCallingUserId(); 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 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; } Loading Loading @@ -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() { Loading
services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +213 −14 File changed.Preview size limit exceeded, changes collapsed. Show changes