Loading core/api/test-current.txt +2 −2 Original line number Original line Diff line number Diff line Loading @@ -401,10 +401,10 @@ package android.app.admin { field public static final int CODE_MANAGED_USERS_NOT_SUPPORTED = 9; // 0x9 field public static final int CODE_MANAGED_USERS_NOT_SUPPORTED = 9; // 0x9 field public static final int CODE_NONSYSTEM_USER_EXISTS = 5; // 0x5 field public static final int CODE_NONSYSTEM_USER_EXISTS = 5; // 0x5 field public static final int CODE_NOT_SYSTEM_USER = 7; // 0x7 field public static final int CODE_NOT_SYSTEM_USER = 7; // 0x7 field public static final int CODE_NOT_SYSTEM_USER_SPLIT = 12; // 0xc field @Deprecated public static final int CODE_NOT_SYSTEM_USER_SPLIT = 12; // 0xc field public static final int CODE_OK = 0; // 0x0 field public static final int CODE_OK = 0; // 0x0 field public static final int CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS = 15; // 0xf field public static final int CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS = 15; // 0xf field public static final int CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14; // 0xe field @Deprecated public static final int CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14; // 0xe field public static final int CODE_SYSTEM_USER = 10; // 0xa field public static final int CODE_SYSTEM_USER = 10; // 0xa field public static final int CODE_USER_HAS_PROFILE_OWNER = 2; // 0x2 field public static final int CODE_USER_HAS_PROFILE_OWNER = 2; // 0x2 field public static final int CODE_USER_NOT_RUNNING = 3; // 0x3 field public static final int CODE_USER_NOT_RUNNING = 3; // 0x3 Loading core/java/android/app/admin/DevicePolicyManager.java +23 −95 Original line number Original line Diff line number Diff line Loading @@ -452,59 +452,6 @@ public class DevicePolicyManager { public static final String ACTION_PROVISION_FINANCED_DEVICE = public static final String ACTION_PROVISION_FINANCED_DEVICE = "android.app.action.PROVISION_FINANCED_DEVICE"; "android.app.action.PROVISION_FINANCED_DEVICE"; /** * Activity action: Starts the provisioning flow which sets up a managed device. * Must be started with {@link android.app.Activity#startActivityForResult(Intent, int)}. * * <p>NOTE: This is only supported on split system user devices, and puts the device into a * management state that is distinct from that reached by * {@link #ACTION_PROVISION_MANAGED_DEVICE} - specifically the device owner runs on the system * user, and only has control over device-wide policies, not individual users and their data. * The primary benefit is that multiple non-system users are supported when provisioning using * this form of device management. * * <p>During device owner provisioning a device admin app is set as the owner of the device. * A device owner has full control over the device. The device owner can not be modified by the * user. * * <p>A typical use case would be a device that is owned by a company, but used by either an * employee or client. * * <p>An intent with this action can be sent only on an unprovisioned device. * It is possible to check if provisioning is allowed or not by querying the method * {@link #isProvisioningAllowed(String)}. * * <p>The intent contains the following extras: * <ul> * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}</li> * <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}, optional</li> * <li>{@link #EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED}, optional</li> * <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional</li> * <li>{@link #EXTRA_PROVISIONING_LOGO_URI}, optional</li> * <li>{@link #EXTRA_PROVISIONING_MAIN_COLOR}, optional</li> * </ul> * * <p>When device owner provisioning has completed, an intent of the type * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} is broadcast to the * device owner. * * <p>From version {@link android.os.Build.VERSION_CODES#O}, when device owner provisioning has * completed, along with the above broadcast, activity intent * {@link #ACTION_PROVISIONING_SUCCESSFUL} will also be sent to the device owner. * * <p>If provisioning fails, the device is factory reset. * * <p>A result code of {@link android.app.Activity#RESULT_OK} implies that the synchronous part * of the provisioning flow was successful, although this doesn't guarantee the full flow will * succeed. Conversely a result code of {@link android.app.Activity#RESULT_CANCELED} implies * that the user backed-out of provisioning, or some precondition for provisioning wasn't met. * * @hide */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE = "android.app.action.PROVISION_MANAGED_SHAREABLE_DEVICE"; /** /** * Activity action: Finalizes management provisioning, should be used after user-setup * Activity action: Finalizes management provisioning, should be used after user-setup * has been completed and {@link #getUserProvisioningState()} returns one of: * has been completed and {@link #getUserProvisioningState()} returns one of: Loading Loading @@ -1990,8 +1937,8 @@ public class DevicePolicyManager { * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, * {@link #ACTION_PROVISION_MANAGED_PROFILE}, {@link #ACTION_PROVISION_MANAGED_USER} and * {@link #ACTION_PROVISION_MANAGED_PROFILE} and {@link #ACTION_PROVISION_MANAGED_USER} * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when provisioning is allowed. * when provisioning is allowed. * * * @hide * @hide */ */ Loading @@ -2001,9 +1948,8 @@ public class DevicePolicyManager { /** /** * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} when the device already has a * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when the device already has a device * device owner. * owner. * * * @hide * @hide */ */ Loading @@ -2013,9 +1959,8 @@ public class DevicePolicyManager { /** /** * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} when the user has a profile owner * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when the user has a profile owner and for * and for {@link #ACTION_PROVISION_MANAGED_PROFILE} when the profile owner is already set. * {@link #ACTION_PROVISION_MANAGED_PROFILE} when the profile owner is already set. * * * @hide * @hide */ */ Loading @@ -2025,8 +1970,7 @@ public class DevicePolicyManager { /** /** * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} when the user isn't running. * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when the user isn't running. * * * @hide * @hide */ */ Loading @@ -2036,9 +1980,8 @@ public class DevicePolicyManager { /** /** * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} if the device has already been * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} if the device has already been setup and * setup and for {@link #ACTION_PROVISION_MANAGED_USER} if the user has already been setup. * for {@link #ACTION_PROVISION_MANAGED_USER} if the user has already been setup. * * * @hide * @hide */ */ Loading @@ -2064,8 +2007,7 @@ public class DevicePolicyManager { /** /** * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} if the user is not a system user. * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} if the user is not a system user. * * * @hide * @hide */ */ Loading @@ -2075,9 +2017,8 @@ public class DevicePolicyManager { /** /** * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} and {@link #ACTION_PROVISION_MANAGED_USER} * {@link #ACTION_PROVISION_MANAGED_USER} when the device is a watch and is already paired. * when the device is a watch and is already paired. * * * @hide * @hide */ */ Loading Loading @@ -2121,14 +2062,11 @@ public class DevicePolicyManager { /** /** * TODO (b/137101239): clean up split system user codes * TODO (b/137101239): clean up split system user codes * 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 * @hide */ * @deprecated not used anymore but can't be removed since it's a @TestApi. **/ @Deprecated @TestApi @TestApi public static final int CODE_NOT_SYSTEM_USER_SPLIT = 12; public static final int CODE_NOT_SYSTEM_USER_SPLIT = 12; Loading @@ -2136,8 +2074,7 @@ public class DevicePolicyManager { * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, * {@link #ACTION_PROVISION_MANAGED_PROFILE}, {@link #ACTION_PROVISION_MANAGED_USER} and * {@link #ACTION_PROVISION_MANAGED_PROFILE} on devices which do not support device * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} on devices which do not support device * admins. * admins. * * * @hide * @hide Loading @@ -2149,11 +2086,10 @@ public class DevicePolicyManager { * TODO (b/137101239): clean up split system user codes * TODO (b/137101239): clean up split system user codes * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_PROFILE} when the device the user is a * system user on a split system user device. * * @hide * @hide * @deprecated not used anymore but can't be removed since it's a @TestApi. */ */ @Deprecated @TestApi @TestApi public static final int CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14; public static final int CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14; Loading Loading @@ -7147,17 +7083,9 @@ public class DevicePolicyManager { } } /** /** * TODO (b/137101239): remove this method in follow-up CL * since it's only used for split system user. * Called by a device owner to set whether all users created on the device should be ephemeral. * Called by a device owner to set whether all users created on the device should be ephemeral. * <p> * The system user is exempt from this policy - it is never ephemeral. * <p> * The calling device admin must be the device owner. If it is not, a security exception will be * thrown. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param forceEphemeralUsers If true, all the existing users will be deleted and all * subsequently created users will be ephemeral. * @throws SecurityException if {@code admin} is not a device owner. * @hide * @hide */ */ public void setForceEphemeralUsers( public void setForceEphemeralUsers( Loading @@ -7173,6 +7101,8 @@ public class DevicePolicyManager { } } /** /** * TODO (b/137101239): remove this method in follow-up CL * since it's only used for split system user. * @return true if all users are created ephemeral. * @return true if all users are created ephemeral. * @throws SecurityException if {@code admin} is not a device owner. * @throws SecurityException if {@code admin} is not a device owner. * @hide * @hide Loading Loading @@ -10731,9 +10661,7 @@ public class DevicePolicyManager { * profile or user, setting the given package as owner. * profile or user, setting the given package as owner. * * * @param action One of {@link #ACTION_PROVISION_MANAGED_DEVICE}, * @param action One of {@link #ACTION_PROVISION_MANAGED_DEVICE}, * {@link #ACTION_PROVISION_MANAGED_PROFILE}, * {@link #ACTION_PROVISION_MANAGED_PROFILE} * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE}, * {@link #ACTION_PROVISION_MANAGED_USER} * @param packageName The package of the component that would be set as device, user, or profile * @param packageName The package of the component that would be set as device, user, or profile * owner. * owner. * @return A {@link ProvisioningPreCondition} value indicating whether provisioning is allowed. * @return A {@link ProvisioningPreCondition} value indicating whether provisioning is allowed. Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +13 −99 Original line number Original line Diff line number Diff line Loading @@ -35,10 +35,8 @@ 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_MANAGED_USERS_NOT_SUPPORTED; import static android.app.admin.DevicePolicyManager.CODE_NONSYSTEM_USER_EXISTS; 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; 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_OK; import static android.app.admin.DevicePolicyManager.CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS; import static android.app.admin.DevicePolicyManager.CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS; 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_SYSTEM_USER; import static android.app.admin.DevicePolicyManager.CODE_USER_HAS_PROFILE_OWNER; 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_NOT_RUNNING; Loading Loading @@ -1380,11 +1378,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { SystemProperties.set(key, value); SystemProperties.set(key, value); } } // TODO (b/137101239): clean up split system user codes boolean userManagerIsSplitSystemUser() { return UserManager.isSplitSystemUser(); } boolean userManagerIsHeadlessSystemUserMode() { boolean userManagerIsHeadlessSystemUserMode() { return UserManager.isHeadlessSystemUserMode(); return UserManager.isHeadlessSystemUserMode(); } } Loading Loading @@ -7404,48 +7397,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return mInjector.settingsGlobalGetInt(Global.AUTO_TIME_ZONE, 0) > 0; return mInjector.settingsGlobalGetInt(Global.AUTO_TIME_ZONE, 0) > 0; } } // TODO (b/137101239): remove this method in follow-up CL // since it's only used for split system user. @Override @Override public void setForceEphemeralUsers(ComponentName who, boolean forceEphemeralUsers) { public void setForceEphemeralUsers(ComponentName who, boolean forceEphemeralUsers) { if (!mHasFeature) { throw new UnsupportedOperationException("This method was used by split system user only."); return; } Objects.requireNonNull(who, "ComponentName is null"); final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isDeviceOwner(caller)); // Allow setting this policy to true only if there is a split system user. if (forceEphemeralUsers && !mInjector.userManagerIsSplitSystemUser()) { throw new UnsupportedOperationException( "Cannot force ephemeral users on systems without split system user."); } boolean removeAllUsers = false; synchronized (getLockObject()) { final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); if (deviceOwner.forceEphemeralUsers != forceEphemeralUsers) { deviceOwner.forceEphemeralUsers = forceEphemeralUsers; saveSettingsLocked(caller.getUserId()); mUserManagerInternal.setForceEphemeralUsers(forceEphemeralUsers); removeAllUsers = forceEphemeralUsers; } } if (removeAllUsers) { mInjector.binderWithCleanCallingIdentity(() -> mUserManagerInternal.removeAllUsers()); } } } // TODO (b/137101239): remove this method in follow-up CL // since it's only used for split system user. @Override @Override public boolean getForceEphemeralUsers(ComponentName who) { public boolean getForceEphemeralUsers(ComponentName who) { if (!mHasFeature) { throw new UnsupportedOperationException("This method was used by split system user only."); return false; } Objects.requireNonNull(who, "ComponentName is null"); final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isDeviceOwner(caller)); synchronized (getLockObject()) { final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); return deviceOwner.forceEphemeralUsers; } } } @Override @Override Loading Loading @@ -12733,13 +12696,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { case DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE: case DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE: case DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE: case DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE: return checkDeviceOwnerProvisioningPreCondition(callingUserId); return checkDeviceOwnerProvisioningPreCondition(callingUserId); // TODO (b/137101239): clean up split system user codes // ACTION_PROVISION_MANAGED_USER and ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE // only supported on split-user systems. case DevicePolicyManager.ACTION_PROVISION_MANAGED_USER: return checkManagedUserProvisioningPreCondition(callingUserId); case DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE: return checkManagedShareableDeviceProvisioningPreCondition(callingUserId); } } } } throw new IllegalArgumentException("Unknown provisioning action " + action); throw new IllegalArgumentException("Unknown provisioning action " + action); Loading Loading @@ -12775,14 +12731,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } } } // TODO (b/137101239): clean up split system user codes if (isAdb) { if (isAdb) { // If shell command runs after user setup completed check device status. Otherwise, OK. // If shell command runs after user setup completed check device status. Otherwise, OK. if (mIsWatch || hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { if (mIsWatch || hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { // In non-headless system user mode, DO can be setup only if // In non-headless system user mode, DO can be setup only if // there's no non-system user // there's no non-system user if (!mInjector.userManagerIsHeadlessSystemUserMode() if (!mInjector.userManagerIsHeadlessSystemUserMode() && !mInjector.userManagerIsSplitSystemUser() && mUserManager.getUserCount() > 1) { && mUserManager.getUserCount() > 1) { return CODE_NONSYSTEM_USER_EXISTS; return CODE_NONSYSTEM_USER_EXISTS; } } Loading @@ -12801,17 +12755,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } return CODE_OK; return CODE_OK; } else { } else { if (!mInjector.userManagerIsSplitSystemUser()) { // DO has to be user 0 // In non-split user mode, DO has to be user 0 if (deviceOwnerUserId != UserHandle.USER_SYSTEM) { if (deviceOwnerUserId != UserHandle.USER_SYSTEM) { return CODE_NOT_SYSTEM_USER; return CODE_NOT_SYSTEM_USER; } } // Only provision DO before setup wizard completes // Only provision DO before setup wizard completes // TODO (b/171423186): implement deferred DO setup for headless system user mode if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { return CODE_USER_SETUP_COMPLETED; return CODE_USER_SETUP_COMPLETED; } } } return CODE_OK; return CODE_OK; } } } } Loading @@ -12831,17 +12782,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } } } // TODO (b/137101239): clean up split system user codes private int checkManagedProfileProvisioningPreCondition(String packageName, private int checkManagedProfileProvisioningPreCondition(String packageName, @UserIdInt int callingUserId) { @UserIdInt int callingUserId) { if (!hasFeatureManagedUsers()) { if (!hasFeatureManagedUsers()) { return CODE_MANAGED_USERS_NOT_SUPPORTED; return CODE_MANAGED_USERS_NOT_SUPPORTED; } } if (callingUserId == UserHandle.USER_SYSTEM && mInjector.userManagerIsSplitSystemUser()) { // Managed-profiles cannot be setup on the system user. return CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER; } if (getProfileOwnerAsUser(callingUserId) != null) { if (getProfileOwnerAsUser(callingUserId) != null) { // Managed user cannot have a managed profile. // Managed user cannot have a managed profile. return CODE_USER_HAS_PROFILE_OWNER; return CODE_USER_HAS_PROFILE_OWNER; Loading Loading @@ -12917,37 +12862,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return null; return null; } } // TODO (b/137101239): clean up split system user codes 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; } // TODO (b/137101239): clean up split system user codes 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() { private boolean hasFeatureManagedUsers() { try { try { return mIPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0); return mIPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0); Loading
core/api/test-current.txt +2 −2 Original line number Original line Diff line number Diff line Loading @@ -401,10 +401,10 @@ package android.app.admin { field public static final int CODE_MANAGED_USERS_NOT_SUPPORTED = 9; // 0x9 field public static final int CODE_MANAGED_USERS_NOT_SUPPORTED = 9; // 0x9 field public static final int CODE_NONSYSTEM_USER_EXISTS = 5; // 0x5 field public static final int CODE_NONSYSTEM_USER_EXISTS = 5; // 0x5 field public static final int CODE_NOT_SYSTEM_USER = 7; // 0x7 field public static final int CODE_NOT_SYSTEM_USER = 7; // 0x7 field public static final int CODE_NOT_SYSTEM_USER_SPLIT = 12; // 0xc field @Deprecated public static final int CODE_NOT_SYSTEM_USER_SPLIT = 12; // 0xc field public static final int CODE_OK = 0; // 0x0 field public static final int CODE_OK = 0; // 0x0 field public static final int CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS = 15; // 0xf field public static final int CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS = 15; // 0xf field public static final int CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14; // 0xe field @Deprecated public static final int CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14; // 0xe field public static final int CODE_SYSTEM_USER = 10; // 0xa field public static final int CODE_SYSTEM_USER = 10; // 0xa field public static final int CODE_USER_HAS_PROFILE_OWNER = 2; // 0x2 field public static final int CODE_USER_HAS_PROFILE_OWNER = 2; // 0x2 field public static final int CODE_USER_NOT_RUNNING = 3; // 0x3 field public static final int CODE_USER_NOT_RUNNING = 3; // 0x3 Loading
core/java/android/app/admin/DevicePolicyManager.java +23 −95 Original line number Original line Diff line number Diff line Loading @@ -452,59 +452,6 @@ public class DevicePolicyManager { public static final String ACTION_PROVISION_FINANCED_DEVICE = public static final String ACTION_PROVISION_FINANCED_DEVICE = "android.app.action.PROVISION_FINANCED_DEVICE"; "android.app.action.PROVISION_FINANCED_DEVICE"; /** * Activity action: Starts the provisioning flow which sets up a managed device. * Must be started with {@link android.app.Activity#startActivityForResult(Intent, int)}. * * <p>NOTE: This is only supported on split system user devices, and puts the device into a * management state that is distinct from that reached by * {@link #ACTION_PROVISION_MANAGED_DEVICE} - specifically the device owner runs on the system * user, and only has control over device-wide policies, not individual users and their data. * The primary benefit is that multiple non-system users are supported when provisioning using * this form of device management. * * <p>During device owner provisioning a device admin app is set as the owner of the device. * A device owner has full control over the device. The device owner can not be modified by the * user. * * <p>A typical use case would be a device that is owned by a company, but used by either an * employee or client. * * <p>An intent with this action can be sent only on an unprovisioned device. * It is possible to check if provisioning is allowed or not by querying the method * {@link #isProvisioningAllowed(String)}. * * <p>The intent contains the following extras: * <ul> * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}</li> * <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}, optional</li> * <li>{@link #EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED}, optional</li> * <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional</li> * <li>{@link #EXTRA_PROVISIONING_LOGO_URI}, optional</li> * <li>{@link #EXTRA_PROVISIONING_MAIN_COLOR}, optional</li> * </ul> * * <p>When device owner provisioning has completed, an intent of the type * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} is broadcast to the * device owner. * * <p>From version {@link android.os.Build.VERSION_CODES#O}, when device owner provisioning has * completed, along with the above broadcast, activity intent * {@link #ACTION_PROVISIONING_SUCCESSFUL} will also be sent to the device owner. * * <p>If provisioning fails, the device is factory reset. * * <p>A result code of {@link android.app.Activity#RESULT_OK} implies that the synchronous part * of the provisioning flow was successful, although this doesn't guarantee the full flow will * succeed. Conversely a result code of {@link android.app.Activity#RESULT_CANCELED} implies * that the user backed-out of provisioning, or some precondition for provisioning wasn't met. * * @hide */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE = "android.app.action.PROVISION_MANAGED_SHAREABLE_DEVICE"; /** /** * Activity action: Finalizes management provisioning, should be used after user-setup * Activity action: Finalizes management provisioning, should be used after user-setup * has been completed and {@link #getUserProvisioningState()} returns one of: * has been completed and {@link #getUserProvisioningState()} returns one of: Loading Loading @@ -1990,8 +1937,8 @@ public class DevicePolicyManager { * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, * {@link #ACTION_PROVISION_MANAGED_PROFILE}, {@link #ACTION_PROVISION_MANAGED_USER} and * {@link #ACTION_PROVISION_MANAGED_PROFILE} and {@link #ACTION_PROVISION_MANAGED_USER} * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when provisioning is allowed. * when provisioning is allowed. * * * @hide * @hide */ */ Loading @@ -2001,9 +1948,8 @@ public class DevicePolicyManager { /** /** * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} when the device already has a * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when the device already has a device * device owner. * owner. * * * @hide * @hide */ */ Loading @@ -2013,9 +1959,8 @@ public class DevicePolicyManager { /** /** * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} when the user has a profile owner * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when the user has a profile owner and for * and for {@link #ACTION_PROVISION_MANAGED_PROFILE} when the profile owner is already set. * {@link #ACTION_PROVISION_MANAGED_PROFILE} when the profile owner is already set. * * * @hide * @hide */ */ Loading @@ -2025,8 +1970,7 @@ public class DevicePolicyManager { /** /** * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} when the user isn't running. * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when the user isn't running. * * * @hide * @hide */ */ Loading @@ -2036,9 +1980,8 @@ public class DevicePolicyManager { /** /** * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} if the device has already been * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} if the device has already been setup and * setup and for {@link #ACTION_PROVISION_MANAGED_USER} if the user has already been setup. * for {@link #ACTION_PROVISION_MANAGED_USER} if the user has already been setup. * * * @hide * @hide */ */ Loading @@ -2064,8 +2007,7 @@ public class DevicePolicyManager { /** /** * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} if the user is not a system user. * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} if the user is not a system user. * * * @hide * @hide */ */ Loading @@ -2075,9 +2017,8 @@ public class DevicePolicyManager { /** /** * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} and {@link #ACTION_PROVISION_MANAGED_USER} * {@link #ACTION_PROVISION_MANAGED_USER} when the device is a watch and is already paired. * when the device is a watch and is already paired. * * * @hide * @hide */ */ Loading Loading @@ -2121,14 +2062,11 @@ public class DevicePolicyManager { /** /** * TODO (b/137101239): clean up split system user codes * TODO (b/137101239): clean up split system user codes * 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 * @hide */ * @deprecated not used anymore but can't be removed since it's a @TestApi. **/ @Deprecated @TestApi @TestApi public static final int CODE_NOT_SYSTEM_USER_SPLIT = 12; public static final int CODE_NOT_SYSTEM_USER_SPLIT = 12; Loading @@ -2136,8 +2074,7 @@ public class DevicePolicyManager { * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE}, * {@link #ACTION_PROVISION_MANAGED_PROFILE}, {@link #ACTION_PROVISION_MANAGED_USER} and * {@link #ACTION_PROVISION_MANAGED_PROFILE} on devices which do not support device * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} on devices which do not support device * admins. * admins. * * * @hide * @hide Loading @@ -2149,11 +2086,10 @@ public class DevicePolicyManager { * TODO (b/137101239): clean up split system user codes * TODO (b/137101239): clean up split system user codes * Result code for {@link #checkProvisioningPreCondition}. * Result code for {@link #checkProvisioningPreCondition}. * * * <p>Returned for {@link #ACTION_PROVISION_MANAGED_PROFILE} when the device the user is a * system user on a split system user device. * * @hide * @hide * @deprecated not used anymore but can't be removed since it's a @TestApi. */ */ @Deprecated @TestApi @TestApi public static final int CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14; public static final int CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14; Loading Loading @@ -7147,17 +7083,9 @@ public class DevicePolicyManager { } } /** /** * TODO (b/137101239): remove this method in follow-up CL * since it's only used for split system user. * Called by a device owner to set whether all users created on the device should be ephemeral. * Called by a device owner to set whether all users created on the device should be ephemeral. * <p> * The system user is exempt from this policy - it is never ephemeral. * <p> * The calling device admin must be the device owner. If it is not, a security exception will be * thrown. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param forceEphemeralUsers If true, all the existing users will be deleted and all * subsequently created users will be ephemeral. * @throws SecurityException if {@code admin} is not a device owner. * @hide * @hide */ */ public void setForceEphemeralUsers( public void setForceEphemeralUsers( Loading @@ -7173,6 +7101,8 @@ public class DevicePolicyManager { } } /** /** * TODO (b/137101239): remove this method in follow-up CL * since it's only used for split system user. * @return true if all users are created ephemeral. * @return true if all users are created ephemeral. * @throws SecurityException if {@code admin} is not a device owner. * @throws SecurityException if {@code admin} is not a device owner. * @hide * @hide Loading Loading @@ -10731,9 +10661,7 @@ public class DevicePolicyManager { * profile or user, setting the given package as owner. * profile or user, setting the given package as owner. * * * @param action One of {@link #ACTION_PROVISION_MANAGED_DEVICE}, * @param action One of {@link #ACTION_PROVISION_MANAGED_DEVICE}, * {@link #ACTION_PROVISION_MANAGED_PROFILE}, * {@link #ACTION_PROVISION_MANAGED_PROFILE} * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE}, * {@link #ACTION_PROVISION_MANAGED_USER} * @param packageName The package of the component that would be set as device, user, or profile * @param packageName The package of the component that would be set as device, user, or profile * owner. * owner. * @return A {@link ProvisioningPreCondition} value indicating whether provisioning is allowed. * @return A {@link ProvisioningPreCondition} value indicating whether provisioning is allowed. Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +13 −99 Original line number Original line Diff line number Diff line Loading @@ -35,10 +35,8 @@ 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_MANAGED_USERS_NOT_SUPPORTED; import static android.app.admin.DevicePolicyManager.CODE_NONSYSTEM_USER_EXISTS; 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; 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_OK; import static android.app.admin.DevicePolicyManager.CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS; import static android.app.admin.DevicePolicyManager.CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS; 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_SYSTEM_USER; import static android.app.admin.DevicePolicyManager.CODE_USER_HAS_PROFILE_OWNER; 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_NOT_RUNNING; Loading Loading @@ -1380,11 +1378,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { SystemProperties.set(key, value); SystemProperties.set(key, value); } } // TODO (b/137101239): clean up split system user codes boolean userManagerIsSplitSystemUser() { return UserManager.isSplitSystemUser(); } boolean userManagerIsHeadlessSystemUserMode() { boolean userManagerIsHeadlessSystemUserMode() { return UserManager.isHeadlessSystemUserMode(); return UserManager.isHeadlessSystemUserMode(); } } Loading Loading @@ -7404,48 +7397,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return mInjector.settingsGlobalGetInt(Global.AUTO_TIME_ZONE, 0) > 0; return mInjector.settingsGlobalGetInt(Global.AUTO_TIME_ZONE, 0) > 0; } } // TODO (b/137101239): remove this method in follow-up CL // since it's only used for split system user. @Override @Override public void setForceEphemeralUsers(ComponentName who, boolean forceEphemeralUsers) { public void setForceEphemeralUsers(ComponentName who, boolean forceEphemeralUsers) { if (!mHasFeature) { throw new UnsupportedOperationException("This method was used by split system user only."); return; } Objects.requireNonNull(who, "ComponentName is null"); final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isDeviceOwner(caller)); // Allow setting this policy to true only if there is a split system user. if (forceEphemeralUsers && !mInjector.userManagerIsSplitSystemUser()) { throw new UnsupportedOperationException( "Cannot force ephemeral users on systems without split system user."); } boolean removeAllUsers = false; synchronized (getLockObject()) { final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); if (deviceOwner.forceEphemeralUsers != forceEphemeralUsers) { deviceOwner.forceEphemeralUsers = forceEphemeralUsers; saveSettingsLocked(caller.getUserId()); mUserManagerInternal.setForceEphemeralUsers(forceEphemeralUsers); removeAllUsers = forceEphemeralUsers; } } if (removeAllUsers) { mInjector.binderWithCleanCallingIdentity(() -> mUserManagerInternal.removeAllUsers()); } } } // TODO (b/137101239): remove this method in follow-up CL // since it's only used for split system user. @Override @Override public boolean getForceEphemeralUsers(ComponentName who) { public boolean getForceEphemeralUsers(ComponentName who) { if (!mHasFeature) { throw new UnsupportedOperationException("This method was used by split system user only."); return false; } Objects.requireNonNull(who, "ComponentName is null"); final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isDeviceOwner(caller)); synchronized (getLockObject()) { final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); return deviceOwner.forceEphemeralUsers; } } } @Override @Override Loading Loading @@ -12733,13 +12696,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { case DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE: case DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE: case DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE: case DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE: return checkDeviceOwnerProvisioningPreCondition(callingUserId); return checkDeviceOwnerProvisioningPreCondition(callingUserId); // TODO (b/137101239): clean up split system user codes // ACTION_PROVISION_MANAGED_USER and ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE // only supported on split-user systems. case DevicePolicyManager.ACTION_PROVISION_MANAGED_USER: return checkManagedUserProvisioningPreCondition(callingUserId); case DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE: return checkManagedShareableDeviceProvisioningPreCondition(callingUserId); } } } } throw new IllegalArgumentException("Unknown provisioning action " + action); throw new IllegalArgumentException("Unknown provisioning action " + action); Loading Loading @@ -12775,14 +12731,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } } } // TODO (b/137101239): clean up split system user codes if (isAdb) { if (isAdb) { // If shell command runs after user setup completed check device status. Otherwise, OK. // If shell command runs after user setup completed check device status. Otherwise, OK. if (mIsWatch || hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { if (mIsWatch || hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { // In non-headless system user mode, DO can be setup only if // In non-headless system user mode, DO can be setup only if // there's no non-system user // there's no non-system user if (!mInjector.userManagerIsHeadlessSystemUserMode() if (!mInjector.userManagerIsHeadlessSystemUserMode() && !mInjector.userManagerIsSplitSystemUser() && mUserManager.getUserCount() > 1) { && mUserManager.getUserCount() > 1) { return CODE_NONSYSTEM_USER_EXISTS; return CODE_NONSYSTEM_USER_EXISTS; } } Loading @@ -12801,17 +12755,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } return CODE_OK; return CODE_OK; } else { } else { if (!mInjector.userManagerIsSplitSystemUser()) { // DO has to be user 0 // In non-split user mode, DO has to be user 0 if (deviceOwnerUserId != UserHandle.USER_SYSTEM) { if (deviceOwnerUserId != UserHandle.USER_SYSTEM) { return CODE_NOT_SYSTEM_USER; return CODE_NOT_SYSTEM_USER; } } // Only provision DO before setup wizard completes // Only provision DO before setup wizard completes // TODO (b/171423186): implement deferred DO setup for headless system user mode if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { return CODE_USER_SETUP_COMPLETED; return CODE_USER_SETUP_COMPLETED; } } } return CODE_OK; return CODE_OK; } } } } Loading @@ -12831,17 +12782,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } } } // TODO (b/137101239): clean up split system user codes private int checkManagedProfileProvisioningPreCondition(String packageName, private int checkManagedProfileProvisioningPreCondition(String packageName, @UserIdInt int callingUserId) { @UserIdInt int callingUserId) { if (!hasFeatureManagedUsers()) { if (!hasFeatureManagedUsers()) { return CODE_MANAGED_USERS_NOT_SUPPORTED; return CODE_MANAGED_USERS_NOT_SUPPORTED; } } if (callingUserId == UserHandle.USER_SYSTEM && mInjector.userManagerIsSplitSystemUser()) { // Managed-profiles cannot be setup on the system user. return CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER; } if (getProfileOwnerAsUser(callingUserId) != null) { if (getProfileOwnerAsUser(callingUserId) != null) { // Managed user cannot have a managed profile. // Managed user cannot have a managed profile. return CODE_USER_HAS_PROFILE_OWNER; return CODE_USER_HAS_PROFILE_OWNER; Loading Loading @@ -12917,37 +12862,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return null; return null; } } // TODO (b/137101239): clean up split system user codes 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; } // TODO (b/137101239): clean up split system user codes 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() { private boolean hasFeatureManagedUsers() { try { try { return mIPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0); return mIPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0);