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

Commit efdaf390 authored by Kholoud Mohamed's avatar Kholoud Mohamed
Browse files

Single user headless DO fixes

Bug: 289515470
Test: atest android.devicepolicy.cts.BackupTest
Test: atest android.devicepolicy.cts.KeyManagementTest
Change-Id: Ie99e085bb4eb8c5af41bbe1ad69f584654a37352
parent 04b0de05
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -253,3 +253,13 @@ flag {
      purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "headless_single_user_fixes"
    namespace: "enterprise"
    description: "Various fixes for headless single user mode"
    bug: "289515470"
    metadata {
      purpose: PURPOSE_BUGFIX
    }
}
+48 −15
Original line number Diff line number Diff line
@@ -819,6 +819,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
    public static final long THROW_SECURITY_EXCEPTION_FOR_SENSOR_PERMISSIONS = 277035314L;
    /**
     * Allows DPCs to provisioning fully managed headless devices in single-user mode.
     */
    @ChangeId
    @EnabledSince(targetSdkVersion = 35)
    public static final long PROVISION_SINGLE_USER_MODE = 289515470L;
    // Only add to the end of the list. Do not change or rearrange these values, that will break
    // historical data. Do not use negative numbers or zero, logger only handles positive
    // integers.
@@ -6856,7 +6863,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        // If there is a profile owner, redirect to that; otherwise query the device owner.
        ComponentName aliasChooser = getProfileOwnerAsUser(caller.getUserId());
        if (aliasChooser == null && caller.getUserHandle().isSystem()) {
        boolean isDoUser = Flags.headlessSingleUserFixes()
                ? caller.getUserId() == getDeviceOwnerUserId()
                : caller.getUserHandle().isSystem();
        if (aliasChooser == null && isDoUser) {
            synchronized (getLockObject()) {
                final ActiveAdmin deviceOwnerAdmin = getDeviceOwnerAdminLocked();
                if (deviceOwnerAdmin != null) {
@@ -7850,7 +7860,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        mInjector.binderWithCleanCallingIdentity(() -> {
            // First check whether the admin is allowed to wipe the device/user/profile.
            final String restriction;
            if (userId == UserHandle.USER_SYSTEM) {
            boolean shouldFactoryReset = userId == UserHandle.USER_SYSTEM;
            if (Flags.headlessSingleUserFixes() && getHeadlessDeviceOwnerModeForDeviceOwner()
                    == HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER) {
                shouldFactoryReset = userId == getMainUserId();
            }
            if (shouldFactoryReset) {
                restriction = UserManager.DISALLOW_FACTORY_RESET;
            } else if (isManagedProfile(userId)) {
                restriction = UserManager.DISALLOW_REMOVE_MANAGED_PROFILE;
@@ -7864,12 +7879,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        });
        boolean isSystemUser = userId == UserHandle.USER_SYSTEM;
        boolean isMainUser = userId == getMainUserId();
        boolean wipeDevice;
        if (factoryReset == null || !mInjector.isChangeEnabled(EXPLICIT_WIPE_BEHAVIOUR,
                adminPackage,
                userId)) {
            // Legacy mode
            wipeDevice = isSystemUser;
            wipeDevice = Flags.headlessSingleUserFixes()
                    && getHeadlessDeviceOwnerModeForDeviceOwner()
                    == HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER ? isMainUser : isSystemUser;
        } else {
            // Explicit behaviour
            if (factoryReset) {
@@ -8207,6 +8225,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                            userHandle, /* parent= */ false);
                    int max = strictestAdmin != null
                            ? strictestAdmin.maximumFailedPasswordsForWipe : 0;
                    if (max > 0 && policy.mFailedPasswordAttempts >= max) {
                        wipeData = true;
                    }
@@ -18428,6 +18447,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller)
                || isProfileOwner(caller) || isFinancedDeviceOwner(caller));
        // Backup service has to be enabled on the main user in order for it to be enabled on
        // secondary users.
        if (Flags.headlessSingleUserFixes() && isDeviceOwner(caller)
                && getHeadlessDeviceOwnerModeForDeviceOwner()
                == HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER) {
            toggleBackupServiceActive(UserHandle.USER_SYSTEM, enabled);
        }
        toggleBackupServiceActive(caller.getUserId(), enabled);
        if (Flags.backupServiceSecurityLogEventEnabled()) {
@@ -21747,7 +21774,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        Objects.requireNonNull(deviceAdmin, "admin is null.");
        Objects.requireNonNull(provisioningParams.getOwnerName(), "owner name is null.");
        final CallerIdentity caller = getCallerIdentity();
        final CallerIdentity caller = getCallerIdentity(callerPackage);
        Preconditions.checkCallAuthorization(
                hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS)
                        || (hasCallingOrSelfPermission(permission.PROVISION_DEMO_DEVICE)
@@ -21757,6 +21784,23 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        final long identity = Binder.clearCallingIdentity();
        try {
            boolean isSingleUserMode;
            if (Flags.headlessDeviceOwnerProvisioningFixEnabled()) {
                int headlessDeviceOwnerMode = getHeadlessDeviceOwnerModeForDeviceAdmin(
                        deviceAdmin, caller.getUserId());
                isSingleUserMode =
                        headlessDeviceOwnerMode == HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER;
            } else {
                isSingleUserMode =
                        getHeadlessDeviceOwnerModeForDeviceOwner()
                                == HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER;
            }
            if (Flags.headlessSingleUserFixes() && isSingleUserMode && !mInjector.isChangeEnabled(
                    PROVISION_SINGLE_USER_MODE, deviceAdmin.getPackageName(), caller.getUserId())) {
                throw new IllegalStateException("Device admin is not targeting Android V.");
            }
            int result = checkProvisioningPreconditionSkipPermission(
                    ACTION_PROVISION_MANAGED_DEVICE, deviceAdmin, caller.getUserId());
            if (result != STATUS_OK) {
@@ -21770,17 +21814,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            setTimeAndTimezone(provisioningParams.getTimeZone(), provisioningParams.getLocalTime());
            setLocale(provisioningParams.getLocale());
            boolean isSingleUserMode;
            if (Flags.headlessDeviceOwnerProvisioningFixEnabled()) {
                int headlessDeviceOwnerMode = getHeadlessDeviceOwnerModeForDeviceAdmin(
                        deviceAdmin, caller.getUserId());
                isSingleUserMode =
                        headlessDeviceOwnerMode == HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER;
            } else {
                isSingleUserMode =
                        getHeadlessDeviceOwnerModeForDeviceOwner()
                                == HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER;
            }
            int deviceOwnerUserId = Flags.headlessDeviceOwnerSingleUserEnabled()
                    && isSingleUserMode
                    ? mUserManagerInternal.getMainUserId() : UserHandle.USER_SYSTEM;