From f50afe81085217b07353b007617e140173ac6a91 Mon Sep 17 00:00:00 2001 From: Beverly Date: Mon, 29 Mar 2021 14:59:49 -0400 Subject: [PATCH 1/2] CancelAodInterrupt in KeyguardUpdateMonitor Since keyguard FP listening is started from KeyguardUpdateMonitor, we rely on the callback in KeyguardUpateMonitor instead of in AuthController for cancelAodInterrupt. The biometric callback in AuthController is for biometric auth via the biometric prompt / BiometricService which doesn't get called on the keyguard/AOD. Test: atest KeyguardUpdateMonitorTest AuthControllerTest Fixes: 183962576 Change-Id: I3a0d8de41b27a3df78e72d401ca70f9d4c3cb166 --- .../keyguard/KeyguardUpdateMonitor.java | 4 +- .../systemui/biometrics/AuthController.java | 14 +++++-- .../keyguard/KeyguardUpdateMonitorTest.java | 40 +++++++++++++++++++ .../biometrics/AuthControllerTest.java | 14 ------- 4 files changed, 54 insertions(+), 18 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 9abc1e7adf864..171e5589ecfff 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -1294,16 +1294,17 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private final FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback = new AuthenticationCallback() { - @Override public void onAuthenticationFailed() { handleFingerprintAuthFailed(); + mAuthController.onCancelAodInterrupt(); } @Override public void onAuthenticationSucceeded(AuthenticationResult result) { Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded"); handleFingerprintAuthenticated(result.getUserId(), result.isStrongBiometric()); + mAuthController.onCancelAodInterrupt(); Trace.endSection(); } @@ -1315,6 +1316,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab @Override public void onAuthenticationError(int errMsgId, CharSequence errString) { handleFingerprintError(errMsgId, errString.toString()); + mAuthController.onCancelAodInterrupt(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index 7d06dd6ab0855..94b4c5f87b16a 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -290,7 +290,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, * called when authentication either succeeds or fails. Failing to cancel the scan will leave * the screen in high brightness mode. */ - private void onCancelAodInterrupt() { + public void onCancelAodInterrupt() { if (mUdfpsController == null) { return; } @@ -397,10 +397,14 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, showDialog(args, skipAnimation, null /* savedState */); } + /** + * Only called via BiometricService for the biometric prompt. Will not be called for + * authentication directly requested through FingerprintManager. For + * example, KeyguardUpdateMonitor has its own {@link FingerprintManager.AuthenticationCallback}. + */ @Override public void onBiometricAuthenticated() { mCurrentDialog.onAuthenticationSucceeded(); - onCancelAodInterrupt(); } @Override @@ -428,6 +432,11 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, } } + /** + * Only called via BiometricService for the biometric prompt. Will not be called for + * authentication directly requested through FingerprintManager. For + * example, KeyguardUpdateMonitor has its own {@link FingerprintManager.AuthenticationCallback}. + */ @Override public void onBiometricError(int modality, int error, int vendorCode) { if (DEBUG) { @@ -455,7 +464,6 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, if (DEBUG) Log.d(TAG, "onBiometricError, hard error: " + errorMessage); mCurrentDialog.onError(errorMessage); } - onCancelAodInterrupt(); } @Override diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 160dae5799644..f19ccbbc52d18 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -517,6 +517,46 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt()); } + @Test + public void testFingerprintCancelAodInterrupt_onAuthenticationFailed() { + // GIVEN on keyguard and listening for fingerprint authentication + mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */); + mTestableLooper.processAllMessages(); + + ArgumentCaptor fingerprintCallbackCaptor = + ArgumentCaptor.forClass(FingerprintManager.AuthenticationCallback.class); + verify(mFingerprintManager).authenticate(any(), any(), fingerprintCallbackCaptor.capture(), + any(), anyInt(), anyInt()); + FingerprintManager.AuthenticationCallback authCallback = + fingerprintCallbackCaptor.getValue(); + + // WHEN authentication fails + authCallback.onAuthenticationFailed(); + + // THEN aod interrupt is cancelled + verify(mAuthController).onCancelAodInterrupt(); + } + + @Test + public void testFingerprintCancelAodInterrupt_onAuthenticationError() { + // GIVEN on keyguard and listening for fingerprint authentication + mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */); + mTestableLooper.processAllMessages(); + + ArgumentCaptor fingerprintCallbackCaptor = + ArgumentCaptor.forClass(FingerprintManager.AuthenticationCallback.class); + verify(mFingerprintManager).authenticate(any(), any(), fingerprintCallbackCaptor.capture(), + any(), anyInt(), anyInt()); + FingerprintManager.AuthenticationCallback authCallback = + fingerprintCallbackCaptor.getValue(); + + // WHEN authentication errors + authCallback.onAuthenticationError(0, ""); + + // THEN aod interrupt is cancelled + verify(mAuthController).onCancelAodInterrupt(); + } + @Test public void skipsAuthentication_whenStatusBarShadeLocked() { mStatusBarStateListener.onStateChanged(StatusBarState.SHADE_LOCKED); diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java index fa190a562d8ba..3fe8cee8d7397 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java @@ -509,20 +509,6 @@ public class AuthControllerTest extends SysuiTestCase { verify(mUdfpsController).onAodInterrupt(eq(pos), eq(pos), eq(majorMinor), eq(majorMinor)); } - @Test - public void testOnBiometricAuthenticated_OnCancelAodInterrupt() { - showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); - mAuthController.onBiometricAuthenticated(); - verify(mUdfpsController).onCancelAodInterrupt(); - } - - @Test - public void testOnBiometricError_OnCancelAodInterrupt() { - showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); - mAuthController.onBiometricError(0, 0, 0); - verify(mUdfpsController).onCancelAodInterrupt(); - } - // Helpers private void showDialog(int[] sensorIds, boolean credentialAllowed) { From bf3916b1c18813ab90b4e5e363872d289d994c62 Mon Sep 17 00:00:00 2001 From: Beverly Date: Mon, 29 Mar 2021 16:16:06 -0400 Subject: [PATCH 2/2] Fully wake screen after udfps auth attempt from AOD Particularly on failure/error. Note: AuthController#onAodInterrupt isn't called in the first few seconds of screen transioning to AOD; it'll only trigger after display transitions to STATE_DOZE, so we have the wakeup logic in KeyguardUpdateMonitor which uses the dozing state. Test: manually check that auth failure on AOD brings user to lock screen Bug: 175717712 Change-Id: I4f888f648ddb061068aa1963239dac45ba195074 --- .../keyguard/KeyguardUpdateMonitor.java | 33 +++++++++++++++++-- .../keyguard/KeyguardUpdateMonitorTest.java | 5 ++- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 171e5589ecfff..27a2ac379eee6 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -66,8 +66,10 @@ import android.os.Handler; import android.os.IRemoteCallback; import android.os.Looper; import android.os.Message; +import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; @@ -241,8 +243,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private final boolean mIsPrimaryUser; private final boolean mIsAutomotive; private final AuthController mAuthController; + private final PowerManager mPowerManager; private final StatusBarStateController mStatusBarStateController; private int mStatusBarState; + private boolean mDozing; private final StatusBarStateController.StateListener mStatusBarStateControllerListener = new StatusBarStateController.StateListener() { @Override @@ -250,6 +254,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mStatusBarState = newState; updateBiometricListeningState(); } + + @Override + public void onDozingChanged(boolean dozing) { + mDozing = dozing; + } }; HashMap mSimDatas = new HashMap<>(); @@ -1294,17 +1303,19 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private final FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback = new AuthenticationCallback() { + private boolean mIsUdfpsRunningWhileDozing; + @Override public void onAuthenticationFailed() { handleFingerprintAuthFailed(); - mAuthController.onCancelAodInterrupt(); + cancelAodInterrupt(); } @Override public void onAuthenticationSucceeded(AuthenticationResult result) { Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded"); handleFingerprintAuthenticated(result.getUserId(), result.isStrongBiometric()); - mAuthController.onCancelAodInterrupt(); + cancelAodInterrupt(); Trace.endSection(); } @@ -1316,7 +1327,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab @Override public void onAuthenticationError(int errMsgId, CharSequence errString) { handleFingerprintError(errMsgId, errString.toString()); - mAuthController.onCancelAodInterrupt(); + cancelAodInterrupt(); } @Override @@ -1327,12 +1338,25 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab @Override public void onUdfpsPointerDown(int sensorId) { Log.d(TAG, "onUdfpsPointerDown, sensorId: " + sensorId); + + if (mDozing) { + mIsUdfpsRunningWhileDozing = true; + } } @Override public void onUdfpsPointerUp(int sensorId) { Log.d(TAG, "onUdfpsPointerUp, sensorId: " + sensorId); } + + private void cancelAodInterrupt() { + if (mIsUdfpsRunningWhileDozing) { + mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE, + "com.android.systemui:AOD_INTERRUPT_END"); + } + mAuthController.onCancelAodInterrupt(); + mIsUdfpsRunningWhileDozing = false; + } }; private final FaceManager.FaceDetectionCallback mFaceDetectionCallback @@ -1619,6 +1643,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab LockPatternUtils lockPatternUtils, AuthController authController, TelephonyListenerManager telephonyListenerManager, + PowerManager powerManager, FeatureFlags featureFlags) { mContext = context; mSubscriptionManager = SubscriptionManager.from(context); @@ -1631,8 +1656,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mStatusBarStateController = statusBarStateController; mStatusBarStateController.addCallback(mStatusBarStateControllerListener); mStatusBarState = mStatusBarStateController.getState(); + mDozing = mStatusBarStateController.isDozing(); mLockPatternUtils = lockPatternUtils; mAuthController = authController; + mPowerManager = powerManager; dumpManager.registerDumpable(getClass().getName(), this); mHandler = new Handler(mainLooper) { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index f19ccbbc52d18..44c3b26189c45 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -61,6 +61,7 @@ import android.nfc.NfcAdapter; import android.os.Bundle; import android.os.Handler; import android.os.IRemoteCallback; +import android.os.PowerManager; import android.os.UserHandle; import android.os.UserManager; import android.telephony.ServiceState; @@ -164,6 +165,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Mock private AuthController mAuthController; @Mock + private PowerManager mPowerManager; + @Mock private TelephonyListenerManager mTelephonyListenerManager; @Mock private FeatureFlags mFeatureFlags; @@ -926,7 +929,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mBroadcastDispatcher, mDumpManager, mRingerModeTracker, mBackgroundExecutor, mStatusBarStateController, mLockPatternUtils, - mAuthController, mTelephonyListenerManager, mFeatureFlags); + mAuthController, mTelephonyListenerManager, mPowerManager, mFeatureFlags); setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker); }