Split onPointerDown to onPointerDown and onUiReady

Previous behavior:
1. Detect a valid touch.
2. Enable HBM.
3. Notify the HAL about onPointerDown when HBM is enabled.

New behavior:
1. Detect a valid touch and report onPointerDown right away.
2. Enable HBM.
3. Notify the HAL about onUiReady when HBM is enabled.

Bug: 184361899
Test: atest UdfpsControllerTest
Test: on device
Change-Id: I48aa3945902a8ca151aabe61a5e71e910773bd88
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index cc1aeeb..b52955d 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -926,6 +926,23 @@
     }
 
     /**
+     * @hide
+     */
+    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+    public void onUiReady(int sensorId) {
+        if (mService == null) {
+            Slog.w(TAG, "onUiReady: no fingerprint service");
+            return;
+        }
+
+        try {
+            mService.onUiReady(sensorId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Determine if there is at least one fingerprint enrolled.
      *
      * @return true if at least one fingerprint is enrolled, false otherwise
@@ -1450,7 +1467,6 @@
         @Override // binder call
         public void onUdfpsPointerUp(int sensorId) {
             mHandler.obtainMessage(MSG_UDFPS_POINTER_UP, sensorId, 0).sendToTarget();
-
         }
     };
 
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 833747f..936f3d6 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -160,6 +160,9 @@
     // Notifies about a finger leaving the sensor area.
     void onPointerUp(int sensorId);
 
+    // Notifies about the fingerprint UI being ready (e.g. HBM illumination is enabled).
+    void onUiReady(int sensorId);
+
     // Sets the controller for managing the UDFPS overlay.
     void setUdfpsOverlayController(in IUdfpsOverlayController controller);
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 7ebfb72..fb62628 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -311,7 +311,7 @@
                 }
                 if (isWithinSensorArea(udfpsView, event.getX(), event.getY(), fromUdfpsView)) {
                     Trace.beginAsyncSection(
-                            "UdfpsController.mOnTouchListener#isWithinSensorArea", 1);
+                            "UdfpsController#ACTION_DOWN", 1);
                     // The pointer that causes ACTION_DOWN is always at index 0.
                     // We need to persist its ID to track it during ACTION_MOVE that could include
                     // data for many other pointers because of multi-touch support.
@@ -347,8 +347,6 @@
                                 minor, major, v, exceedsVelocityThreshold);
                         final long sinceLastLog = SystemClock.elapsedRealtime() - mTouchLogTime;
                         if (!isFingerDown && !exceedsVelocityThreshold) {
-                            Trace.endAsyncSection(
-                                    "UdfpsController.mOnTouchListener#isWithinSensorArea", 1);
                             onFingerDown((int) x, (int) y, minor, major);
                             Log.v(TAG, "onTouch | finger down: " + touchInfo);
                             mTouchLogTime = SystemClock.elapsedRealtime();
@@ -707,10 +705,13 @@
             Log.w(TAG, "Null view in onFingerDown");
             return;
         }
+        mFingerprintManager.onPointerDown(mSensorProps.sensorId, x, y, minor, major);
+        Trace.endAsyncSection(
+                "UdfpsController#ACTION_DOWN", 1);
         Trace.beginAsyncSection("UdfpsController#startIllumination", 1);
         mView.startIllumination(() -> {
+            mFingerprintManager.onUiReady(mSensorProps.sensorId);
             Trace.endAsyncSection("UdfpsController#startIllumination", 1);
-            mFingerprintManager.onPointerDown(mSensorProps.sensorId, x, y, minor, major);
         });
     }
 
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 725f0e6..c9b8f64 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -230,12 +230,14 @@
         MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
         moveEvent.recycle();
-        // THEN illumination begins
-        // AND onIlluminatedRunnable that notifies FingerprintManager is set
-        verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture());
-        mOnIlluminatedRunnableCaptor.getValue().run();
+        // THEN FingerprintManager is notified about onPointerDown
         verify(mFingerprintManager).onPointerDown(eq(mUdfpsController.mSensorProps.sensorId), eq(0),
                 eq(0), eq(0f), eq(0f));
+        // AND illumination begins
+        verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture());
+        // AND onIlluminatedRunnable notifies FingerprintManager about onUiReady
+        mOnIlluminatedRunnableCaptor.getValue().run();
+        verify(mFingerprintManager).onUiReady(eq(mUdfpsController.mSensorProps.sensorId));
     }
 
     @Test
diff --git a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java
index d82847c..62a9769 100644
--- a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java
+++ b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java
@@ -167,13 +167,13 @@
 
     // Fingerprint-specific callbacks for FingerprintManager only
 
