Only enable UDFPS display mode for optical sensors

Bug: 248323102
Test: atest AuthControllerTest
Test: atest UdfpsControllerTest
Change-Id: I4d215ee8d3a0495fee36a21e8a650cb08f911ba7
Merged-In: I4d215ee8d3a0495fee36a21e8a650cb08f911ba7
This commit is contained in:
Ilya Matyukhin
2022-10-13 22:44:54 +00:00
parent 116f7c93f0
commit 21a710db0e
3 changed files with 293 additions and 128 deletions

View File

@@ -777,13 +777,16 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
private void updateUdfpsLocation() { private void updateUdfpsLocation() {
if (mUdfpsController != null) { if (mUdfpsController != null) {
final FingerprintSensorPropertiesInternal udfpsProp = mUdfpsProps.get(0); final FingerprintSensorPropertiesInternal udfpsProp = mUdfpsProps.get(0);
final Rect previousUdfpsBounds = mUdfpsBounds; final Rect previousUdfpsBounds = mUdfpsBounds;
mUdfpsBounds = udfpsProp.getLocation().getRect(); mUdfpsBounds = udfpsProp.getLocation().getRect();
mUdfpsBounds.scale(mScaleFactor); mUdfpsBounds.scale(mScaleFactor);
mUdfpsController.updateOverlayParams(udfpsProp.sensorId,
new UdfpsOverlayParams(mUdfpsBounds, mCachedDisplayInfo.getNaturalWidth(), final UdfpsOverlayParams overlayParams = new UdfpsOverlayParams(mUdfpsBounds,
mCachedDisplayInfo.getNaturalHeight(), mScaleFactor, mCachedDisplayInfo.getNaturalWidth(), mCachedDisplayInfo.getNaturalHeight(),
mCachedDisplayInfo.rotation)); mScaleFactor, mCachedDisplayInfo.rotation);
mUdfpsController.updateOverlayParams(udfpsProp, overlayParams);
if (!Objects.equals(previousUdfpsBounds, mUdfpsBounds)) { if (!Objects.equals(previousUdfpsBounds, mUdfpsBounds)) {
for (Callback cb : mCallbacks) { for (Callback cb : mCallbacks) {
cb.onUdfpsLocationChanged(); cb.onUdfpsLocationChanged();

View File

@@ -23,16 +23,17 @@ import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.systemui.classifier.Classifier.LOCK_ICON; import static com.android.systemui.classifier.Classifier.LOCK_ICON;
import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION; import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.graphics.Point; import android.graphics.Point;
import android.hardware.biometrics.BiometricFingerprintConstants; import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.SensorProperties;
import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IUdfpsOverlayController; import android.hardware.fingerprint.IUdfpsOverlayController;
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback; import android.hardware.fingerprint.IUdfpsOverlayControllerCallback;
import android.os.Handler; import android.os.Handler;
@@ -50,10 +51,14 @@ import android.view.VelocityTracker;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.LatencyTracker; import com.android.internal.util.LatencyTracker;
import com.android.keyguard.FaceAuthApiRequestReason; import com.android.keyguard.FaceAuthApiRequestReason;
import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.Dumpable;
import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.biometrics.dagger.BiometricsBackground; import com.android.systemui.biometrics.dagger.BiometricsBackground;
import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.SysUISingleton;
@@ -77,6 +82,8 @@ import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.concurrency.Execution; import com.android.systemui.util.concurrency.Execution;
import com.android.systemui.util.time.SystemClock; import com.android.systemui.util.time.SystemClock;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@@ -99,7 +106,7 @@ import kotlin.Unit;
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@SysUISingleton @SysUISingleton
public class UdfpsController implements DozeReceiver { public class UdfpsController implements DozeReceiver, Dumpable {
private static final String TAG = "UdfpsController"; private static final String TAG = "UdfpsController";
private static final long AOD_INTERRUPT_TIMEOUT_MILLIS = 1000; private static final long AOD_INTERRUPT_TIMEOUT_MILLIS = 1000;
@@ -137,7 +144,7 @@ public class UdfpsController implements DozeReceiver {
// Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
// sensors, this, in addition to a lot of the code here, will be updated. // sensors, this, in addition to a lot of the code here, will be updated.
@VisibleForTesting int mSensorId; @VisibleForTesting @NonNull FingerprintSensorPropertiesInternal mSensorProps;
@VisibleForTesting @NonNull UdfpsOverlayParams mOverlayParams = new UdfpsOverlayParams(); @VisibleForTesting @NonNull UdfpsOverlayParams mOverlayParams = new UdfpsOverlayParams();
// TODO(b/229290039): UDFPS controller should manage its dimensions on its own. Remove this. // TODO(b/229290039): UDFPS controller should manage its dimensions on its own. Remove this.
@Nullable private Runnable mAuthControllerUpdateUdfpsLocation; @Nullable private Runnable mAuthControllerUpdateUdfpsLocation;
@@ -202,6 +209,11 @@ public class UdfpsController implements DozeReceiver {
} }
}; };
@Override
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("mSensorProps=(" + mSensorProps + ")");
}
public class UdfpsOverlayController extends IUdfpsOverlayController.Stub { public class UdfpsOverlayController extends IUdfpsOverlayController.Stub {
@Override @Override
public void showUdfpsOverlay(long requestId, int sensorId, int reason, public void showUdfpsOverlay(long requestId, int sensorId, int reason,
@@ -249,7 +261,7 @@ public class UdfpsController implements DozeReceiver {
} }
mAcquiredReceived = true; mAcquiredReceived = true;
final UdfpsView view = mOverlay.getOverlayView(); final UdfpsView view = mOverlay.getOverlayView();
if (view != null) { if (view != null && isOptical()) {
unconfigureDisplay(view); unconfigureDisplay(view);
} }
if (acquiredGood) { if (acquiredGood) {
@@ -295,12 +307,13 @@ public class UdfpsController implements DozeReceiver {
/** /**
* Updates the overlay parameters and reconstructs or redraws the overlay, if necessary. * Updates the overlay parameters and reconstructs or redraws the overlay, if necessary.
* *
* @param sensorId sensor for which the overlay is getting updated. * @param sensorProps sensor for which the overlay is getting updated.
* @param overlayParams See {@link UdfpsOverlayParams}. * @param overlayParams See {@link UdfpsOverlayParams}.
*/ */
public void updateOverlayParams(int sensorId, @NonNull UdfpsOverlayParams overlayParams) { public void updateOverlayParams(@NonNull FingerprintSensorPropertiesInternal sensorProps,
if (sensorId != mSensorId) { @NonNull UdfpsOverlayParams overlayParams) {
mSensorId = sensorId; if (mSensorProps.sensorId != sensorProps.sensorId) {
mSensorProps = sensorProps;
Log.w(TAG, "updateUdfpsParams | sensorId has changed"); Log.w(TAG, "updateUdfpsParams | sensorId has changed");
} }
@@ -324,7 +337,7 @@ public class UdfpsController implements DozeReceiver {
mAuthControllerUpdateUdfpsLocation = r; mAuthControllerUpdateUdfpsLocation = r;
} }
public void setUdfpsDisplayMode(UdfpsDisplayMode udfpsDisplayMode) { public void setUdfpsDisplayMode(@Nullable UdfpsDisplayMode udfpsDisplayMode) {
mUdfpsDisplayMode = udfpsDisplayMode; mUdfpsDisplayMode = udfpsDisplayMode;
} }
@@ -428,7 +441,6 @@ public class UdfpsController implements DozeReceiver {
} }
final UdfpsView udfpsView = mOverlay.getOverlayView(); final UdfpsView udfpsView = mOverlay.getOverlayView();
final boolean isDisplayConfigured = udfpsView.isDisplayConfigured();
boolean handled = false; boolean handled = false;
switch (event.getActionMasked()) { switch (event.getActionMasked()) {
case MotionEvent.ACTION_OUTSIDE: case MotionEvent.ACTION_OUTSIDE:
@@ -512,15 +524,14 @@ public class UdfpsController implements DozeReceiver {
"minor: %.1f, major: %.1f, v: %.1f, exceedsVelocityThreshold: %b", "minor: %.1f, major: %.1f, v: %.1f, exceedsVelocityThreshold: %b",
minor, major, v, exceedsVelocityThreshold); minor, major, v, exceedsVelocityThreshold);
final long sinceLastLog = mSystemClock.elapsedRealtime() - mTouchLogTime; final long sinceLastLog = mSystemClock.elapsedRealtime() - mTouchLogTime;
if (!isDisplayConfigured && !mAcquiredReceived
&& !exceedsVelocityThreshold) {
if (!mOnFingerDown && !mAcquiredReceived && !exceedsVelocityThreshold) {
final float scale = mOverlayParams.getScaleFactor(); final float scale = mOverlayParams.getScaleFactor();
float scaledMinor = minor / scale; float scaledMinor = minor / scale;
float scaledMajor = major / scale; float scaledMajor = major / scale;
onFingerDown(requestId, scaledTouch.x, scaledTouch.y, scaledMinor, onFingerDown(requestId, scaledTouch.x, scaledTouch.y, scaledMinor,
scaledMajor); scaledMajor);
Log.v(TAG, "onTouch | finger down: " + touchInfo); Log.v(TAG, "onTouch | finger down: " + touchInfo);
mTouchLogTime = mSystemClock.elapsedRealtime(); mTouchLogTime = mSystemClock.elapsedRealtime();
handled = true; handled = true;
@@ -614,7 +625,7 @@ public class UdfpsController implements DozeReceiver {
@NonNull LatencyTracker latencyTracker, @NonNull LatencyTracker latencyTracker,
@NonNull ActivityLaunchAnimator activityLaunchAnimator, @NonNull ActivityLaunchAnimator activityLaunchAnimator,
@NonNull Optional<AlternateUdfpsTouchProvider> alternateTouchProvider, @NonNull Optional<AlternateUdfpsTouchProvider> alternateTouchProvider,
@BiometricsBackground Executor biometricsExecutor, @NonNull @BiometricsBackground Executor biometricsExecutor,
@NonNull BouncerInteractor bouncerInteractor) { @NonNull BouncerInteractor bouncerInteractor) {
mContext = context; mContext = context;
mExecution = execution; mExecution = execution;
@@ -644,10 +655,20 @@ public class UdfpsController implements DozeReceiver {
mLatencyTracker = latencyTracker; mLatencyTracker = latencyTracker;
mActivityLaunchAnimator = activityLaunchAnimator; mActivityLaunchAnimator = activityLaunchAnimator;
mAlternateTouchProvider = alternateTouchProvider.orElse(null); mAlternateTouchProvider = alternateTouchProvider.orElse(null);
mSensorProps = new FingerprintSensorPropertiesInternal(
-1 /* sensorId */,
SensorProperties.STRENGTH_CONVENIENCE,
0 /* maxEnrollmentsPerUser */,
new ArrayList<>() /* componentInfo */,
FingerprintSensorProperties.TYPE_UNKNOWN,
false /* resetLockoutRequiresHardwareAuthToken */);
mBiometricExecutor = biometricsExecutor; mBiometricExecutor = biometricsExecutor;
mFeatureFlags = featureFlags; mFeatureFlags = featureFlags;
mBouncerInteractor = bouncerInteractor; mBouncerInteractor = bouncerInteractor;
mDumpManager.registerDumpable(TAG, this);
mOrientationListener = new BiometricDisplayListener( mOrientationListener = new BiometricDisplayListener(
context, context,
displayManager, displayManager,
@@ -843,6 +864,10 @@ public class UdfpsController implements DozeReceiver {
mIsAodInterruptActive = false; mIsAodInterruptActive = false;
} }
private boolean isOptical() {
return mSensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
}
public boolean isFingerDown() { public boolean isFingerDown() {
return mOnFingerDown; return mOnFingerDown;
} }
@@ -859,7 +884,9 @@ public class UdfpsController implements DozeReceiver {
+ " current: " + mOverlay.getRequestId()); + " current: " + mOverlay.getRequestId());
return; return;
} }
mLatencyTracker.onActionStart(LatencyTracker.ACTION_UDFPS_ILLUMINATE); if (isOptical()) {
mLatencyTracker.onActionStart(LatencyTracker.ACTION_UDFPS_ILLUMINATE);
}
// Refresh screen timeout and boost process priority if possible. // Refresh screen timeout and boost process priority if possible.
mPowerManager.userActivity(mSystemClock.uptimeMillis(), mPowerManager.userActivity(mSystemClock.uptimeMillis(),
PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0); PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
@@ -882,11 +909,11 @@ public class UdfpsController implements DozeReceiver {
} }
}); });
} else { } else {
mFingerprintManager.onPointerDown(requestId, mSensorId, x, y, minor, major); mFingerprintManager.onPointerDown(requestId, mSensorProps.sensorId, x, y, minor, major);
} }
Trace.endAsyncSection("UdfpsController.e2e.onPointerDown", 0); Trace.endAsyncSection("UdfpsController.e2e.onPointerDown", 0);
final UdfpsView view = mOverlay.getOverlayView(); final UdfpsView view = mOverlay.getOverlayView();
if (view != null) { if (view != null && isOptical()) {
view.configureDisplay(() -> { view.configureDisplay(() -> {
if (mAlternateTouchProvider != null) { if (mAlternateTouchProvider != null) {
mBiometricExecutor.execute(() -> { mBiometricExecutor.execute(() -> {
@@ -894,7 +921,7 @@ public class UdfpsController implements DozeReceiver {
mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE); mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE);
}); });
} else { } else {
mFingerprintManager.onUiReady(requestId, mSensorId); mFingerprintManager.onUiReady(requestId, mSensorProps.sensorId);
mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE); mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE);
} }
}); });
@@ -920,15 +947,16 @@ public class UdfpsController implements DozeReceiver {
} }
}); });
} else { } else {
mFingerprintManager.onPointerUp(requestId, mSensorId); mFingerprintManager.onPointerUp(requestId, mSensorProps.sensorId);
} }
for (Callback cb : mCallbacks) { for (Callback cb : mCallbacks) {
cb.onFingerUp(); cb.onFingerUp();
} }
} }
mOnFingerDown = false; mOnFingerDown = false;
unconfigureDisplay(view); if (isOptical()) {
unconfigureDisplay(view);
}
} }
/** /**

View File

@@ -20,6 +20,8 @@ import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_MOVE; import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_UP; import static android.view.MotionEvent.ACTION_UP;
import static com.android.internal.util.FunctionalUtils.ThrowingConsumer;
import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
@@ -108,9 +110,6 @@ import java.util.Optional;
@RunWithLooper(setAsMainLooper = true) @RunWithLooper(setAsMainLooper = true)
public class UdfpsControllerTest extends SysuiTestCase { public class UdfpsControllerTest extends SysuiTestCase {
// Use this for inputs going into SystemUI. Use UdfpsController.mUdfpsSensorId for things
// leaving SystemUI.
private static final int TEST_UDFPS_SENSOR_ID = 1;
private static final long TEST_REQUEST_ID = 70; private static final long TEST_REQUEST_ID = 70;
@Rule @Rule
@@ -121,7 +120,6 @@ public class UdfpsControllerTest extends SysuiTestCase {
// Dependencies // Dependencies
private FakeExecutor mBiometricsExecutor; private FakeExecutor mBiometricsExecutor;
private Execution mExecution;
@Mock @Mock
private LayoutInflater mLayoutInflater; private LayoutInflater mLayoutInflater;
@Mock @Mock
@@ -129,8 +127,6 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Mock @Mock
private WindowManager mWindowManager; private WindowManager mWindowManager;
@Mock @Mock
private UdfpsDisplayModeProvider mDisplayModeProvider;
@Mock
private StatusBarStateController mStatusBarStateController; private StatusBarStateController mStatusBarStateController;
@Mock @Mock
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@@ -199,17 +195,24 @@ public class UdfpsControllerTest extends SysuiTestCase {
private BouncerInteractor mBouncerInteractor; private BouncerInteractor mBouncerInteractor;
// Capture listeners so that they can be used to send events // Capture listeners so that they can be used to send events
@Captor private ArgumentCaptor<IUdfpsOverlayController> mOverlayCaptor; @Captor
private ArgumentCaptor<IUdfpsOverlayController> mOverlayCaptor;
private IUdfpsOverlayController mOverlayController; private IUdfpsOverlayController mOverlayController;
@Captor private ArgumentCaptor<UdfpsView.OnTouchListener> mTouchListenerCaptor; @Captor
@Captor private ArgumentCaptor<View.OnHoverListener> mHoverListenerCaptor; private ArgumentCaptor<UdfpsView.OnTouchListener> mTouchListenerCaptor;
@Captor private ArgumentCaptor<Runnable> mOnDisplayConfiguredCaptor; @Captor
@Captor private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor; private ArgumentCaptor<View.OnHoverListener> mHoverListenerCaptor;
@Captor
private ArgumentCaptor<Runnable> mOnDisplayConfiguredCaptor;
@Captor
private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor;
private ScreenLifecycle.Observer mScreenObserver; private ScreenLifecycle.Observer mScreenObserver;
private FingerprintSensorPropertiesInternal mOpticalProps;
private FingerprintSensorPropertiesInternal mUltrasonicProps;
@Before @Before
public void setUp() { public void setUp() {
mExecution = new FakeExecution(); Execution execution = new FakeExecution();
when(mLayoutInflater.inflate(R.layout.udfps_view, null, false)) when(mLayoutInflater.inflate(R.layout.udfps_view, null, false))
.thenReturn(mUdfpsView); .thenReturn(mUdfpsView);
@@ -222,9 +225,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
when(mLayoutInflater.inflate(R.layout.udfps_fpm_other_view, null)) when(mLayoutInflater.inflate(R.layout.udfps_fpm_other_view, null))
.thenReturn(mFpmOtherView); .thenReturn(mFpmOtherView);
when(mEnrollView.getContext()).thenReturn(mContext); when(mEnrollView.getContext()).thenReturn(mContext);
when(mKeyguardStateController.isOccluded()).thenReturn(false);
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true); when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
final List<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
final List<ComponentInfoInternal> componentInfo = new ArrayList<>(); final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */, componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
@@ -234,13 +235,25 @@ public class UdfpsControllerTest extends SysuiTestCase {
"" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */, "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
"vendor/version/revision" /* softwareVersion */)); "vendor/version/revision" /* softwareVersion */));
props.add(new FingerprintSensorPropertiesInternal(TEST_UDFPS_SENSOR_ID, mOpticalProps = new FingerprintSensorPropertiesInternal(1 /* sensorId */,
SensorProperties.STRENGTH_STRONG, SensorProperties.STRENGTH_STRONG,
5 /* maxEnrollmentsPerUser */, 5 /* maxEnrollmentsPerUser */,
componentInfo, componentInfo,
FingerprintSensorProperties.TYPE_UDFPS_OPTICAL, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
true /* resetLockoutRequiresHardwareAuthToken */)); true /* resetLockoutRequiresHardwareAuthToken */);
mUltrasonicProps = new FingerprintSensorPropertiesInternal(2 /* sensorId */,
SensorProperties.STRENGTH_STRONG,
5 /* maxEnrollmentsPerUser */,
componentInfo,
FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC,
true /* resetLockoutRequiresHardwareAuthToken */);
List<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
props.add(mOpticalProps);
props.add(mUltrasonicProps);
when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props); when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props);
mFgExecutor = new FakeExecutor(new FakeSystemClock()); mFgExecutor = new FakeExecutor(new FakeSystemClock());
// Create a fake background executor. // Create a fake background executor.
@@ -248,7 +261,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
mUdfpsController = new UdfpsController( mUdfpsController = new UdfpsController(
mContext, mContext,
mExecution, execution,
mLayoutInflater, mLayoutInflater,
mFingerprintManager, mFingerprintManager,
mWindowManager, mWindowManager,
@@ -283,13 +296,13 @@ public class UdfpsControllerTest extends SysuiTestCase {
mOverlayController = mOverlayCaptor.getValue(); mOverlayController = mOverlayCaptor.getValue();
verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture()); verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
mScreenObserver = mScreenObserverCaptor.getValue(); mScreenObserver = mScreenObserverCaptor.getValue();
mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, new UdfpsOverlayParams()); mUdfpsController.updateOverlayParams(mOpticalProps, new UdfpsOverlayParams());
mUdfpsController.setUdfpsDisplayMode(mUdfpsDisplayMode); mUdfpsController.setUdfpsDisplayMode(mUdfpsDisplayMode);
} }
@Test @Test
public void dozeTimeTick() throws RemoteException { public void dozeTimeTick() throws RemoteException {
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
mUdfpsController.dozeTimeTick(); mUdfpsController.dozeTimeTick();
@@ -304,7 +317,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController); when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController);
// GIVEN that the overlay is showing // GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
@@ -339,7 +352,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController); when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController);
// GIVEN that the overlay is showing // GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
@@ -347,7 +360,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
if (stale) { if (stale) {
mOverlayController.hideUdfpsOverlay(TEST_UDFPS_SENSOR_ID); mOverlayController.hideUdfpsOverlay(mOpticalProps.sensorId);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
} }
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
@@ -367,7 +380,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController); when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController);
// GIVEN that the overlay is showing // GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
@@ -390,12 +403,12 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Test @Test
public void hideUdfpsOverlay_resetsAltAuthBouncerWhenShowing() throws RemoteException { public void hideUdfpsOverlay_resetsAltAuthBouncerWhenShowing() throws RemoteException {
// GIVEN overlay was showing and the udfps bouncer is showing // GIVEN overlay was showing and the udfps bouncer is showing
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
when(mStatusBarKeyguardViewManager.isShowingAlternateAuth()).thenReturn(true); when(mStatusBarKeyguardViewManager.isShowingAlternateAuth()).thenReturn(true);
// WHEN the overlay is hidden // WHEN the overlay is hidden
mOverlayController.hideUdfpsOverlay(TEST_UDFPS_SENSOR_ID); mOverlayController.hideUdfpsOverlay(mOpticalProps.sensorId);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
// THEN the udfps bouncer is reset // THEN the udfps bouncer is reset
@@ -404,13 +417,13 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Test @Test
public void testSubscribesToOrientationChangesWhenShowingOverlay() throws Exception { public void testSubscribesToOrientationChangesWhenShowingOverlay() throws Exception {
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
verify(mDisplayManager).registerDisplayListener(any(), eq(mHandler), anyLong()); verify(mDisplayManager).registerDisplayListener(any(), eq(mHandler), anyLong());
mOverlayController.hideUdfpsOverlay(TEST_UDFPS_SENSOR_ID); mOverlayController.hideUdfpsOverlay(mOpticalProps.sensorId);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
verify(mDisplayManager).unregisterDisplayListener(any()); verify(mDisplayManager).unregisterDisplayListener(any());
@@ -440,12 +453,12 @@ public class UdfpsControllerTest extends SysuiTestCase {
} }
// Initialize the overlay with old parameters. // Initialize the overlay with old parameters.
mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, oldParams); mUdfpsController.updateOverlayParams(mOpticalProps, oldParams);
// Show the overlay. // Show the overlay.
reset(mWindowManager); reset(mWindowManager);
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID,
TEST_UDFPS_SENSOR_ID, mOpticalProps.sensorId,
BiometricOverlayConstants.REASON_ENROLL_ENROLLING, BiometricOverlayConstants.REASON_ENROLL_ENROLLING,
mUdfpsOverlayControllerCallback); mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
@@ -453,7 +466,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// Update overlay parameters. // Update overlay parameters.
reset(mWindowManager); reset(mWindowManager);
mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, newParams); mUdfpsController.updateOverlayParams(mOpticalProps, newParams);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
// Ensure the overlay was recreated. // Ensure the overlay was recreated.
@@ -475,18 +488,18 @@ public class UdfpsControllerTest extends SysuiTestCase {
final int rotation = Surface.ROTATION_0; final int rotation = Surface.ROTATION_0;
// Initialize the overlay. // Initialize the overlay.
mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, mUdfpsController.updateOverlayParams(mOpticalProps,
new UdfpsOverlayParams(sensorBounds, displayWidth, displayHeight, scaleFactor, new UdfpsOverlayParams(sensorBounds, displayWidth, displayHeight, scaleFactor,
rotation)); rotation));
// Show the overlay. // Show the overlay.
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
BiometricOverlayConstants.REASON_ENROLL_ENROLLING, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_ENROLL_ENROLLING, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
verify(mWindowManager).addView(any(), any()); verify(mWindowManager).addView(any(), any());
// Update overlay with the same parameters. // Update overlay with the same parameters.
mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, mUdfpsController.updateOverlayParams(mOpticalProps,
new UdfpsOverlayParams(sensorBounds, displayWidth, displayHeight, scaleFactor, new UdfpsOverlayParams(sensorBounds, displayWidth, displayHeight, scaleFactor,
rotation)); rotation));
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
@@ -528,13 +541,13 @@ public class UdfpsControllerTest extends SysuiTestCase {
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
// Show the overlay. // Show the overlay.
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
BiometricOverlayConstants.REASON_ENROLL_ENROLLING, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_ENROLL_ENROLLING, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
// Test ROTATION_0 // Test ROTATION_0
mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, mUdfpsController.updateOverlayParams(mOpticalProps,
new UdfpsOverlayParams(sensorBounds, displayWidth, displayHeight, scaleFactor, new UdfpsOverlayParams(sensorBounds, displayWidth, displayHeight, scaleFactor,
Surface.ROTATION_0)); Surface.ROTATION_0));
MotionEvent event = obtainMotionEvent(ACTION_DOWN, displayWidth, displayHeight, touchMinor, MotionEvent event = obtainMotionEvent(ACTION_DOWN, displayWidth, displayHeight, touchMinor,
@@ -551,7 +564,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// Test ROTATION_90 // Test ROTATION_90
reset(mAlternateTouchProvider); reset(mAlternateTouchProvider);
mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, mUdfpsController.updateOverlayParams(mOpticalProps,
new UdfpsOverlayParams(sensorBounds, displayWidth, displayHeight, scaleFactor, new UdfpsOverlayParams(sensorBounds, displayWidth, displayHeight, scaleFactor,
Surface.ROTATION_90)); Surface.ROTATION_90));
event = obtainMotionEvent(ACTION_DOWN, displayHeight, 0, touchMinor, touchMajor); event = obtainMotionEvent(ACTION_DOWN, displayHeight, 0, touchMinor, touchMajor);
@@ -567,7 +580,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// Test ROTATION_270 // Test ROTATION_270
reset(mAlternateTouchProvider); reset(mAlternateTouchProvider);
mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, mUdfpsController.updateOverlayParams(mOpticalProps,
new UdfpsOverlayParams(sensorBounds, displayWidth, displayHeight, scaleFactor, new UdfpsOverlayParams(sensorBounds, displayWidth, displayHeight, scaleFactor,
Surface.ROTATION_270)); Surface.ROTATION_270));
event = obtainMotionEvent(ACTION_DOWN, 0, displayWidth, touchMinor, touchMajor); event = obtainMotionEvent(ACTION_DOWN, 0, displayWidth, touchMinor, touchMajor);
@@ -583,7 +596,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// Test ROTATION_180 // Test ROTATION_180
reset(mAlternateTouchProvider); reset(mAlternateTouchProvider);
mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, mUdfpsController.updateOverlayParams(mOpticalProps,
new UdfpsOverlayParams(sensorBounds, displayWidth, displayHeight, scaleFactor, new UdfpsOverlayParams(sensorBounds, displayWidth, displayHeight, scaleFactor,
Surface.ROTATION_180)); Surface.ROTATION_180));
// ROTATION_180 is not supported. It should be treated like ROTATION_0. // ROTATION_180 is not supported. It should be treated like ROTATION_0.
@@ -599,63 +612,108 @@ public class UdfpsControllerTest extends SysuiTestCase {
eq(expectedY), eq(expectedMinor), eq(expectedMajor)); eq(expectedY), eq(expectedMinor), eq(expectedMajor));
} }
private void runForAllUdfpsTypes(
ThrowingConsumer<FingerprintSensorPropertiesInternal> sensorPropsConsumer) {
for (FingerprintSensorPropertiesInternal sensorProps : List.of(mOpticalProps,
mUltrasonicProps)) {
mUdfpsController.updateOverlayParams(sensorProps, new UdfpsOverlayParams());
sensorPropsConsumer.accept(sensorProps);
}
}
@Test @Test
public void fingerDown() throws RemoteException { public void fingerDown() {
runForAllUdfpsTypes(this::fingerDownForSensor);
}
private void fingerDownForSensor(FingerprintSensorPropertiesInternal sensorProps)
throws RemoteException {
reset(mUdfpsView, mAlternateTouchProvider, mFingerprintManager, mLatencyTracker,
mKeyguardUpdateMonitor);
// Configure UdfpsView to accept the ACTION_DOWN event // Configure UdfpsView to accept the ACTION_DOWN event
when(mUdfpsView.isDisplayConfigured()).thenReturn(false); when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true); when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
// GIVEN that the overlay is showing // GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, sensorProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
// WHEN ACTION_DOWN is received
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
// WHEN ACTION_DOWN is received
MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0); MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
mBiometricsExecutor.runAllReady(); mBiometricsExecutor.runAllReady();
downEvent.recycle(); downEvent.recycle();
MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
// FIX THIS TEST MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
mBiometricsExecutor.runAllReady(); mBiometricsExecutor.runAllReady();
moveEvent.recycle(); moveEvent.recycle();
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
// THEN FingerprintManager is notified about onPointerDown // THEN FingerprintManager is notified about onPointerDown
verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(0), eq(0), eq(0f), verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(0), eq(0), eq(0f),
eq(0f)); eq(0f));
verify(mFingerprintManager, never()).onPointerDown(anyLong(), anyInt(), anyInt(), anyInt(), verify(mFingerprintManager, never()).onPointerDown(anyLong(), anyInt(), anyInt(), anyInt(),
anyFloat(), anyFloat()); anyFloat(), anyFloat());
verify(mLatencyTracker).onActionStart(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
// AND display configuration begins // AND display configuration begins
verify(mUdfpsView).configureDisplay(mOnDisplayConfiguredCaptor.capture()); if (sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) {
verify(mLatencyTracker).onActionStart(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
verify(mUdfpsView).configureDisplay(mOnDisplayConfiguredCaptor.capture());
} else {
verify(mLatencyTracker, never()).onActionStart(
eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
verify(mUdfpsView, never()).configureDisplay(any());
}
verify(mLatencyTracker, never()).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE)); verify(mLatencyTracker, never()).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
verify(mKeyguardUpdateMonitor).onUdfpsPointerDown(eq((int) TEST_REQUEST_ID)); verify(mKeyguardUpdateMonitor).onUdfpsPointerDown(eq((int) TEST_REQUEST_ID));
// AND onDisplayConfigured notifies FingerprintManager about onUiReady
mOnDisplayConfiguredCaptor.getValue().run(); if (sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) {
mBiometricsExecutor.runAllReady(); // AND onDisplayConfigured notifies FingerprintManager about onUiReady
InOrder inOrder = inOrder(mAlternateTouchProvider, mLatencyTracker); mOnDisplayConfiguredCaptor.getValue().run();
inOrder.verify(mAlternateTouchProvider).onUiReady(); mBiometricsExecutor.runAllReady();
inOrder.verify(mLatencyTracker).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE)); InOrder inOrder = inOrder(mAlternateTouchProvider, mLatencyTracker);
inOrder.verify(mAlternateTouchProvider).onUiReady();
inOrder.verify(mLatencyTracker).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
} else {
verify(mAlternateTouchProvider, never()).onUiReady();
verify(mLatencyTracker, never()).onActionEnd(
eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
}
} }
@Test @Test
public void aodInterrupt() throws RemoteException { public void aodInterrupt() {
runForAllUdfpsTypes(this::aodInterruptForSensor);
}
private void aodInterruptForSensor(FingerprintSensorPropertiesInternal sensorProps)
throws RemoteException {
mUdfpsController.cancelAodInterrupt();
reset(mUdfpsView, mAlternateTouchProvider, mFingerprintManager, mKeyguardUpdateMonitor);
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
// GIVEN that the overlay is showing and screen is on and fp is running // GIVEN that the overlay is showing and screen is on and fp is running
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, sensorProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn(); mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
// WHEN fingerprint is requested because of AOD interrupt // WHEN fingerprint is requested because of AOD interrupt
mUdfpsController.onAodInterrupt(0, 0, 2f, 3f); mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
// THEN display configuration begins if (sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) {
// AND onDisplayConfigured notifies FingerprintManager about onUiReady // THEN display configuration begins
verify(mUdfpsView).configureDisplay(mOnDisplayConfiguredCaptor.capture()); // AND onDisplayConfigured notifies FingerprintManager about onUiReady
mOnDisplayConfiguredCaptor.getValue().run(); verify(mUdfpsView).configureDisplay(mOnDisplayConfiguredCaptor.capture());
mOnDisplayConfiguredCaptor.getValue().run();
} else {
verify(mUdfpsView, never()).configureDisplay(mOnDisplayConfiguredCaptor.capture());
}
mBiometricsExecutor.runAllReady(); mBiometricsExecutor.runAllReady();
verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID),
eq(0), eq(0), eq(3f) /* minor */, eq(2f) /* major */); eq(0), eq(0), eq(3f) /* minor */, eq(2f) /* major */);
@@ -665,54 +723,92 @@ public class UdfpsControllerTest extends SysuiTestCase {
} }
@Test @Test
public void cancelAodInterrupt() throws RemoteException { public void cancelAodInterrupt() {
runForAllUdfpsTypes(this::cancelAodInterruptForSensor);
}
private void cancelAodInterruptForSensor(FingerprintSensorPropertiesInternal sensorProps)
throws RemoteException {
reset(mUdfpsView);
// GIVEN AOD interrupt // GIVEN AOD interrupt
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, sensorProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn(); mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
when(mUdfpsView.isDisplayConfigured()).thenReturn(true); if (sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) {
// WHEN it is cancelled when(mUdfpsView.isDisplayConfigured()).thenReturn(true);
mUdfpsController.cancelAodInterrupt(); // WHEN it is cancelled
// THEN the display is unconfigured mUdfpsController.cancelAodInterrupt();
verify(mUdfpsView).unconfigureDisplay(); // THEN the display is unconfigured
verify(mUdfpsView).unconfigureDisplay();
} else {
when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
// WHEN it is cancelled
mUdfpsController.cancelAodInterrupt();
// THEN the display configuration is unchanged.
verify(mUdfpsView, never()).unconfigureDisplay();
}
} }
@Test @Test
public void aodInterruptTimeout() throws RemoteException { public void aodInterruptTimeout() {
runForAllUdfpsTypes(this::aodInterruptTimeoutForSensor);
}
private void aodInterruptTimeoutForSensor(FingerprintSensorPropertiesInternal sensorProps)
throws RemoteException {
reset(mUdfpsView);
// GIVEN AOD interrupt // GIVEN AOD interrupt
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, sensorProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn(); mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
when(mUdfpsView.isDisplayConfigured()).thenReturn(true); if (sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) {
when(mUdfpsView.isDisplayConfigured()).thenReturn(true);
} else {
when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
}
// WHEN it times out // WHEN it times out
mFgExecutor.advanceClockToNext(); mFgExecutor.advanceClockToNext();
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
// THEN the display is unconfigured if (sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) {
verify(mUdfpsView).unconfigureDisplay(); // THEN the display is unconfigured.
verify(mUdfpsView).unconfigureDisplay();
} else {
// THEN the display configuration is unchanged.
verify(mUdfpsView, never()).unconfigureDisplay();
}
} }
@Test @Test
public void aodInterruptCancelTimeoutActionOnFingerUp() throws RemoteException { public void aodInterruptCancelTimeoutActionOnFingerUp() {
runForAllUdfpsTypes(this::aodInterruptCancelTimeoutActionOnFingerUpForSensor);
}
private void aodInterruptCancelTimeoutActionOnFingerUpForSensor(
FingerprintSensorPropertiesInternal sensorProps) throws RemoteException {
reset(mUdfpsView);
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
// GIVEN AOD interrupt // GIVEN AOD interrupt
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, sensorProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn(); mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
// Configure UdfpsView to accept the ACTION_UP event if (sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) {
when(mUdfpsView.isDisplayConfigured()).thenReturn(true); // Configure UdfpsView to accept the ACTION_UP event
when(mUdfpsView.isDisplayConfigured()).thenReturn(true);
} else {
when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
}
// WHEN ACTION_UP is received // WHEN ACTION_UP is received
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
@@ -737,37 +833,54 @@ public class UdfpsControllerTest extends SysuiTestCase {
moveEvent.recycle(); moveEvent.recycle();
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
// Configure UdfpsView to accept the finger up event if (sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) {
when(mUdfpsView.isDisplayConfigured()).thenReturn(true); // Configure UdfpsView to accept the finger up event
when(mUdfpsView.isDisplayConfigured()).thenReturn(true);
} else {
when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
}
// WHEN it times out // WHEN it times out
mFgExecutor.advanceClockToNext(); mFgExecutor.advanceClockToNext();
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
// THEN the display should be unconfigured once. If the timeout action is not if (sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) {
// cancelled, the display would be unconfigured twice which would cause two // THEN the display should be unconfigured once. If the timeout action is not
// FP attempts. // cancelled, the display would be unconfigured twice which would cause two
verify(mUdfpsView, times(1)).unconfigureDisplay(); // FP attempts.
verify(mUdfpsView, times(1)).unconfigureDisplay();
} else {
verify(mUdfpsView, never()).unconfigureDisplay();
}
} }
@Test @Test
public void aodInterruptCancelTimeoutActionOnAcquired() throws RemoteException { public void aodInterruptCancelTimeoutActionOnAcquired() {
runForAllUdfpsTypes(this::aodInterruptCancelTimeoutActionOnAcquiredForSensor);
}
private void aodInterruptCancelTimeoutActionOnAcquiredForSensor(
FingerprintSensorPropertiesInternal sensorProps) throws RemoteException {
reset(mUdfpsView);
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
// GIVEN AOD interrupt // GIVEN AOD interrupt
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, sensorProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn(); mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
// Configure UdfpsView to accept the acquired event if (sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) {
when(mUdfpsView.isDisplayConfigured()).thenReturn(true); // Configure UdfpsView to accept the acquired event
when(mUdfpsView.isDisplayConfigured()).thenReturn(true);
} else {
when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
}
// WHEN acquired is received // WHEN acquired is received
mOverlayController.onAcquired(TEST_UDFPS_SENSOR_ID, mOverlayController.onAcquired(sensorProps.sensorId,
BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD); BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD);
// Configure UdfpsView to accept the ACTION_DOWN event // Configure UdfpsView to accept the ACTION_DOWN event
@@ -787,29 +900,43 @@ public class UdfpsControllerTest extends SysuiTestCase {
moveEvent.recycle(); moveEvent.recycle();
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
// Configure UdfpsView to accept the finger up event if (sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) {
when(mUdfpsView.isDisplayConfigured()).thenReturn(true); // Configure UdfpsView to accept the finger up event
when(mUdfpsView.isDisplayConfigured()).thenReturn(true);
} else {
when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
}
// WHEN it times out // WHEN it times out
mFgExecutor.advanceClockToNext(); mFgExecutor.advanceClockToNext();
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
// THEN the display should be unconfigured once. If the timeout action is not if (sensorProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) {
// cancelled, the display would be unconfigured twice which would cause two // THEN the display should be unconfigured once. If the timeout action is not
// FP attempts. // cancelled, the display would be unconfigured twice which would cause two
verify(mUdfpsView, times(1)).unconfigureDisplay(); // FP attempts.
verify(mUdfpsView, times(1)).unconfigureDisplay();
} else {
verify(mUdfpsView, never()).unconfigureDisplay();
}
} }
@Test @Test
public void aodInterruptScreenOff() throws RemoteException { public void aodInterruptScreenOff() {
runForAllUdfpsTypes(this::aodInterruptScreenOffForSensor);
}
private void aodInterruptScreenOffForSensor(FingerprintSensorPropertiesInternal sensorProps)
throws RemoteException {
reset(mUdfpsView);
// GIVEN screen off // GIVEN screen off
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, sensorProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOff(); mScreenObserver.onScreenTurnedOff();
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
// WHEN aod interrupt is received // WHEN aod interrupt is received
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
// THEN display doesn't get configured because it's off // THEN display doesn't get configured because it's off
@@ -817,9 +944,16 @@ public class UdfpsControllerTest extends SysuiTestCase {
} }
@Test @Test
public void aodInterrupt_fingerprintNotRunning() throws RemoteException { public void aodInterrupt_fingerprintNotRunning() {
runForAllUdfpsTypes(this::aodInterrupt_fingerprintNotRunningForSensor);
}
private void aodInterrupt_fingerprintNotRunningForSensor(
FingerprintSensorPropertiesInternal sensorProps) throws RemoteException {
reset(mUdfpsView);
// GIVEN showing overlay // GIVEN showing overlay
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, sensorProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, BiometricOverlayConstants.REASON_AUTH_KEYGUARD,
mUdfpsOverlayControllerCallback); mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn(); mScreenObserver.onScreenTurnedOn();
@@ -841,7 +975,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// GIVEN that the overlay is showing and a11y touch exploration enabled // GIVEN that the overlay is showing and a11y touch exploration enabled
when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true); when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
@@ -876,7 +1010,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// GIVEN that the overlay is showing and a11y touch exploration NOT enabled // GIVEN that the overlay is showing and a11y touch exploration NOT enabled
when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false); when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID, mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();