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

Commit d3432a4d authored by Felipe Leme's avatar Felipe Leme Committed by Automerger Merge Worker
Browse files

Merge "Improved error message when PO / DO cannot be set by adb." into udc-dev am: 83bad42d

parents 417e158c 83bad42d
Loading
Loading
Loading
Loading
+97 −20
Original line number Original line Diff line number Diff line
@@ -10617,38 +10617,59 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
     * - SYSTEM_UID
     * - SYSTEM_UID
     * - adb unless hasIncompatibleAccountsOrNonAdb is true.
     * - adb unless hasIncompatibleAccountsOrNonAdb is true.
     */
     */
    @GuardedBy("getLockObject()")
    private void enforceCanSetProfileOwnerLocked(
    private void enforceCanSetProfileOwnerLocked(
            CallerIdentity caller, @Nullable ComponentName owner, int userHandle,
            CallerIdentity caller, @Nullable ComponentName owner, @UserIdInt int userId,
            boolean hasIncompatibleAccountsOrNonAdb) {
            boolean hasIncompatibleAccountsOrNonAdb) {
        UserInfo info = getUserInfo(userHandle);
        UserInfo info = getUserInfo(userId);
        if (info == null) {
        if (info == null) {
            // User doesn't exist.
            // User doesn't exist.
            throw new IllegalArgumentException(
            throw new IllegalArgumentException(
                    "Attempted to set profile owner for invalid userId: " + userHandle);
                    "Attempted to set profile owner for invalid userId: " + userId);
        }
        }
        if (info.isGuest()) {
        if (info.isGuest()) {
            throw new IllegalStateException("Cannot set a profile owner on a guest");
            throw new IllegalStateException("Cannot set a profile owner on a guest");
        }
        }
        if (mOwners.hasProfileOwner(userHandle)) {
        if (mOwners.hasProfileOwner(userId)) {
            throw new IllegalStateException("Trying to set the profile owner, but profile owner "
            StringBuilder errorMessage = new StringBuilder("Trying to set the profile owner");
                    + "is already set.");
            if (!hasIncompatibleAccountsOrNonAdb) {
                append(errorMessage, owner).append(" on user ").append(userId);
            }
            errorMessage.append(", but profile owner");
            if (!hasIncompatibleAccountsOrNonAdb) {
                appendProfileOwnerLocked(errorMessage, userId);
            }
            throw new IllegalStateException(errorMessage.append(" is already set.").toString());
        }
        if (mOwners.hasDeviceOwner() && mOwners.getDeviceOwnerUserId() == userId) {
            StringBuilder errorMessage = new StringBuilder("Trying to set the profile owner");
            if (!hasIncompatibleAccountsOrNonAdb) {
                append(errorMessage, owner).append(" on user ").append(userId);
            }
            errorMessage.append(", but the user already has a device owner");
            if (!hasIncompatibleAccountsOrNonAdb) {
                appendDeviceOwnerLocked(errorMessage);
            }
            }
        if (mOwners.hasDeviceOwner() && mOwners.getDeviceOwnerUserId() == userHandle) {
            throw new IllegalStateException(errorMessage.append('.').toString());
            throw new IllegalStateException("Trying to set the profile owner, but the user "
                    + "already has a device owner.");
        }
        }
        if (isAdb(caller)) {
        if (isAdb(caller)) {
            if ((mIsWatch || hasUserSetupCompleted(userHandle))
            if ((mIsWatch || hasUserSetupCompleted(userId))
                    && hasIncompatibleAccountsOrNonAdb) {
                    && hasIncompatibleAccountsOrNonAdb) {
                throw new IllegalStateException("Not allowed to set the profile owner because "
                StringBuilder errorMessage = new StringBuilder("Not allowed to set the profile "
                        + "there are already some accounts on the profile");
                        + "owner");
                if (!hasIncompatibleAccountsOrNonAdb) {
                    append(errorMessage, owner).append(" on user ").append(userId).append(' ');
                }
                throw new IllegalStateException(errorMessage.append(" because there are already "
                        + "some accounts on the profile.").toString());
            }
            }
            return;
            return;
        }
        }
        Preconditions.checkCallAuthorization(
        Preconditions.checkCallAuthorization(
                hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
                hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
        if ((mIsWatch || hasUserSetupCompleted(userHandle))) {
        if ((mIsWatch || hasUserSetupCompleted(userId))) {
            Preconditions.checkState(isSystemUid(caller),
            Preconditions.checkState(isSystemUid(caller),
                    "Cannot set the profile owner on a user which is already set-up");
                    "Cannot set the profile owner on a user which is already set-up");
@@ -10665,31 +10686,62 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
     * The Device owner can only be set by adb or an app with the MANAGE_PROFILE_AND_DEVICE_OWNERS
     * The Device owner can only be set by adb or an app with the MANAGE_PROFILE_AND_DEVICE_OWNERS
     * permission.
     * permission.
     */
     */
    @GuardedBy("getLockObject()")
    private void enforceCanSetDeviceOwnerLocked(
    private void enforceCanSetDeviceOwnerLocked(
            CallerIdentity caller, @Nullable ComponentName owner, @UserIdInt int deviceOwnerUserId,
            CallerIdentity caller, @Nullable ComponentName owner, @UserIdInt int deviceOwnerUserId,
            boolean hasIncompatibleAccountsOrNonAdb) {
            boolean hasIncompatibleAccountsOrNonAdb) {
        boolean showComponentOnError = false;
        if (!isAdb(caller)) {
        if (!isAdb(caller)) {
            Preconditions.checkCallAuthorization(
            Preconditions.checkCallAuthorization(
                    hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
                    hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
        } else {
            showComponentOnError = true;
        }
        }
        final int code = checkDeviceOwnerProvisioningPreConditionLocked(owner,
        final int code = checkDeviceOwnerProvisioningPreConditionLocked(owner,
                /* deviceOwnerUserId= */ deviceOwnerUserId, /* callingUserId*/ caller.getUserId(),
                /* deviceOwnerUserId= */ deviceOwnerUserId, /* callingUserId*/ caller.getUserId(),
                isAdb(caller), hasIncompatibleAccountsOrNonAdb);
                isAdb(caller), hasIncompatibleAccountsOrNonAdb);
        if (code != STATUS_OK) {
        if (code != STATUS_OK) {
            throw new IllegalStateException(
            throw new IllegalStateException(computeProvisioningErrorStringLocked(code,
                    computeProvisioningErrorString(code, deviceOwnerUserId));
                    deviceOwnerUserId, owner, showComponentOnError));
        }
        }
    }
    }
    private static String computeProvisioningErrorString(int code, @UserIdInt int userId) {
    private String computeProvisioningErrorString(int code, @UserIdInt int userId) {
        synchronized (getLockObject()) {
            return computeProvisioningErrorStringLocked(code, userId, /* newOwner= */ null,
                    /* showComponentOnError= */ false);
        }
    }
    @GuardedBy("getLockObject()")
    private String computeProvisioningErrorStringLocked(int code, @UserIdInt int userId,
            @Nullable ComponentName newOwner, boolean showComponentOnError) {
        switch (code) {
        switch (code) {
            case STATUS_OK:
            case STATUS_OK:
                return "OK";
                return "OK";
            case STATUS_HAS_DEVICE_OWNER:
            case STATUS_HAS_DEVICE_OWNER: {
                return "Trying to set the device owner, but device owner is already set.";
                StringBuilder error = new StringBuilder("Trying to set the device owner");
            case STATUS_USER_HAS_PROFILE_OWNER:
                if (showComponentOnError && newOwner != null) {
                return "Trying to set the device owner, but the user already has a profile owner.";
                    append(error, newOwner);
                }
                error.append(", but device owner");
                if (showComponentOnError) {
                    appendDeviceOwnerLocked(error);
                }
                return error.append(" is already set.").toString();
            }
            case STATUS_USER_HAS_PROFILE_OWNER: {
                StringBuilder error = new StringBuilder("Trying to set the device owner");
                if (showComponentOnError && newOwner != null) {
                    append(error, newOwner);
                }
                error.append(", but the user already has a profile owner");
                if (showComponentOnError) {
                    appendProfileOwnerLocked(error, userId);
                }
                return error.append(".").toString();
            }
            case STATUS_USER_NOT_RUNNING:
            case STATUS_USER_NOT_RUNNING:
                return "User " + userId + " not running.";
                return "User " + userId + " not running.";
            case STATUS_NOT_SYSTEM_USER:
            case STATUS_NOT_SYSTEM_USER:
@@ -10708,7 +10760,32 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            default:
            default:
                return "Unexpected @ProvisioningPreCondition: " + code;
                return "Unexpected @ProvisioningPreCondition: " + code;
        }
        }
    }
    @GuardedBy("getLockObject()")
    private void appendDeviceOwnerLocked(StringBuilder string) {
        ComponentName deviceOwner = getDeviceOwnerComponent(/* callingUserOnly= */ false);
        if (deviceOwner == null) {
            // Shouldn't happen, but it doesn't hurt to check...
            Slogf.wtf(LOG_TAG, "appendDeviceOwnerLocked(): device has no DO set");
            return;
        }
        append(string, deviceOwner);
    }
    @GuardedBy("getLockObject()")
    private void appendProfileOwnerLocked(StringBuilder string, @UserIdInt int userId) {
        ComponentName profileOwner = mOwners.getProfileOwnerComponent(userId);
        if (profileOwner == null) {
            // Shouldn't happen, but it doesn't hurt to check...
            Slogf.wtf(LOG_TAG, "profileOwner(%d): PO not set", userId);
            return;
        }
        append(string, profileOwner);
    }
    private static StringBuilder append(StringBuilder string, ComponentName component) {
        return string.append(" (").append(component.flattenToShortString()).append(')');
    }
    }
    private void enforceUserUnlocked(int userId) {
    private void enforceUserUnlocked(int userId) {