Loading core/res/res/values/config.xml +3 −3 Original line number Diff line number Diff line Loading @@ -3577,9 +3577,9 @@ config_sidefpsSkipWaitForPowerVendorAcquireMessage --> <integer name="config_sidefpsSkipWaitForPowerAcquireMessage">6</integer> <!-- This vendor acquired message that will cause the sidefpsKgPowerPress window to be skipped. config_sidefpsSkipWaitForPowerOnFingerUp must be true and config_sidefpsSkipWaitForPowerAcquireMessage must be BIOMETRIC_ACQUIRED_VENDOR == 6. --> <!-- This vendor acquired message will cause the sidefpsKgPowerPress window to be skipped when config_sidefpsSkipWaitForPowerAcquireMessage == 6 (VENDOR) and the vendor acquire message equals this constant --> <integer name="config_sidefpsSkipWaitForPowerVendorAcquireMessage">2</integer> <!-- This config is used to force VoiceInteractionService to start on certain low ram devices. Loading services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java +20 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.biometrics.sensors.fingerprint.aidl; import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START; import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR; import android.annotation.NonNull; Loading Loading @@ -57,6 +58,7 @@ import com.android.server.biometrics.sensors.SensorOverlays; import com.android.server.biometrics.sensors.fingerprint.PowerPressHandler; import com.android.server.biometrics.sensors.fingerprint.Udfps; import java.time.Clock; import java.util.ArrayList; import java.util.function.Supplier; Loading Loading @@ -88,7 +90,9 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession> private long mWaitForAuthKeyguard; private long mWaitForAuthBp; private long mIgnoreAuthFor; private long mSideFpsLastAcquireStartTime; private Runnable mAuthSuccessRunnable; private final Clock mClock; FingerprintAuthenticationClient( @NonNull Context context, Loading @@ -112,7 +116,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession> @Nullable ISidefpsController sidefpsController, boolean allowBackgroundAuthentication, @NonNull FingerprintSensorPropertiesInternal sensorProps, @NonNull Handler handler) { @NonNull Handler handler, @NonNull Clock clock) { super( context, lazyDaemon, Loading Loading @@ -154,6 +159,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession> mSkipWaitForPowerVendorAcquireMessage = context.getResources().getInteger( R.integer.config_sidefpsSkipWaitForPowerVendorAcquireMessage); mSideFpsLastAcquireStartTime = -1; mClock = clock; if (mSensorProps.isAnySidefpsType()) { if (Build.isDebuggable()) { Loading Loading @@ -235,8 +242,14 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession> return; } delay = isKeyguard() ? mWaitForAuthKeyguard : mWaitForAuthBp; Slog.i(TAG, "(sideFPS) Auth succeeded, sideFps waiting for power for: " + delay + "ms"); if (mSideFpsLastAcquireStartTime != -1) { delay = Math.max(0, delay - (mClock.millis() - mSideFpsLastAcquireStartTime)); } Slog.i(TAG, "(sideFPS) Auth succeeded, sideFps " + "waiting for power until: " + delay + "ms"); } if (mHandler.hasMessages(MESSAGE_FINGER_UP)) { Loading @@ -260,13 +273,15 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession> mSensorOverlays.ifUdfps(controller -> controller.onAcquired(getSensorId(), acquiredInfo)); super.onAcquired(acquiredInfo, vendorCode); if (mSensorProps.isAnySidefpsType()) { if (acquiredInfo == FINGERPRINT_ACQUIRED_START) { mSideFpsLastAcquireStartTime = mClock.millis(); } final boolean shouldLookForVendor = mSkipWaitForPowerAcquireMessage == FINGERPRINT_ACQUIRED_VENDOR; final boolean acquireMessageMatch = acquiredInfo == mSkipWaitForPowerAcquireMessage; final boolean vendorMessageMatch = vendorCode == mSkipWaitForPowerVendorAcquireMessage; final boolean ignorePowerPress = (acquireMessageMatch && !shouldLookForVendor) || (shouldLookForVendor && acquireMessageMatch && vendorMessageMatch); acquireMessageMatch && (!shouldLookForVendor || vendorMessageMatch); if (ignorePowerPress) { Slog.d(TAG, "(sideFPS) onFingerUp"); Loading services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java +3 −1 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserManager; import android.util.Slog; import android.util.SparseArray; Loading Loading @@ -447,7 +448,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi mBiometricContext, isStrongBiometric, mTaskStackListener, mSensors.get(sensorId).getLockoutCache(), mUdfpsOverlayController, mSidefpsController, allowBackgroundAuthentication, mSensors.get(sensorId).getSensorProperties(), mHandler); mSensors.get(sensorId).getSensorProperties(), mHandler, SystemClock.elapsedRealtimeClock()); scheduleForSensor(sensorId, client, mBiometricStateCallback); }); } Loading services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java +124 −1 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.hardware.biometrics.common.OperationContext; import android.hardware.biometrics.fingerprint.ISession; import android.hardware.biometrics.fingerprint.PointerContext; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.ISidefpsController; import android.hardware.fingerprint.IUdfpsOverlayController; Loading Loading @@ -73,6 +74,7 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import java.time.Clock; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; Loading Loading @@ -128,6 +130,8 @@ public class FingerprintAuthenticationClientTest { private ICancellationSignal mCancellationSignal; @Mock private Probe mLuxProbe; @Mock private Clock mClock; @Captor private ArgumentCaptor<OperationContext> mOperationContextCaptor; @Captor Loading Loading @@ -446,6 +450,52 @@ public class FingerprintAuthenticationClientTest { verify(mCallback).onClientFinished(any(), eq(true)); } @Test public void sideFingerprintSkipsWindowIfVendorMessageMatch() throws Exception { when(mSensorProps.isAnySidefpsType()).thenReturn(true); final int vendorAcquireMessage = 1234; mContext.getOrCreateTestableResources().addOverride( R.integer.config_sidefpsSkipWaitForPowerAcquireMessage, FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR); mContext.getOrCreateTestableResources().addOverride( R.integer.config_sidefpsSkipWaitForPowerVendorAcquireMessage, vendorAcquireMessage); final FingerprintAuthenticationClient client = createClient(1); client.start(mCallback); mLooper.dispatchAll(); client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */), true /* authenticated */, new ArrayList<>()); client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR, vendorAcquireMessage); mLooper.dispatchAll(); verify(mCallback).onClientFinished(any(), eq(true)); } @Test public void sideFingerprintDoesNotSkipWindowOnVendorErrorMismatch() throws Exception { when(mSensorProps.isAnySidefpsType()).thenReturn(true); final int vendorAcquireMessage = 1234; mContext.getOrCreateTestableResources().addOverride( R.integer.config_sidefpsSkipWaitForPowerAcquireMessage, FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR); mContext.getOrCreateTestableResources().addOverride( R.integer.config_sidefpsSkipWaitForPowerVendorAcquireMessage, vendorAcquireMessage); final FingerprintAuthenticationClient client = createClient(1); client.start(mCallback); mLooper.dispatchAll(); client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */), true /* authenticated */, new ArrayList<>()); client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR, 1); mLooper.dispatchAll(); verify(mCallback, never()).onClientFinished(any(), anyBoolean()); } @Test public void sideFingerprintSendsAuthIfFingerUp() throws Exception { when(mSensorProps.isAnySidefpsType()).thenReturn(true); Loading Loading @@ -493,6 +543,79 @@ public class FingerprintAuthenticationClientTest { verify(mCallback).onClientFinished(any(), eq(true)); } @Test public void sideFingerprintPowerWindowStartsOnAcquireStart() throws Exception { final int powerWindow = 500; final long authStart = 300; when(mSensorProps.isAnySidefpsType()).thenReturn(true); mContext.getOrCreateTestableResources().addOverride( R.integer.config_sidefpsBpPowerPressWindow, powerWindow); final FingerprintAuthenticationClient client = createClient(1); client.start(mCallback); // Acquire start occurs at time = 0ms when(mClock.millis()).thenReturn(0L); client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_START, 0 /* vendorCode */); // Auth occurs at time = 300 when(mClock.millis()).thenReturn(authStart); // At this point the delay should be 500 - (300 - 0) == 200 milliseconds. client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */), true /* authenticated */, new ArrayList<>()); mLooper.dispatchAll(); verify(mCallback, never()).onClientFinished(any(), anyBoolean()); // After waiting 200 milliseconds, auth should succeed. mLooper.moveTimeForward(powerWindow - authStart); mLooper.dispatchAll(); verify(mCallback).onClientFinished(any(), eq(true)); } @Test public void sideFingerprintPowerWindowStartsOnLastAcquireStart() throws Exception { final int powerWindow = 500; when(mSensorProps.isAnySidefpsType()).thenReturn(true); mContext.getOrCreateTestableResources().addOverride( R.integer.config_sidefpsBpPowerPressWindow, powerWindow); final FingerprintAuthenticationClient client = createClient(1); client.start(mCallback); // Acquire start occurs at time = 0ms when(mClock.millis()).thenReturn(0L); client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_START, 0 /* vendorCode */); // Auth reject occurs at time = 300ms when(mClock.millis()).thenReturn(300L); client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */), false /* authenticated */, new ArrayList<>()); mLooper.dispatchAll(); mLooper.moveTimeForward(300); mLooper.dispatchAll(); verify(mCallback, never()).onClientFinished(any(), anyBoolean()); when(mClock.millis()).thenReturn(1300L); client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_START, 0 /* vendorCode */); // If code is correct, the new acquired start timestamp should be used // and the code should only have to wait 500 - (1500-1300)ms. when(mClock.millis()).thenReturn(1500L); client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */), true /* authenticated */, new ArrayList<>()); mLooper.dispatchAll(); mLooper.moveTimeForward(299); mLooper.dispatchAll(); verify(mCallback, never()).onClientFinished(any(), anyBoolean()); mLooper.moveTimeForward(1); mLooper.dispatchAll(); verify(mCallback).onClientFinished(any(), eq(true)); } private FingerprintAuthenticationClient createClient() throws RemoteException { return createClient(100 /* version */, true /* allowBackgroundAuthentication */); } Loading Loading @@ -520,7 +643,7 @@ public class FingerprintAuthenticationClientTest { null /* taskStackListener */, mLockoutCache, mUdfpsOverlayController, mSideFpsController, allowBackgroundAuthentication, mSensorProps, new Handler(mLooper.getLooper())) { new Handler(mLooper.getLooper()), mClock) { @Override protected ActivityTaskManager getActivityTaskManager() { return mActivityTaskManager; Loading Loading
core/res/res/values/config.xml +3 −3 Original line number Diff line number Diff line Loading @@ -3577,9 +3577,9 @@ config_sidefpsSkipWaitForPowerVendorAcquireMessage --> <integer name="config_sidefpsSkipWaitForPowerAcquireMessage">6</integer> <!-- This vendor acquired message that will cause the sidefpsKgPowerPress window to be skipped. config_sidefpsSkipWaitForPowerOnFingerUp must be true and config_sidefpsSkipWaitForPowerAcquireMessage must be BIOMETRIC_ACQUIRED_VENDOR == 6. --> <!-- This vendor acquired message will cause the sidefpsKgPowerPress window to be skipped when config_sidefpsSkipWaitForPowerAcquireMessage == 6 (VENDOR) and the vendor acquire message equals this constant --> <integer name="config_sidefpsSkipWaitForPowerVendorAcquireMessage">2</integer> <!-- This config is used to force VoiceInteractionService to start on certain low ram devices. Loading
services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java +20 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.biometrics.sensors.fingerprint.aidl; import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START; import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR; import android.annotation.NonNull; Loading Loading @@ -57,6 +58,7 @@ import com.android.server.biometrics.sensors.SensorOverlays; import com.android.server.biometrics.sensors.fingerprint.PowerPressHandler; import com.android.server.biometrics.sensors.fingerprint.Udfps; import java.time.Clock; import java.util.ArrayList; import java.util.function.Supplier; Loading Loading @@ -88,7 +90,9 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession> private long mWaitForAuthKeyguard; private long mWaitForAuthBp; private long mIgnoreAuthFor; private long mSideFpsLastAcquireStartTime; private Runnable mAuthSuccessRunnable; private final Clock mClock; FingerprintAuthenticationClient( @NonNull Context context, Loading @@ -112,7 +116,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession> @Nullable ISidefpsController sidefpsController, boolean allowBackgroundAuthentication, @NonNull FingerprintSensorPropertiesInternal sensorProps, @NonNull Handler handler) { @NonNull Handler handler, @NonNull Clock clock) { super( context, lazyDaemon, Loading Loading @@ -154,6 +159,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession> mSkipWaitForPowerVendorAcquireMessage = context.getResources().getInteger( R.integer.config_sidefpsSkipWaitForPowerVendorAcquireMessage); mSideFpsLastAcquireStartTime = -1; mClock = clock; if (mSensorProps.isAnySidefpsType()) { if (Build.isDebuggable()) { Loading Loading @@ -235,8 +242,14 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession> return; } delay = isKeyguard() ? mWaitForAuthKeyguard : mWaitForAuthBp; Slog.i(TAG, "(sideFPS) Auth succeeded, sideFps waiting for power for: " + delay + "ms"); if (mSideFpsLastAcquireStartTime != -1) { delay = Math.max(0, delay - (mClock.millis() - mSideFpsLastAcquireStartTime)); } Slog.i(TAG, "(sideFPS) Auth succeeded, sideFps " + "waiting for power until: " + delay + "ms"); } if (mHandler.hasMessages(MESSAGE_FINGER_UP)) { Loading @@ -260,13 +273,15 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession> mSensorOverlays.ifUdfps(controller -> controller.onAcquired(getSensorId(), acquiredInfo)); super.onAcquired(acquiredInfo, vendorCode); if (mSensorProps.isAnySidefpsType()) { if (acquiredInfo == FINGERPRINT_ACQUIRED_START) { mSideFpsLastAcquireStartTime = mClock.millis(); } final boolean shouldLookForVendor = mSkipWaitForPowerAcquireMessage == FINGERPRINT_ACQUIRED_VENDOR; final boolean acquireMessageMatch = acquiredInfo == mSkipWaitForPowerAcquireMessage; final boolean vendorMessageMatch = vendorCode == mSkipWaitForPowerVendorAcquireMessage; final boolean ignorePowerPress = (acquireMessageMatch && !shouldLookForVendor) || (shouldLookForVendor && acquireMessageMatch && vendorMessageMatch); acquireMessageMatch && (!shouldLookForVendor || vendorMessageMatch); if (ignorePowerPress) { Slog.d(TAG, "(sideFPS) onFingerUp"); Loading
services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java +3 −1 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserManager; import android.util.Slog; import android.util.SparseArray; Loading Loading @@ -447,7 +448,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi mBiometricContext, isStrongBiometric, mTaskStackListener, mSensors.get(sensorId).getLockoutCache(), mUdfpsOverlayController, mSidefpsController, allowBackgroundAuthentication, mSensors.get(sensorId).getSensorProperties(), mHandler); mSensors.get(sensorId).getSensorProperties(), mHandler, SystemClock.elapsedRealtimeClock()); scheduleForSensor(sensorId, client, mBiometricStateCallback); }); } Loading
services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java +124 −1 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.hardware.biometrics.common.OperationContext; import android.hardware.biometrics.fingerprint.ISession; import android.hardware.biometrics.fingerprint.PointerContext; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.ISidefpsController; import android.hardware.fingerprint.IUdfpsOverlayController; Loading Loading @@ -73,6 +74,7 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import java.time.Clock; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; Loading Loading @@ -128,6 +130,8 @@ public class FingerprintAuthenticationClientTest { private ICancellationSignal mCancellationSignal; @Mock private Probe mLuxProbe; @Mock private Clock mClock; @Captor private ArgumentCaptor<OperationContext> mOperationContextCaptor; @Captor Loading Loading @@ -446,6 +450,52 @@ public class FingerprintAuthenticationClientTest { verify(mCallback).onClientFinished(any(), eq(true)); } @Test public void sideFingerprintSkipsWindowIfVendorMessageMatch() throws Exception { when(mSensorProps.isAnySidefpsType()).thenReturn(true); final int vendorAcquireMessage = 1234; mContext.getOrCreateTestableResources().addOverride( R.integer.config_sidefpsSkipWaitForPowerAcquireMessage, FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR); mContext.getOrCreateTestableResources().addOverride( R.integer.config_sidefpsSkipWaitForPowerVendorAcquireMessage, vendorAcquireMessage); final FingerprintAuthenticationClient client = createClient(1); client.start(mCallback); mLooper.dispatchAll(); client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */), true /* authenticated */, new ArrayList<>()); client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR, vendorAcquireMessage); mLooper.dispatchAll(); verify(mCallback).onClientFinished(any(), eq(true)); } @Test public void sideFingerprintDoesNotSkipWindowOnVendorErrorMismatch() throws Exception { when(mSensorProps.isAnySidefpsType()).thenReturn(true); final int vendorAcquireMessage = 1234; mContext.getOrCreateTestableResources().addOverride( R.integer.config_sidefpsSkipWaitForPowerAcquireMessage, FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR); mContext.getOrCreateTestableResources().addOverride( R.integer.config_sidefpsSkipWaitForPowerVendorAcquireMessage, vendorAcquireMessage); final FingerprintAuthenticationClient client = createClient(1); client.start(mCallback); mLooper.dispatchAll(); client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */), true /* authenticated */, new ArrayList<>()); client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR, 1); mLooper.dispatchAll(); verify(mCallback, never()).onClientFinished(any(), anyBoolean()); } @Test public void sideFingerprintSendsAuthIfFingerUp() throws Exception { when(mSensorProps.isAnySidefpsType()).thenReturn(true); Loading Loading @@ -493,6 +543,79 @@ public class FingerprintAuthenticationClientTest { verify(mCallback).onClientFinished(any(), eq(true)); } @Test public void sideFingerprintPowerWindowStartsOnAcquireStart() throws Exception { final int powerWindow = 500; final long authStart = 300; when(mSensorProps.isAnySidefpsType()).thenReturn(true); mContext.getOrCreateTestableResources().addOverride( R.integer.config_sidefpsBpPowerPressWindow, powerWindow); final FingerprintAuthenticationClient client = createClient(1); client.start(mCallback); // Acquire start occurs at time = 0ms when(mClock.millis()).thenReturn(0L); client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_START, 0 /* vendorCode */); // Auth occurs at time = 300 when(mClock.millis()).thenReturn(authStart); // At this point the delay should be 500 - (300 - 0) == 200 milliseconds. client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */), true /* authenticated */, new ArrayList<>()); mLooper.dispatchAll(); verify(mCallback, never()).onClientFinished(any(), anyBoolean()); // After waiting 200 milliseconds, auth should succeed. mLooper.moveTimeForward(powerWindow - authStart); mLooper.dispatchAll(); verify(mCallback).onClientFinished(any(), eq(true)); } @Test public void sideFingerprintPowerWindowStartsOnLastAcquireStart() throws Exception { final int powerWindow = 500; when(mSensorProps.isAnySidefpsType()).thenReturn(true); mContext.getOrCreateTestableResources().addOverride( R.integer.config_sidefpsBpPowerPressWindow, powerWindow); final FingerprintAuthenticationClient client = createClient(1); client.start(mCallback); // Acquire start occurs at time = 0ms when(mClock.millis()).thenReturn(0L); client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_START, 0 /* vendorCode */); // Auth reject occurs at time = 300ms when(mClock.millis()).thenReturn(300L); client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */), false /* authenticated */, new ArrayList<>()); mLooper.dispatchAll(); mLooper.moveTimeForward(300); mLooper.dispatchAll(); verify(mCallback, never()).onClientFinished(any(), anyBoolean()); when(mClock.millis()).thenReturn(1300L); client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_START, 0 /* vendorCode */); // If code is correct, the new acquired start timestamp should be used // and the code should only have to wait 500 - (1500-1300)ms. when(mClock.millis()).thenReturn(1500L); client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */), true /* authenticated */, new ArrayList<>()); mLooper.dispatchAll(); mLooper.moveTimeForward(299); mLooper.dispatchAll(); verify(mCallback, never()).onClientFinished(any(), anyBoolean()); mLooper.moveTimeForward(1); mLooper.dispatchAll(); verify(mCallback).onClientFinished(any(), eq(true)); } private FingerprintAuthenticationClient createClient() throws RemoteException { return createClient(100 /* version */, true /* allowBackgroundAuthentication */); } Loading Loading @@ -520,7 +643,7 @@ public class FingerprintAuthenticationClientTest { null /* taskStackListener */, mLockoutCache, mUdfpsOverlayController, mSideFpsController, allowBackgroundAuthentication, mSensorProps, new Handler(mLooper.getLooper())) { new Handler(mLooper.getLooper()), mClock) { @Override protected ActivityTaskManager getActivityTaskManager() { return mActivityTaskManager; Loading