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

Commit dd9f25b1 authored by Beverly Tai's avatar Beverly Tai Committed by Android (Google) Code Review
Browse files

Merge "Show bouncer after failed UDFPS attempts" into sc-v2-dev

parents 5b9b66e8 98902d63
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -801,13 +801,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            mHandler.postDelayed(mRetryFingerprintAuthentication, HAL_ERROR_RETRY_TIMEOUT);
        }

        boolean lockedOutStateChanged = false;
        if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
            lockedOutStateChanged |= !mFingerprintLockedOutPermanent;
            mFingerprintLockedOutPermanent = true;
            requireStrongAuthIfAllLockedOut();
        }

        if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT
                || msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
            lockedOutStateChanged |= !mFingerprintLockedOut;
            mFingerprintLockedOut = true;
            if (isUdfpsEnrolled()) {
                updateFingerprintListeningState();
@@ -820,9 +823,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                cb.onBiometricError(msgId, errString, BiometricSourceType.FINGERPRINT);
            }
        }

        if (lockedOutStateChanged) {
            notifyLockedOutStateChanged(BiometricSourceType.FINGERPRINT);
        }
    }

    private void handleFingerprintLockoutReset() {
        boolean changed = mFingerprintLockedOut || mFingerprintLockedOutPermanent;
        mFingerprintLockedOut = false;
        mFingerprintLockedOutPermanent = false;

@@ -837,6 +845,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        } else {
            updateFingerprintListeningState();
        }

        if (changed) {
            notifyLockedOutStateChanged(BiometricSourceType.FINGERPRINT);
        }
    }

    private void setFingerprintRunningState(int fingerprintRunningState) {
@@ -999,7 +1011,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            }
        }

        boolean lockedOutStateChanged = false;
        if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
            lockedOutStateChanged = !mFaceLockedOutPermanent;
            mFaceLockedOutPermanent = true;
            requireStrongAuthIfAllLockedOut();
        }
@@ -1011,11 +1025,21 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                        BiometricSourceType.FACE);
            }
        }

        if (lockedOutStateChanged) {
            notifyLockedOutStateChanged(BiometricSourceType.FACE);
        }
    }

    private void handleFaceLockoutReset() {
        boolean changed = mFaceLockedOutPermanent;
        mFaceLockedOutPermanent = false;

        updateFaceListeningState();

        if (changed) {
            notifyLockedOutStateChanged(BiometricSourceType.FACE);
        }
    }

    private void setFaceRunningState(int faceRunningState) {
@@ -1237,6 +1261,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        }
    }

    private void notifyLockedOutStateChanged(BiometricSourceType type) {
        Assert.isMainThread();
        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
                cb.onLockedOutStateChanged(type);
            }
        }
    }

    public boolean isScreenOn() {
        return mScreenOn;
    }
