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

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

Merge "Make LSS report honest password quality to DPMS"

parents 75eaf771 19a4fb3f
Loading
Loading
Loading
Loading
+29 −6
Original line number Diff line number Diff line
@@ -24,8 +24,12 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;

import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.app.admin.DevicePolicyManager.PasswordComplexity;
@@ -33,13 +37,15 @@ import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
import com.android.internal.widget.LockPatternUtils.CredentialType;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * A class that represents the metrics of a password that are used to decide whether or not a
 * password meets the requirements.
 * A class that represents the metrics of a credential that are used to decide whether or not a
 * credential meets the requirements. If the credential is a pattern, only quality matters.
 *
 * {@hide}
 */
@@ -48,8 +54,6 @@ public class PasswordMetrics implements Parcelable {
    // consider it a complex PIN/password.
    public static final int MAX_ALLOWED_SEQUENCE = 3;

    // TODO(b/120536847): refactor isActivePasswordSufficient logic so that the actual password
    // quality is not overwritten
    public int quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
    public int length = 0;
    public int letters = 0;
@@ -221,6 +225,25 @@ public class PasswordMetrics implements Parcelable {
        }
    };

    /**
     * Returnsthe {@code PasswordMetrics} for a given credential.
     *
     * If the credential is a pin or a password, equivalent to {@link #computeForPassword(byte[])}.
     * {@code credential} cannot be null when {@code type} is
     * {@link com.android.internal.widget.LockPatternUtils#CREDENTIAL_TYPE_PASSWORD}.
     */
    public static PasswordMetrics computeForCredential(
            @CredentialType int type, byte[] credential) {
        if (type == CREDENTIAL_TYPE_PASSWORD) {
            Preconditions.checkNotNull(credential, "credential cannot be null");
            return PasswordMetrics.computeForPassword(credential);
        } else if (type == CREDENTIAL_TYPE_PATTERN)  {
            return new PasswordMetrics(PASSWORD_QUALITY_SOMETHING);
        } else /* if (type == CREDENTIAL_TYPE_NONE) */ {
            return new PasswordMetrics(PASSWORD_QUALITY_UNSPECIFIED);
        }
    }

    /**
     * Returns the {@code PasswordMetrics} for a given password
     */
