diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index cc1aeeb92685a..b52955d035b50 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -925,6 +925,23 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing } } + /** + * @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. * @@ -1450,7 +1467,6 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing @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 833747f19a0c0..936f3d6b2788d 100644 --- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl +++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl @@ -160,6 +160,9 @@ interface IFingerprintService { // 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 e243e1e76c54b..5f27400741a95 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -345,7 +345,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback { } 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. @@ -382,8 +382,6 @@ public class UdfpsController implements DozeReceiver, HbmCallback { 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(); @@ -761,10 +759,13 @@ public class UdfpsController implements DozeReceiver, HbmCallback { 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 aed49a84ca4d6..875696a08cf1e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -232,12 +232,14 @@ public class UdfpsControllerTest extends SysuiTestCase { 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 d82847c95dce0..62a9769aee1a4 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 @@ public class ClientMonitorCallbackConverter { // 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 ce06d06afe4e0..6382950711ce2 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 @@ -924,6 +924,18 @@ public class FingerprintService extends SystemService { provider.onPointerUp(sensorId); } + @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 701b9a739e33e..4cbe031d01419 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 @@ public interface ServiceProvider { 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 0aa112f106c40..150e69c60974a 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 @@ import com.android.server.biometrics.sensors.BaseClientMonitor; 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 4e5d12d2021ce..45842677609cf 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 @@ class FingerprintAuthenticationClient extends AuthenticationClient imp 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,13 +132,22 @@ class FingerprintAuthenticationClient extends AuthenticationClient imp try { getFreshDaemon().onPointerUp(0 /* pointerId */); if (getListener() != null) { - getListener().onUdfpsPointerUp(getSensorId(), getCookie()); + getListener().onUdfpsPointerUp(getSensorId()); } } catch (RemoteException e) { Slog.e(TAG, "Remote exception", e); } } + @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); 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 fd4aece339f33..790b38c07bf53 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 @@ class FingerprintEnrollClient extends EnrollClient implements Udfps { 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 388bd0a1dc407..20d6ee24d3279 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 @@ -513,6 +513,18 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi udfps.onPointerUp(); } + @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 f0ea90dcbc338..2746520966247 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 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider udfps.onPointerUp(); } + @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 97f128748bcc0..24ed85c42e4ef 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 @@ class FingerprintAuthenticationClient extends AuthenticationClient UdfpsHelper.onFingerUp(getFreshDaemon()); } + @Override + public void onUiReady() { + // Unsupported in HIDL. + } + @Override public void onAuthenticated(BiometricAuthenticator.Identifier identifier, boolean authenticated, ArrayList hardwareAuthToken) { 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 41d23089a5309..4265f4082ff40 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 class FingerprintEnrollClient extends EnrollClient