From 8ae64b5c2950eda2c48844e8a798f7b274d8c41a Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Mon, 6 Apr 2020 15:48:49 -0700 Subject: [PATCH] Update bouncer fingerprint lockout logic Do not request fingerprint auth if the user is locked out and they have attempted credential on bouncer. This fixes an issue where the incorrect PIN/Pattern/Password message would be overwritten by the fingerprint lockout message. KeyguardUpdateMonitor controlls biometric requests for lockscreen/bouncer, so poke in credential attempts so it can be used for determining if biometric should be requested. Fixes: 141960543 Test: 1) set up PIN/Pattern/Password and fingerprint 2) reject fingerprint 5 times, then swipe up to bouncer 3) note that "too many attempts" message is shown 4) enter wrong PIN/Pattern/Password 5) note that from now on, this current bouncer session will only show credential-related errors Change-Id: Ifb837b29f93caa5b8762bd5609ca09601b6e4784 --- .../keyguard/KeyguardAbsKeyInputView.java | 5 ++++ .../android/keyguard/KeyguardPatternView.java | 1 + .../keyguard/KeyguardUpdateMonitor.java | 30 +++++++++++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java index caee8ccb69704..88f4176f5eaca 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java @@ -34,6 +34,7 @@ import com.android.internal.util.LatencyTracker; import com.android.internal.widget.LockPatternChecker; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockscreenCredential; +import com.android.systemui.Dependency; import com.android.systemui.R; /** @@ -50,6 +51,7 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout private boolean mDismissing; protected boolean mResumed; private CountDownTimer mCountdownTimer = null; + private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; // To avoid accidental lockout due to events while the device in in the pocket, ignore // any passwords with length less than or equal to this length. @@ -61,6 +63,7 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout public KeyguardAbsKeyInputView(Context context, AttributeSet attrs) { super(context, attrs); + mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class); } @Override @@ -151,6 +154,8 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout LatencyTracker.getInstance(mContext).onActionStart(ACTION_CHECK_CREDENTIAL); LatencyTracker.getInstance(mContext).onActionStart(ACTION_CHECK_CREDENTIAL_UNLOCKED); } + + mKeyguardUpdateMonitor.setCredentialAttempted(); mPendingLockCheck = LockPatternChecker.checkCredential( mLockPatternUtils, password, diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java index 48c6bd114d4a5..ad92f8f623e45 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java @@ -282,6 +282,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit @Override public void onPatternDetected(final List pattern) { + mKeyguardUpdateMonitor.setCredentialAttempted(); mLockPatternView.disableInput(); if (mPendingLockCheck != null) { mPendingLockCheck.cancel(false); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 57e3f14d7aed0..88d6943b4071f 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -223,6 +223,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private int mRingMode; private int mPhoneState; private boolean mKeyguardIsVisible; + private boolean mCredentialAttempted; private boolean mKeyguardGoingAway; private boolean mGoingToSleep; private boolean mBouncer; @@ -497,12 +498,22 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } } + /** + * Updates KeyguardUpdateMonitor's internal state to know if credential was attempted on + * bouncer. Note that this does not care if the credential was correct/incorrect. This is + * cleared when the user leaves the bouncer (unlocked, screen off, back to lockscreen, etc) + */ + public void setCredentialAttempted() { + mCredentialAttempted = true; + updateBiometricListeningState(); + } + /** * Updates KeyguardUpdateMonitor's internal state to know if keyguard is goingAway */ public void setKeyguardGoingAway(boolean goingAway) { mKeyguardGoingAway = goingAway; - updateFingerprintListeningState(); + updateBiometricListeningState(); } /** @@ -664,6 +675,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab updateFingerprintListeningState(); } else { setFingerprintRunningState(BIOMETRIC_STATE_STOPPED); + mFingerprintCancelSignal = null; + mFaceCancelSignal = null; } if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) { @@ -679,6 +692,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab getCurrentUser()); } + if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT + || msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) { + mFingerprintLockedOut = true; + } + for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); if (cb != null) { @@ -688,6 +706,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } private void handleFingerprintLockoutReset() { + mFingerprintLockedOut = false; updateFingerprintListeningState(); } @@ -1274,6 +1293,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private CancellationSignal mFaceCancelSignal; private FingerprintManager mFpm; private FaceManager mFaceManager; + private boolean mFingerprintLockedOut; /** * When we receive a @@ -1820,13 +1840,17 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } private boolean shouldListenForFingerprint() { + final boolean allowedOnBouncer = + !(mFingerprintLockedOut && mBouncer && mCredentialAttempted); + // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware. final boolean shouldListen = (mKeyguardIsVisible || !mDeviceInteractive || (mBouncer && !mKeyguardGoingAway) || mGoingToSleep || shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming)) && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser()) - && (!mKeyguardGoingAway || !mDeviceInteractive) && mIsPrimaryUser; + && (!mKeyguardGoingAway || !mDeviceInteractive) && mIsPrimaryUser + && allowedOnBouncer; return shouldListen; } @@ -2372,6 +2396,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab // camera requests dismiss keyguard (tapping on photos for example). When these happen, // face auth should resume. mSecureCameraLaunched = false; + } else { + mCredentialAttempted = false; } for (int i = 0; i < mCallbacks.size(); i++) {