@@ -233,8 +256,8 @@ public class PasswordMetrics implements Parcelable {
        int symbols = 0;
        int nonLetter = 0;
        final int length = password.length;
        for (int i = 0; i < length; i++) {
            switch (categoryChar((char) password[i])) {
        for (byte b : password) {
            switch (categoryChar((char) b)) {
                case CHAR_LOWER_CASE:
                    letters++;
                    lowerCase++;
+31 −37
Original line number Diff line number Diff line
@@ -78,7 +78,6 @@ import java.util.StringJoiner;
public class LockPatternUtils {

    private static final String TAG = "LockPatternUtils";
    private static final boolean DEBUG = false;
    private static final boolean FRP_CREDENTIAL_ENABLED = true;

    /**
@@ -86,12 +85,6 @@ public class LockPatternUtils {
     */
    public static final String LEGACY_LOCK_PATTERN_ENABLED = "legacy_lock_pattern_enabled";

    /**
     * The number of incorrect attempts before which we fall back on an alternative
     * method of verifying the user, and resetting their lock pattern.
     */
    public static final int FAILED_ATTEMPTS_BEFORE_RESET = 20;

    /**
     * The interval of the countdown for showing progress of the lockout.
     */
@@ -115,18 +108,23 @@ public class LockPatternUtils {
    public static final int MIN_LOCK_PASSWORD_SIZE = 4;

    /**
     * The minimum number of dots the user must include in a wrong pattern
     * attempt for it to be counted against the counts that affect
     * {@link #FAILED_ATTEMPTS_BEFORE_TIMEOUT} and {@link #FAILED_ATTEMPTS_BEFORE_RESET}
     * The minimum number of dots the user must include in a wrong pattern attempt for it to be
     * counted.
     */
    public static final int MIN_PATTERN_REGISTER_FAIL = MIN_LOCK_PATTERN_SIZE;

    public static final int CREDENTIAL_TYPE_NONE = -1;

    public static final int CREDENTIAL_TYPE_PATTERN = 1;

    public static final int CREDENTIAL_TYPE_PASSWORD = 2;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"CREDENTIAL_TYPE_"}, value = {
            CREDENTIAL_TYPE_NONE,
            CREDENTIAL_TYPE_PATTERN,
            CREDENTIAL_TYPE_PASSWORD, // Either pin or password.
    })
    public @interface CredentialType {}

    /**
     * Special user id for triggering the FRP verification flow.
     */
@@ -915,9 +913,10 @@ public class LockPatternUtils {
        }

        final int currentQuality = getKeyguardStoredPasswordQuality(userHandle);
        setKeyguardStoredPasswordQuality(
                computePasswordQuality(CREDENTIAL_TYPE_PASSWORD, password, requestedQuality),
                userHandle);
        final int passwordQuality = PasswordMetrics.computeForPassword(password).quality;
        final int newKeyguardQuality =
                computeKeyguardQuality(CREDENTIAL_TYPE_PASSWORD, requestedQuality, passwordQuality);
        setKeyguardStoredPasswordQuality(newKeyguardQuality, userHandle);
        try {
            getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword,
                    requestedQuality, userHandle);
@@ -927,12 +926,24 @@ public class LockPatternUtils {
            return;
        }

        updateEncryptionPasswordIfNeeded(password,
                PasswordMetrics.computeForPassword(password).quality, userHandle);
        updateEncryptionPasswordIfNeeded(password, passwordQuality, userHandle);
        updatePasswordHistory(password, userHandle);
        onAfterChangingPassword(userHandle);
    }

    /**
     * Compute keyguard credential quality to store in PASSWORD_TYPE_KEY by computing max between
     * them so that digit-only password is distinguished from PIN.
     *
     * TODO: remove this method and make CREDENTIAL_TYPE distinguish between PIN and password, so
     * that this quality is no longer needs to be persisted.
     */
    private int computeKeyguardQuality(
            @CredentialType int credentialType, int requestedQuality, int passwordQuality) {
        return credentialType == CREDENTIAL_TYPE_PASSWORD
                ? Math.max(passwordQuality, requestedQuality) : passwordQuality;
    }

    /**
     * Update device encryption password if calling user is USER_SYSTEM and device supports
     * encryption.
@@ -1032,24 +1043,6 @@ public class LockPatternUtils {
        setLong(PASSWORD_TYPE_KEY, quality, userHandle);
    }

    /**
     * Returns the password quality of the given credential, promoting it to a higher level
     * if DevicePolicyManager has a stronger quality requirement. This value will be written
     * to PASSWORD_TYPE_KEY.
     */
    private int computePasswordQuality(int type, byte[] credential, int requestedQuality) {
        final int quality;
        if (type == CREDENTIAL_TYPE_PASSWORD) {
            int computedQuality = PasswordMetrics.computeForPassword(credential).quality;
            quality = Math.max(requestedQuality, computedQuality);
        } else if (type == CREDENTIAL_TYPE_PATTERN)  {
            quality = PASSWORD_QUALITY_SOMETHING;
        } else /* if (type == CREDENTIAL_TYPE_NONE) */ {
            quality = PASSWORD_QUALITY_UNSPECIFIED;
        }
        return quality;
    }

    /**
     * Enables/disables the Separate Profile Challenge for this {@param userHandle}. This is a no-op
     * for user handles that do not belong to a managed profile.
@@ -1752,9 +1745,10 @@ public class LockPatternUtils {
                throw new IllegalArgumentException("password must not be null and at least "
                        + "of length " + MIN_LOCK_PASSWORD_SIZE);
            }
            final int quality = computePasswordQuality(type, credential, requestedQuality);
            final int quality = PasswordMetrics.computeForCredential(type, credential).quality;
            final int keyguardQuality = computeKeyguardQuality(type, quality, requestedQuality);
            if (!localService.setLockCredentialWithToken(credential, type, tokenHandle, token,
                    quality, userId)) {
                    keyguardQuality, userId)) {
                return false;
            }
            setKeyguardStoredPasswordQuality(quality, userId);
+45 −49
Original line number Diff line number Diff line
@@ -21,6 +21,9 @@ import static android.Manifest.permission.READ_CONTACTS;
import static android.content.Context.KEYGUARD_SERVICE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;

import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
@@ -106,6 +109,7 @@ import com.android.internal.util.Preconditions;
import com.android.internal.widget.ICheckCredentialProgressCallback;
import com.android.internal.widget.ILockSettings;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternUtils.CredentialType;
import com.android.internal.widget.LockSettingsInternal;
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.server.LocalServices;
@@ -319,7 +323,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            }
            Arrays.fill(newPasswordChars, '\u0000');
            final int quality = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
            setLockCredentialInternal(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
            setLockCredentialInternal(newPassword, CREDENTIAL_TYPE_PASSWORD,
                    managedUserPassword, quality, managedUserId);
            // We store a private credential for the managed user that's unlocked by the primary
            // account holder's credential. As such, the user will never be prompted to enter this
@@ -1082,13 +1086,12 @@ public class LockSettingsService extends ILockSettings.Stub {
    }

    @Override
    public boolean havePassword(int userId) throws RemoteException {
    public boolean havePassword(int userId) {
        checkPasswordHavePermission(userId);
        synchronized (mSpManager) {
            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
                long handle = getSyntheticPasswordHandleLocked(userId);
                return mSpManager.getCredentialType(handle, userId) ==
                        LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
                final long handle = getSyntheticPasswordHandleLocked(userId);
                return mSpManager.getCredentialType(handle, userId) == CREDENTIAL_TYPE_PASSWORD;
            }
        }
        // Do we need a permissions check here?
@@ -1096,13 +1099,12 @@ public class LockSettingsService extends ILockSettings.Stub {
    }

    @Override
    public boolean havePattern(int userId) throws RemoteException {
    public boolean havePattern(int userId) {
        checkPasswordHavePermission(userId);
        synchronized (mSpManager) {
            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
                long handle = getSyntheticPasswordHandleLocked(userId);
                return mSpManager.getCredentialType(handle, userId) ==
                        LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
                final long handle = getSyntheticPasswordHandleLocked(userId);
                return mSpManager.getCredentialType(handle, userId) == CREDENTIAL_TYPE_PATTERN;
            }
        }
        // Do we need a permissions check here?
@@ -1112,9 +1114,8 @@ public class LockSettingsService extends ILockSettings.Stub {
    private boolean isUserSecure(int userId) {
        synchronized (mSpManager) {
            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
                long handle = getSyntheticPasswordHandleLocked(userId);
                return mSpManager.getCredentialType(handle, userId) !=
                        LockPatternUtils.CREDENTIAL_TYPE_NONE;
                final long handle = getSyntheticPasswordHandleLocked(userId);
                return mSpManager.getCredentialType(handle, userId) != CREDENTIAL_TYPE_NONE;
            }
        }
        return mStorage.hasCredential(userId);
@@ -1167,7 +1168,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            throws RemoteException {
        try {
            doVerifyCredential(getDecryptedPasswordForTiedProfile(profileHandle),
                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
                    CREDENTIAL_TYPE_PASSWORD,
                    false, 0 /* no challenge */, profileHandle, null /* progressCallback */);
        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
                | NoSuchAlgorithmException | NoSuchPaddingException
@@ -1299,13 +1300,13 @@ public class LockSettingsService extends ILockSettings.Stub {
                    // We use cached work profile password computed before clearing the parent's
                    // credential, otherwise they get lost
                    if (profilePasswordMap != null && profilePasswordMap.containsKey(managedUserId)) {
                        setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
                        setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE,
                                profilePasswordMap.get(managedUserId),
                                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId);
                    } else {
                        Slog.wtf(TAG, "clear tied profile challenges, but no password supplied.");
                        // Supplying null here would lead to untrusted credential change
                        setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, null,
                        setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE, null,
                                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId);
                    }
                    mStorage.removeChildProfileLock(managedUserId);
@@ -1345,7 +1346,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        notifySeparateProfileChallengeChanged(userId);
    }

    private void setLockCredentialInternal(byte[] credential, int credentialType,
    private void setLockCredentialInternal(byte[] credential, @CredentialType int credentialType,
            byte[] savedCredential, int requestedQuality, int userId) throws RemoteException {
        // Normalize savedCredential and credential such that empty string is always represented
        // as null.
@@ -1363,7 +1364,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            }
        }

        if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
        if (credentialType == CREDENTIAL_TYPE_NONE) {
            if (credential != null) {
                Slog.wtf(TAG, "CredentialType is none, but credential is non-null.");
            }
@@ -1373,7 +1374,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            setKeystorePassword(null, userId);
            fixateNewestUserKeyAuth(userId);
            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
            notifyActivePasswordMetricsAvailable(null, userId);
            notifyActivePasswordMetricsAvailable(CREDENTIAL_TYPE_NONE, null, userId);
            mRecoverableKeyStoreManager.lockScreenSecretChanged(credentialType, credential, userId);
            return;
        }
@@ -1431,8 +1432,7 @@ public class LockSettingsService extends ILockSettings.Stub {
                userId);
        } else {
            throw new RemoteException("Failed to enroll " +
                    (credentialType == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD ? "password"
                            : "pattern"));
                    (credentialType == CREDENTIAL_TYPE_PASSWORD ? "password" : "pattern"));
        }
    }

