diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 9abc1e7adf864..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,16 +1303,19 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private final FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback = new AuthenticationCallback() { + private boolean mIsUdfpsRunningWhileDozing; @Override public void onAuthenticationFailed() { handleFingerprintAuthFailed(); + cancelAodInterrupt(); } @Override public void onAuthenticationSucceeded(AuthenticationResult result) { Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded"); handleFingerprintAuthenticated(result.getUserId(), result.isStrongBiometric()); + cancelAodInterrupt(); Trace.endSection(); } @@ -1315,6 +1327,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab @Override public void onAuthenticationError(int errMsgId, CharSequence errString) { handleFingerprintError(errMsgId, errString.toString()); + cancelAodInterrupt(); } @Override @@ -1325,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 @@ -1617,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); @@ -1629,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/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..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; @@ -517,6 +520,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); @@ -886,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); } 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) {