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

Commit 42f22a83 authored by Beverly Tai's avatar Beverly Tai Committed by Automerger Merge Worker
Browse files

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

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16306818

Change-Id: Id09b128a3ab944a11c2c9a96d69c05df5db957e7
parents 75954281 dd9f25b1
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