Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e7a937b0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Clean up split system user code for device policy management" into sc-dev

parents ae26632f 3ea0eb2b
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -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
+23 −95
Original line number Original line Diff line number Diff line
@@ -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:
@@ -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
     */
     */
@@ -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
     */
     */
@@ -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
     */
     */
@@ -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
     */
     */
@@ -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
     */
     */
@@ -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
     */
     */
@@ -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
     */
     */
@@ -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;
@@ -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
@@ -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;
@@ -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(
@@ -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
@@ -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.
+13 −99
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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();
        }
        }
@@ -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
@@ -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);
@@ -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;
                }
                }
@@ -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;
        }
        }
    }
    }
@@ -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;
@@ -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);