@@ -1688,7 +1688,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            return VerifyCredentialResponse.ERROR;
        }

        boolean shouldReEnrollBaseZero = storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
        boolean shouldReEnrollBaseZero = storedHash.type == CREDENTIAL_TYPE_PATTERN
                && storedHash.isBaseZeroPattern;

        byte[] credentialToVerify;
@@ -1736,7 +1736,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        try {
            // Unlock work profile, and work profile with unified lock must use password only
            return doVerifyCredential(getDecryptedPasswordForTiedProfile(userId),
                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
                    CREDENTIAL_TYPE_PASSWORD,
                    true,
                    challenge,
                    userId, null /* progressCallback */);
@@ -1773,14 +1773,14 @@ public class LockSettingsService extends ILockSettings.Stub {

        if (storedHash.version == CredentialHash.VERSION_LEGACY) {
            final byte[] hash;
            if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
            if (storedHash.type == CREDENTIAL_TYPE_PATTERN) {
                hash = LockPatternUtils.patternToHash(
                        LockPatternUtils.byteArrayToPattern(credential));
            } else {
                hash = mLockPatternUtils.legacyPasswordToHash(credential, userId).getBytes();
            }
            if (Arrays.equals(hash, storedHash.hash)) {
                if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
                if (storedHash.type == CREDENTIAL_TYPE_PATTERN) {
                    unlockKeystore(LockPatternUtils.patternByteArrayToBaseZero(credential), userId);
                } else {
                    unlockKeystore(credential, userId);
@@ -1793,12 +1793,12 @@ public class LockSettingsService extends ILockSettings.Stub {

                // migrate credential to GateKeeper
                setLockCredentialInternal(credential, storedHash.type, null,
                        storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
                        storedHash.type == CREDENTIAL_TYPE_PATTERN
                                ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
                                : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
                                /* TODO(roosa): keep the same password quality */, userId);
                if (!hasChallenge) {
                    notifyActivePasswordMetricsAvailable(credential, userId);
                    notifyActivePasswordMetricsAvailable(storedHash.type, credential, userId);
                    // Use credentials to create recoverable keystore snapshot.
                    mRecoverableKeyStoreManager.lockScreenSecretAvailable(
                            storedHash.type, credential, userId);
@@ -1823,7 +1823,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            if (progressCallback != null) {
                progressCallback.onCredentialVerified();
            }
            notifyActivePasswordMetricsAvailable(credential, userId);
            notifyActivePasswordMetricsAvailable(storedHash.type, credential, userId);
            unlockKeystore(credential, userId);

            Slog.i(TAG, "Unlocking user " + userId + " with token length "
@@ -1835,7 +1835,7 @@ public class LockSettingsService extends ILockSettings.Stub {
                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
                trustManager.setDeviceLockedForUser(userId, false);
            }
            int reEnrollQuality = storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
            int reEnrollQuality = storedHash.type == CREDENTIAL_TYPE_PATTERN
                    ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
                    : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
                    /* TODO(roosa): keep the same password quality */;
@@ -1871,18 +1871,14 @@ public class LockSettingsService extends ILockSettings.Stub {
     * Call this method to notify DPMS regarding the latest password metric. This should be called
     * when the user is authenticating or when a new password is being set.
     */
    private void notifyActivePasswordMetricsAvailable(byte[] password, @UserIdInt int userId) {
        final PasswordMetrics metrics;
        if (password == null) {
            metrics = new PasswordMetrics();
        } else {
            metrics = PasswordMetrics.computeForPassword(password);
            metrics.quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(userId);
        }
    private void notifyActivePasswordMetricsAvailable(
            @CredentialType int credentialType, byte[] password, @UserIdInt int userId) {
        final PasswordMetrics metrics =
                PasswordMetrics.computeForCredential(credentialType, password);

        // Asynchronous to avoid dead lock
        mHandler.post(() -> {
            DevicePolicyManager dpm = (DevicePolicyManager)
            final DevicePolicyManager dpm = (DevicePolicyManager)
                    mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
            dpm.setActivePasswordState(metrics, userId);
        });
@@ -1935,7 +1931,7 @@ public class LockSettingsService extends ILockSettings.Stub {

        try {
            if (mLockPatternUtils.isLockPatternEnabled(userId)) {
                if (checkCredential(password.getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
                if (checkCredential(password.getBytes(), CREDENTIAL_TYPE_PATTERN,
                        userId, null /* progressCallback */)
                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
                    return true;
@@ -1946,7 +1942,7 @@ public class LockSettingsService extends ILockSettings.Stub {

        try {
            if (mLockPatternUtils.isLockPasswordEnabled(userId)) {
                if (checkCredential(password.getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
                if (checkCredential(password.getBytes(), CREDENTIAL_TYPE_PASSWORD,
                        userId, null /* progressCallback */)
                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
                    return true;
@@ -2392,11 +2388,11 @@ public class LockSettingsService extends ILockSettings.Stub {
        setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
    }

    private VerifyCredentialResponse spBasedDoVerifyCredential(byte[] userCredential, int
            credentialType, boolean hasChallenge, long challenge, int userId,
    private VerifyCredentialResponse spBasedDoVerifyCredential(byte[] userCredential,
            @CredentialType int credentialType, boolean hasChallenge, long challenge, int userId,
            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
        if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredential: user=" + userId);
        if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
        if (credentialType == CREDENTIAL_TYPE_NONE) {
            userCredential = null;
        }

@@ -2444,7 +2440,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        }

        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
            notifyActivePasswordMetricsAvailable(userCredential, userId);
            notifyActivePasswordMetricsAvailable(credentialType, userCredential, userId);
            unlockKeystore(authResult.authToken.deriveKeyStorePassword(), userId);
            // Reset lockout
            if (mInjector.hasBiometrics()) {
@@ -2491,8 +2487,9 @@ public class LockSettingsService extends ILockSettings.Stub {
     * added back when new password is set in future.
     */
    @GuardedBy("mSpManager")
    private long setLockCredentialWithAuthTokenLocked(byte[] credential, int credentialType,
            AuthenticationToken auth, int requestedQuality, int userId) throws RemoteException {
    private long setLockCredentialWithAuthTokenLocked(byte[] credential,
            @CredentialType int credentialType, AuthenticationToken auth, int requestedQuality,
            int userId) throws RemoteException {
        if (DEBUG) Slog.d(TAG, "setLockCredentialWithAuthTokenLocked: user=" + userId);
        long newHandle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
                credential, credentialType, auth, requestedQuality, userId);
@@ -2534,7 +2531,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, newHandle, userId);
        synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords);

        notifyActivePasswordMetricsAvailable(credential, userId);
        notifyActivePasswordMetricsAvailable(credentialType, credential, userId);

        if (profilePasswords != null) {
            for (Map.Entry<Integer, byte[]> entry : profilePasswords.entrySet()) {
@@ -2571,8 +2568,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        // If existing credential is provided, then it must match.
        if (savedCredential != null && auth == null) {
            throw new RemoteException("Failed to enroll " +
                    (credentialType == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD ? "password"
                            : "pattern"));
                    (credentialType == CREDENTIAL_TYPE_PASSWORD ? "password" : "pattern"));
        }

        boolean untrustedReset = false;
@@ -2660,7 +2656,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            if (!isUserSecure(userId)) {
                if (shouldMigrateToSyntheticPasswordLocked(userId)) {
                    auth = initializeSyntheticPasswordLocked(null, null,
                            LockPatternUtils.CREDENTIAL_TYPE_NONE,
                            CREDENTIAL_TYPE_NONE,
                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId);
                } else /* isSyntheticPasswordBasedCredentialLocked(userId) */ {
                    long pwdHandle = getSyntheticPasswordHandleLocked(userId);
+5 −3

File changed.

Preview size limit exceeded, changes collapsed.

+38 −37

File changed.

Preview size limit exceeded, changes collapsed.