@@ -2454,6 +2488,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        }
    }

    public boolean isFingerprintLockedOut() {
        return mFingerprintLockedOut || mFingerprintLockedOutPermanent;
    }

    /**
     * If biometrics hardware is available, not disabled, and user has enrolled templates.
     * This does NOT check if the device is encrypted or in lockdown.
+5 −0
Original line number Diff line number Diff line
@@ -291,6 +291,11 @@ public class KeyguardUpdateMonitorCallback {
     */
    public void onStrongAuthStateChanged(int userId) { }

    /**
     * When the current user's locked out state changed.
     */
    public void onLockedOutStateChanged(BiometricSourceType biometricSourceType) { }

    /**
     * Called when the dream's window state is changed.
     * @param dreaming true if the dream's window has been created and is visible
+0 −1
Original line number Diff line number Diff line
@@ -255,7 +255,6 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
    private void maybeShowInputBouncer() {
        if (mShowingUdfpsBouncer && hasUdfpsBouncerShownWithMinTime()) {
            mKeyguardViewManager.showBouncer(true);
            mKeyguardViewManager.resetAlternateAuth(false);
        }
    }

+2 −1
Original line number Diff line number Diff line
@@ -793,7 +793,8 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
                return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN;
            } else if (trust && (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) {
                return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
            } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0) {
            } else if (any && ((strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0
                    || mUpdateMonitor.isFingerprintLockedOut())) {
                return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT;
            } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE) != 0) {
                return KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE;
+43 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.content.Context;
import android.content.res.Resources;
import android.hardware.biometrics.BiometricSourceType;
import android.hardware.fingerprint.FingerprintManager;
import android.metrics.LogMaker;
import android.os.Handler;
import android.os.PowerManager;
@@ -46,9 +47,11 @@ import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.policy.KeyguardStateController;

import java.io.FileDescriptor;
@@ -71,6 +74,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
    private static final long BIOMETRIC_WAKELOCK_TIMEOUT_MS = 15 * 1000;
    private static final String BIOMETRIC_WAKE_LOCK_NAME = "wake-and-unlock:wakelock";
    private static final UiEventLogger UI_EVENT_LOGGER = new UiEventLoggerImpl();
    private static final int FP_ATTEMPTS_BEFORE_SHOW_BOUNCER = 3;

    @IntDef(prefix = { "MODE_" }, value = {
            MODE_NONE,
@@ -167,6 +171,10 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp

    private final MetricsLogger mMetricsLogger;
    private final AuthController mAuthController;
    private final StatusBarStateController mStatusBarStateController;

    private long mLastFpFailureUptimeMillis;
    private int mNumConsecutiveFpFailures;

    private static final class PendingAuthenticated {
        public final int userId;
@@ -209,7 +217,10 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
        BIOMETRIC_IRIS_FAILURE(403),

        @UiEvent(doc = "A biometric event of type iris errored.")
        BIOMETRIC_IRIS_ERROR(404);
        BIOMETRIC_IRIS_ERROR(404),

        @UiEvent(doc = "Bouncer was shown as a result of consecutive failed UDFPS attempts.")
        BIOMETRIC_BOUNCER_SHOWN(916);

        private final int mId;

@@ -257,7 +268,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
            NotificationMediaManager notificationMediaManager,
            WakefulnessLifecycle wakefulnessLifecycle,
            ScreenLifecycle screenLifecycle,
            AuthController authController) {
            AuthController authController,
            StatusBarStateController statusBarStateController) {
        mContext = context;
        mPowerManager = powerManager;
        mShadeController = shadeController;
@@ -279,6 +291,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
        mKeyguardBypassController.setUnlockController(this);
        mMetricsLogger = metricsLogger;
        mAuthController = authController;
        mStatusBarStateController = statusBarStateController;
        dumpManager.registerDumpable(getClass().getName(), this);
    }

@@ -620,6 +633,22 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
                .setType(MetricsEvent.TYPE_FAILURE).setSubtype(toSubtype(biometricSourceType)));
        Optional.ofNullable(BiometricUiEvent.FAILURE_EVENT_BY_SOURCE_TYPE.get(biometricSourceType))
                .ifPresent(UI_EVENT_LOGGER::log);

        long currUptimeMillis = SystemClock.uptimeMillis();
        if (currUptimeMillis - mLastFpFailureUptimeMillis < 2000) { // attempt within 2 seconds
            mNumConsecutiveFpFailures += 1;
        } else {
            mNumConsecutiveFpFailures = 1;
        }
        mLastFpFailureUptimeMillis = currUptimeMillis;

        if (biometricSourceType.equals(BiometricSourceType.FINGERPRINT)
                && mUpdateMonitor.isUdfpsSupported()
                && mNumConsecutiveFpFailures >= FP_ATTEMPTS_BEFORE_SHOW_BOUNCER) {
            mKeyguardViewController.showBouncer(true);
            UI_EVENT_LOGGER.log(BiometricUiEvent.BIOMETRIC_BOUNCER_SHOWN);
            mNumConsecutiveFpFailures = 0;
        }
        cleanup();
    }

@@ -631,6 +660,16 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
                .addTaggedData(MetricsEvent.FIELD_BIOMETRIC_AUTH_ERROR, msgId));
        Optional.ofNullable(BiometricUiEvent.ERROR_EVENT_BY_SOURCE_TYPE.get(biometricSourceType))
                .ifPresent(UI_EVENT_LOGGER::log);

        // if we're on the shade and we're locked out, immediately show the bouncer
        if (biometricSourceType == BiometricSourceType.FINGERPRINT
                && (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT
                || msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT)
                && mUpdateMonitor.isUdfpsSupported()
                && (mStatusBarStateController.getState() == StatusBarState.SHADE
                    || mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED)) {
            mKeyguardViewController.showBouncer(true);
        }
        cleanup();
    }

@@ -664,6 +703,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
            mBiometricModeListener.onResetMode();
            mBiometricModeListener.notifyBiometricAuthModeChanged();
        }
        mNumConsecutiveFpFailures = 0;
        mLastFpFailureUptimeMillis = 0;
    }

    @VisibleForTesting
Loading