-    public void onUdfpsPointerDown(int sensorId, int cookie) throws RemoteException {
+    public void onUdfpsPointerDown(int sensorId) throws RemoteException {
         if (mFingerprintServiceReceiver != null) {
             mFingerprintServiceReceiver.onUdfpsPointerDown(sensorId);
         }
     }
 
-    public void onUdfpsPointerUp(int sensorId, int cookie) throws RemoteException {
+    public void onUdfpsPointerUp(int sensorId) throws RemoteException {
         if (mFingerprintServiceReceiver != null) {
             mFingerprintServiceReceiver.onUdfpsPointerUp(sensorId);
         }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 39b7a74..e76362e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -925,6 +925,18 @@
         }
 
         @Override
+        public void onUiReady(int sensorId) {
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+
+            final ServiceProvider provider = getProviderForSensor(sensorId);
+            if (provider == null) {
+                Slog.w(TAG, "No matching provider for onUiReady, sensorId: " + sensorId);
+                return;
+            }
+            provider.onUiReady(sensorId);
+        }
+
+        @Override
         public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
index 701b9a7..4cbe031 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
@@ -140,6 +140,8 @@
 
     void onPointerUp(int sensorId);
 
+    void onUiReady(int sensorId);
+
     void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller);
 
     void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java
index 0aa112f..150e69c6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java
@@ -26,4 +26,5 @@
 public interface Udfps {
     void onPointerDown(int x, int y, float minor, float major);
     void onPointerUp();
+    void onUiReady();
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index 4e5d12d..4584267 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -120,7 +120,7 @@
         try {
             getFreshDaemon().onPointerDown(0 /* pointerId */, x, y, minor, major);
             if (getListener() != null) {
-                getListener().onUdfpsPointerDown(getSensorId(), getCookie());
+                getListener().onUdfpsPointerDown(getSensorId());
             }
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception", e);
@@ -132,7 +132,7 @@
         try {
             getFreshDaemon().onPointerUp(0 /* pointerId */);
             if (getListener() != null) {
-                getListener().onUdfpsPointerUp(getSensorId(), getCookie());
+                getListener().onUdfpsPointerUp(getSensorId());
             }
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception", e);
@@ -140,6 +140,15 @@
     }
 
     @Override
+    public void onUiReady() {
+        try {
+            getFreshDaemon().onUiReady();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Remote exception", e);
+        }
+    }
+
+    @Override
     public void onLockoutTimed(long durationMillis) {
         mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_TIMED);
         // Lockout metrics are logged as an error code.
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
index fd4aece..790b38c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
@@ -150,4 +150,13 @@
             Slog.e(TAG, "Unable to send pointer up", e);
         }
     }
+
+    @Override
+    public void onUiReady() {
+        try {
+            getFreshDaemon().onUiReady();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Unable to send UI ready", e);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index c23c113..b3dbd30 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -512,6 +512,18 @@
     }
 
     @Override
+    public void onUiReady(int sensorId) {
+        final BaseClientMonitor client =
+                mSensors.get(sensorId).getScheduler().getCurrentClient();
+        if (!(client instanceof Udfps)) {
+            Slog.e(getTag(), "onUiReady received during client: " + client);
+            return;
+        }
+        final Udfps udfps = (Udfps) client;
+        udfps.onUiReady();
+    }
+
+    @Override
     public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) {
         mUdfpsOverlayController = controller;
     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index 3528690..18730e9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -737,6 +737,17 @@
     }
 
     @Override
+    public void onUiReady(int sensorId) {
+        final BaseClientMonitor client = mScheduler.getCurrentClient();
+        if (!(client instanceof Udfps)) {
+            Slog.w(TAG, "onUiReady received during client: " + client);
+            return;
+        }
+        final Udfps udfps = (Udfps) client;
+        udfps.onUiReady();
+    }
+
+    @Override
     public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) {
         mUdfpsOverlayController = controller;
     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java
index 97f1287..24ed85c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java
@@ -152,7 +152,7 @@
         UdfpsHelper.onFingerDown(getFreshDaemon(), x, y, minor, major);
         if (getListener() != null) {
             try {
-                getListener().onUdfpsPointerDown(getSensorId(), getCookie());
+                getListener().onUdfpsPointerDown(getSensorId());
             } catch (RemoteException e) {
                 Slog.e(TAG, "Remote exception", e);
             }
@@ -164,10 +164,15 @@
         UdfpsHelper.onFingerUp(getFreshDaemon());
         if (getListener() != null) {
             try {
-                getListener().onUdfpsPointerUp(getSensorId(), getCookie());
+                getListener().onUdfpsPointerUp(getSensorId());
             } catch (RemoteException e) {
                 Slog.e(TAG, "Remote exception", e);
             }
         }
     }
+
+    @Override
+    public void onUiReady() {
+        // Unsupported in HIDL.
+    }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java
index db44aee..1607364 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java
@@ -108,6 +108,11 @@
     }
 
     @Override
+    public void onUiReady() {
+        // Unsupported in HIDL.
+    }
+
+    @Override
     public void onAuthenticated(BiometricAuthenticator.Identifier identifier, boolean authenticated,
             ArrayList<Byte> hardwareAuthToken) {
         logOnAuthenticated(getContext(), authenticated, false /* requireConfirmation */,
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java
index 41d2308..4265f40 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java
@@ -146,4 +146,9 @@
     public void onPointerUp() {
         UdfpsHelper.onFingerUp(getFreshDaemon());
     }
+
+    @Override
+    public void onUiReady() {
+        // Unsupported in HIDL.
+    }
 }