Merge "Add missing @Test annotation to ignoresGesture_transitionInProgress This change is intentionally a no-op on master because the tag already exists on master."
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index c0e1be1..7775f50 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -53,6 +53,7 @@
 import com.android.internal.util.LatencyTracker;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.animation.ActivityLaunchAnimator;
+import com.android.systemui.biometrics.dagger.BiometricsBackground;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -76,6 +77,7 @@
 import java.util.HashSet;
 import java.util.Optional;
 import java.util.Set;
+import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
 
@@ -107,6 +109,7 @@
     @NonNull private final LayoutInflater mInflater;
     private final WindowManager mWindowManager;
     private final DelayableExecutor mFgExecutor;
+    @NonNull private final Executor mBiometricExecutor;
     @NonNull private final PanelExpansionStateManager mPanelExpansionStateManager;
     @NonNull private final StatusBarStateController mStatusBarStateController;
     @NonNull private final KeyguardStateController mKeyguardStateController;
@@ -603,7 +606,8 @@
             @NonNull LatencyTracker latencyTracker,
             @NonNull ActivityLaunchAnimator activityLaunchAnimator,
             @NonNull Optional<AlternateUdfpsTouchProvider> aternateTouchProvider,
-            @NonNull BroadcastSender broadcastSender) {
+            @NonNull BroadcastSender broadcastSender,
+            @BiometricsBackground Executor biometricsExecutor) {
         mContext = context;
         mExecution = execution;
         mVibrator = vibrator;
@@ -634,6 +638,7 @@
         mActivityLaunchAnimator = activityLaunchAnimator;
         mAlternateTouchProvider = aternateTouchProvider.orElse(null);
         mBroadcastSender = broadcastSender;
+        mBiometricExecutor = biometricsExecutor;
 
         mOrientationListener = new BiometricDisplayListener(
                 context,
@@ -837,7 +842,9 @@
         }
         mOnFingerDown = true;
         if (mAlternateTouchProvider != null) {
-            mAlternateTouchProvider.onPointerDown(requestId, x, y, minor, major);
+            mBiometricExecutor.execute(() -> {
+                mAlternateTouchProvider.onPointerDown(requestId, x, y, minor, major);
+            });
             mFgExecutor.execute(() -> {
                 if (mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
                     mKeyguardUpdateMonitor.onUdfpsPointerDown((int) requestId);
@@ -847,16 +854,18 @@
             mFingerprintManager.onPointerDown(requestId, mSensorId, x, y, minor, major);
         }
         Trace.endAsyncSection("UdfpsController.e2e.onPointerDown", 0);
-
         final UdfpsView view = mOverlay.getOverlayView();
         if (view != null) {
             view.startIllumination(() -> {
                 if (mAlternateTouchProvider != null) {
-                    mAlternateTouchProvider.onUiReady();
+                    mBiometricExecutor.execute(() -> {
+                        mAlternateTouchProvider.onUiReady();
+                        mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE);
+                    });
                 } else {
                     mFingerprintManager.onUiReady(requestId, mSensorId);
+                    mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE);
                 }
-                mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE);
             });
         }
 
@@ -871,7 +880,9 @@
         mAcquiredReceived = false;
         if (mOnFingerDown) {
             if (mAlternateTouchProvider != null) {
-                mAlternateTouchProvider.onPointerUp(requestId);
+                mBiometricExecutor.execute(() -> {
+                    mAlternateTouchProvider.onPointerUp(requestId);
+                });
                 mFgExecutor.execute(() -> {
                     if (mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
                         mKeyguardUpdateMonitor.onUdfpsPointerUp((int) requestId);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index e6832a2..554e27d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -117,6 +117,7 @@
     private UdfpsController mUdfpsController;
 
     // Dependencies
+    private FakeExecutor mBiometricsExecutor;
     private Execution mExecution;
     @Mock
     private LayoutInflater mLayoutInflater;
@@ -234,6 +235,10 @@
                 true /* resetLockoutRequiresHardwareAuthToken */));
         when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props);
         mFgExecutor = new FakeExecutor(new FakeSystemClock());
+
+        // Create a fake background executor.
+        mBiometricsExecutor = new FakeExecutor(new FakeSystemClock());
+
         mUdfpsController = new UdfpsController(
                 mContext,
                 mExecution,
@@ -265,7 +270,8 @@
                 mLatencyTracker,
                 mActivityLaunchAnimator,
                 Optional.of(mAlternateTouchProvider),
-                mBroadcastSender);
+                mBroadcastSender,
+                mBiometricsExecutor);
         verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
         mOverlayController = mOverlayCaptor.getValue();
         verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
@@ -298,6 +304,7 @@
         verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
         MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
+        mBiometricsExecutor.runAllReady();
         downEvent.recycle();
 
         // THEN notify keyguard authenticate to dismiss the keyguard
@@ -336,6 +343,7 @@
             mFgExecutor.runAllReady();
         }
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
+        mBiometricsExecutor.runAllReady();
         moveEvent.recycle();
 
         // THEN notify keyguard authenticate to dismiss the keyguard
@@ -359,10 +367,12 @@
         verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
         MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
+        mBiometricsExecutor.runAllReady();
         downEvent.recycle();
         MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
+        mBiometricsExecutor.runAllReady();
         moveEvent.recycle();
 
         // THEN notify keyguard authenticate to dismiss the keyguard
@@ -516,9 +526,11 @@
         MotionEvent event = obtainMotionEvent(ACTION_DOWN, displayWidth, displayHeight, touchMinor,
                 touchMajor);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
+        mBiometricsExecutor.runAllReady();
         event.recycle();
         event = obtainMotionEvent(ACTION_MOVE, displayWidth, displayHeight, touchMinor, touchMajor);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
+        mBiometricsExecutor.runAllReady();
         event.recycle();
         verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(expectedX),
                 eq(expectedY), eq(expectedMinor), eq(expectedMajor));
