Loading packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +18 −2 Original line number Diff line number Diff line Loading @@ -214,7 +214,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab * If no cancel signal has been received after this amount of time, set the biometric running * state to stopped to allow Keyguard to retry authentication. */ private static final int DEFAULT_CANCEL_SIGNAL_TIMEOUT = 3000; @VisibleForTesting protected static final int DEFAULT_CANCEL_SIGNAL_TIMEOUT = 3000; private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName( "com.android.settings", "com.android.settings.FallbackHome"); Loading Loading @@ -332,10 +333,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private static final int HAL_ERROR_RETRY_TIMEOUT = 500; // ms private static final int HAL_ERROR_RETRY_MAX = 20; private final Runnable mFpCancelNotReceived = this::onFingerprintCancelNotReceived; @VisibleForTesting protected final Runnable mFpCancelNotReceived = this::onFingerprintCancelNotReceived; private final Runnable mFaceCancelNotReceived = this::onFaceCancelNotReceived; @VisibleForTesting protected Handler getHandler() { return mHandler; } private final Handler mHandler; private SparseBooleanArray mBiometricEnabledForUser = new SparseBooleanArray(); Loading Loading @@ -723,6 +729,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private void handleFingerprintAuthFailed() { Assert.isMainThread(); if (mHandler.hasCallbacks(mFpCancelNotReceived)) { Log.d(TAG, "handleFingerprintAuthFailed()" + " triggered while waiting for cancellation, removing watchdog"); mHandler.removeCallbacks(mFpCancelNotReceived); } for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); if (cb != null) { Loading Loading @@ -753,6 +764,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private void handleFingerprintAuthenticated(int authUserId, boolean isStrongBiometric) { Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated"); if (mHandler.hasCallbacks(mFpCancelNotReceived)) { Log.d(TAG, "handleFingerprintAuthenticated()" + " triggered while waiting for cancellation, removing watchdog"); mHandler.removeCallbacks(mFpCancelNotReceived); } try { final int userId; try { Loading packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +47 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT; import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -109,6 +110,7 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.MockitoSession; import org.mockito.internal.util.reflection.FieldSetter; import java.util.ArrayList; import java.util.Arrays; Loading Loading @@ -200,9 +202,10 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { private ArgumentCaptor<CancellationSignal> mCancellationSignalCaptor; // Direct executor private Executor mBackgroundExecutor = Runnable::run; private Executor mMainExecutor = Runnable::run; private final Executor mBackgroundExecutor = Runnable::run; private final Executor mMainExecutor = Runnable::run; private TestableLooper mTestableLooper; private Handler mHandler; private TestableKeyguardUpdateMonitor mKeyguardUpdateMonitor; private TestableContext mSpiedContext; private MockitoSession mMockitoSession; Loading Loading @@ -291,6 +294,13 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mBiometricEnabledOnKeyguardCallback = mBiometricEnabledCallbackArgCaptor.getValue(); biometricsEnabledForCurrentUser(); mHandler = spy(mKeyguardUpdateMonitor.getHandler()); try { FieldSetter.setField(mKeyguardUpdateMonitor, KeyguardUpdateMonitor.class.getDeclaredField("mHandler"), mHandler); } catch (NoSuchFieldException e) { } verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture()); mStatusBarStateListener = mStatusBarStateListenerCaptor.getValue(); mKeyguardUpdateMonitor.registerCallback(mTestCallback); Loading Loading @@ -791,7 +801,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { public void testBiometricsCleared_whenUserSwitches() throws Exception { final IRemoteCallback reply = new IRemoteCallback.Stub() { @Override public void sendResult(Bundle data) {} // do nothing public void sendResult(Bundle data) { } // do nothing }; final BiometricAuthenticated dummyAuthentication = new BiometricAuthenticated(true /* authenticated */, true /* strong */); Loading @@ -809,7 +820,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { public void testMultiUserJankMonitor_whenUserSwitches() throws Exception { final IRemoteCallback reply = new IRemoteCallback.Stub() { @Override public void sendResult(Bundle data) {} // do nothing public void sendResult(Bundle data) { } // do nothing }; mKeyguardUpdateMonitor.handleUserSwitchComplete(10 /* user */); verify(mInteractionJankMonitor).end(InteractionJankMonitor.CUJ_USER_SWITCH); Loading Loading @@ -1499,6 +1511,34 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { assertThat(cancelSignal.isCanceled()).isTrue(); } @Test public void testFingerprintCanAuth_whenCancellationNotReceivedAndAuthFailed() { mKeyguardUpdateMonitor.dispatchStartedWakingUp(); mTestableLooper.processAllMessages(); mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean()); verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(), anyInt()); mKeyguardUpdateMonitor.onFaceAuthenticated(0, false); // Make sure keyguard is going away after face auth attempt, and that it calls // updateBiometricStateListeningState. mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(false); mTestableLooper.processAllMessages(); verify(mHandler).postDelayed(mKeyguardUpdateMonitor.mFpCancelNotReceived, DEFAULT_CANCEL_SIGNAL_TIMEOUT); mKeyguardUpdateMonitor.onFingerprintAuthenticated(0, true); mTestableLooper.processAllMessages(); verify(mHandler, times(1)).removeCallbacks(mKeyguardUpdateMonitor.mFpCancelNotReceived); mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */); mTestableLooper.processAllMessages(); assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(anyBoolean())).isEqualTo(true); } private void fingerprintIsNotEnrolled() { when(mFingerprintManager.hasEnrolledTemplates(mCurrentUserId)).thenReturn(false); } Loading Loading
packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +18 −2 Original line number Diff line number Diff line Loading @@ -214,7 +214,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab * If no cancel signal has been received after this amount of time, set the biometric running * state to stopped to allow Keyguard to retry authentication. */ private static final int DEFAULT_CANCEL_SIGNAL_TIMEOUT = 3000; @VisibleForTesting protected static final int DEFAULT_CANCEL_SIGNAL_TIMEOUT = 3000; private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName( "com.android.settings", "com.android.settings.FallbackHome"); Loading Loading @@ -332,10 +333,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private static final int HAL_ERROR_RETRY_TIMEOUT = 500; // ms private static final int HAL_ERROR_RETRY_MAX = 20; private final Runnable mFpCancelNotReceived = this::onFingerprintCancelNotReceived; @VisibleForTesting protected final Runnable mFpCancelNotReceived = this::onFingerprintCancelNotReceived; private final Runnable mFaceCancelNotReceived = this::onFaceCancelNotReceived; @VisibleForTesting protected Handler getHandler() { return mHandler; } private final Handler mHandler; private SparseBooleanArray mBiometricEnabledForUser = new SparseBooleanArray(); Loading Loading @@ -723,6 +729,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private void handleFingerprintAuthFailed() { Assert.isMainThread(); if (mHandler.hasCallbacks(mFpCancelNotReceived)) { Log.d(TAG, "handleFingerprintAuthFailed()" + " triggered while waiting for cancellation, removing watchdog"); mHandler.removeCallbacks(mFpCancelNotReceived); } for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); if (cb != null) { Loading Loading @@ -753,6 +764,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private void handleFingerprintAuthenticated(int authUserId, boolean isStrongBiometric) { Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated"); if (mHandler.hasCallbacks(mFpCancelNotReceived)) { Log.d(TAG, "handleFingerprintAuthenticated()" + " triggered while waiting for cancellation, removing watchdog"); mHandler.removeCallbacks(mFpCancelNotReceived); } try { final int userId; try { Loading
packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +47 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT; import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -109,6 +110,7 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.MockitoSession; import org.mockito.internal.util.reflection.FieldSetter; import java.util.ArrayList; import java.util.Arrays; Loading Loading @@ -200,9 +202,10 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { private ArgumentCaptor<CancellationSignal> mCancellationSignalCaptor; // Direct executor private Executor mBackgroundExecutor = Runnable::run; private Executor mMainExecutor = Runnable::run; private final Executor mBackgroundExecutor = Runnable::run; private final Executor mMainExecutor = Runnable::run; private TestableLooper mTestableLooper; private Handler mHandler; private TestableKeyguardUpdateMonitor mKeyguardUpdateMonitor; private TestableContext mSpiedContext; private MockitoSession mMockitoSession; Loading Loading @@ -291,6 +294,13 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mBiometricEnabledOnKeyguardCallback = mBiometricEnabledCallbackArgCaptor.getValue(); biometricsEnabledForCurrentUser(); mHandler = spy(mKeyguardUpdateMonitor.getHandler()); try { FieldSetter.setField(mKeyguardUpdateMonitor, KeyguardUpdateMonitor.class.getDeclaredField("mHandler"), mHandler); } catch (NoSuchFieldException e) { } verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture()); mStatusBarStateListener = mStatusBarStateListenerCaptor.getValue(); mKeyguardUpdateMonitor.registerCallback(mTestCallback); Loading Loading @@ -791,7 +801,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { public void testBiometricsCleared_whenUserSwitches() throws Exception { final IRemoteCallback reply = new IRemoteCallback.Stub() { @Override public void sendResult(Bundle data) {} // do nothing public void sendResult(Bundle data) { } // do nothing }; final BiometricAuthenticated dummyAuthentication = new BiometricAuthenticated(true /* authenticated */, true /* strong */); Loading @@ -809,7 +820,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { public void testMultiUserJankMonitor_whenUserSwitches() throws Exception { final IRemoteCallback reply = new IRemoteCallback.Stub() { @Override public void sendResult(Bundle data) {} // do nothing public void sendResult(Bundle data) { } // do nothing }; mKeyguardUpdateMonitor.handleUserSwitchComplete(10 /* user */); verify(mInteractionJankMonitor).end(InteractionJankMonitor.CUJ_USER_SWITCH); Loading Loading @@ -1499,6 +1511,34 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { assertThat(cancelSignal.isCanceled()).isTrue(); } @Test public void testFingerprintCanAuth_whenCancellationNotReceivedAndAuthFailed() { mKeyguardUpdateMonitor.dispatchStartedWakingUp(); mTestableLooper.processAllMessages(); mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean()); verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(), anyInt()); mKeyguardUpdateMonitor.onFaceAuthenticated(0, false); // Make sure keyguard is going away after face auth attempt, and that it calls // updateBiometricStateListeningState. mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(false); mTestableLooper.processAllMessages(); verify(mHandler).postDelayed(mKeyguardUpdateMonitor.mFpCancelNotReceived, DEFAULT_CANCEL_SIGNAL_TIMEOUT); mKeyguardUpdateMonitor.onFingerprintAuthenticated(0, true); mTestableLooper.processAllMessages(); verify(mHandler, times(1)).removeCallbacks(mKeyguardUpdateMonitor.mFpCancelNotReceived); mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */); mTestableLooper.processAllMessages(); assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(anyBoolean())).isEqualTo(true); } private void fingerprintIsNotEnrolled() { when(mFingerprintManager.hasEnrolledTemplates(mCurrentUserId)).thenReturn(false); } Loading