@@ -530,9 +542,11 @@
                         Surface.ROTATION_90));
         event = obtainMotionEvent(ACTION_DOWN, displayHeight, 0, touchMinor, touchMajor);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
+        mBiometricsExecutor.runAllReady();
         event.recycle();
         event = obtainMotionEvent(ACTION_MOVE, displayHeight, 0, touchMinor, touchMajor);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
+        mBiometricsExecutor.runAllReady();
         event.recycle();
         verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(expectedX),
                 eq(expectedY), eq(expectedMinor), eq(expectedMajor));
@@ -544,9 +558,11 @@
                         Surface.ROTATION_270));
         event = obtainMotionEvent(ACTION_DOWN, 0, displayWidth, touchMinor, touchMajor);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
+        mBiometricsExecutor.runAllReady();
         event.recycle();
         event = obtainMotionEvent(ACTION_MOVE, 0, displayWidth, touchMinor, touchMajor);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
+        mBiometricsExecutor.runAllReady();
         event.recycle();
         verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(expectedX),
                 eq(expectedY), eq(expectedMinor), eq(expectedMajor));
@@ -559,9 +575,11 @@
         // ROTATION_180 is not supported. It should be treated like ROTATION_0.
         event = obtainMotionEvent(ACTION_DOWN, displayWidth, displayHeight, touchMinor, touchMajor);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
+        mBiometricsExecutor.runAllReady();
         event.recycle();
         event = obtainMotionEvent(ACTION_MOVE, displayWidth, displayHeight, touchMinor, touchMajor);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
+        mBiometricsExecutor.runAllReady();
         event.recycle();
         verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(expectedX),
                 eq(expectedY), eq(expectedMinor), eq(expectedMajor));
@@ -582,11 +600,13 @@
         verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
         MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
+        mBiometricsExecutor.runAllReady();
         downEvent.recycle();
         MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
 
         // FIX THIS TEST
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
+        mBiometricsExecutor.runAllReady();
         moveEvent.recycle();
         mFgExecutor.runAllReady();
         // THEN FingerprintManager is notified about onPointerDown
@@ -601,6 +621,7 @@
         verify(mKeyguardUpdateMonitor).onUdfpsPointerDown(eq((int) TEST_REQUEST_ID));
         // AND onIlluminatedRunnable notifies FingerprintManager about onUiReady
         mOnIlluminatedRunnableCaptor.getValue().run();
+        mBiometricsExecutor.runAllReady();
         InOrder inOrder = inOrder(mAlternateTouchProvider, mLatencyTracker);
         inOrder.verify(mAlternateTouchProvider).onUiReady();
         inOrder.verify(mLatencyTracker).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
@@ -621,6 +642,7 @@
         // AND onIlluminatedRunnable that notifies FingerprintManager is set
         verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture());
         mOnIlluminatedRunnableCaptor.getValue().run();
+        mBiometricsExecutor.runAllReady();
         verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID),
                 eq(0), eq(0), eq(3f) /* minor */, eq(2f) /* major */);
         verify(mFingerprintManager, never()).onPointerDown(anyLong(), anyInt(), anyInt(), anyInt(),
@@ -746,9 +768,11 @@
         verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
         MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
+        mBiometricsExecutor.runAllReady();
         downEvent.recycle();
         MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
+        mBiometricsExecutor.runAllReady();
         moveEvent.recycle();
 
         // THEN NO haptic played