diff --git a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl index d2cb5bfe6910f..f18360ff41087 100644 --- a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl +++ b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl @@ -35,6 +35,10 @@ oneway interface IUdfpsOverlayController { // Hides the overlay. void hideUdfpsOverlay(int sensorId); + // Good image captured. Turn off HBM. Success/Reject comes after, which is when hideUdfpsOverlay + // will be called. + void onAcquiredGood(int sensorId); + // Notifies of enrollment progress changes. void onEnrollmentProgress(int sensorId, int remaining); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 5d2fef7a7a035..3726ae132b648 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -123,6 +123,11 @@ public class UdfpsController implements DozeReceiver { private int mActivePointerId = -1; // The timestamp of the most recent touch log. private long mTouchLogTime; + // Sensor has a good capture for this touch. Do not need to illuminate for this particular + // touch event anymore. In other words, do not illuminate until user lifts and touches the + // sensor area again. + // TODO: We should probably try to make touch/illumination things more of a FSM + private boolean mGoodCaptureReceived; @Nullable private UdfpsView mView; // The current request from FingerprintService. Null if no current request. @@ -233,7 +238,6 @@ public class UdfpsController implements DozeReceiver { } else { enrollHelper = null; } - mServerRequest = new ServerRequest(reason, callback, enrollHelper); updateOverlay(); }); @@ -247,6 +251,18 @@ public class UdfpsController implements DozeReceiver { }); } + @Override + public void onAcquiredGood(int sensorId) { + mFgExecutor.execute(() -> { + if (mView == null) { + Log.e(TAG, "Null view when onAcquiredGood for sensorId: " + sensorId); + return; + } + mGoodCaptureReceived = true; + mView.stopIllumination(); + }); + } + @Override public void onEnrollmentProgress(int sensorId, int remaining) { mFgExecutor.execute(() -> { @@ -254,7 +270,6 @@ public class UdfpsController implements DozeReceiver { Log.e(TAG, "onEnrollProgress received but serverRequest is null"); return; } - mServerRequest.onEnrollmentProgress(remaining); }); } @@ -266,7 +281,6 @@ public class UdfpsController implements DozeReceiver { Log.e(TAG, "onEnrollmentHelp received but serverRequest is null"); return; } - mServerRequest.onEnrollmentHelp(); }); } @@ -277,7 +291,6 @@ public class UdfpsController implements DozeReceiver { if (mView == null) { return; } - mView.setDebugMessage(message); }); } @@ -346,7 +359,7 @@ public class UdfpsController implements DozeReceiver { private boolean onTouch(View view, MotionEvent event, boolean fromUdfpsView) { UdfpsView udfpsView = (UdfpsView) view; - final boolean isFingerDown = udfpsView.isIlluminationRequested(); + final boolean isIlluminationRequested = udfpsView.isIlluminationRequested(); boolean handled = false; switch (event.getActionMasked()) { case MotionEvent.ACTION_OUTSIDE: @@ -401,7 +414,8 @@ public class UdfpsController implements DozeReceiver { "minor: %.1f, major: %.1f, v: %.1f, exceedsVelocityThreshold: %b", minor, major, v, exceedsVelocityThreshold); final long sinceLastLog = SystemClock.elapsedRealtime() - mTouchLogTime; - if (!isFingerDown && !exceedsVelocityThreshold) { + if (!isIlluminationRequested && !mGoodCaptureReceived && + !exceedsVelocityThreshold) { onFingerDown((int) x, (int) y, minor, major); Log.v(TAG, "onTouch | finger down: " + touchInfo); mTouchLogTime = SystemClock.elapsedRealtime(); @@ -436,7 +450,7 @@ public class UdfpsController implements DozeReceiver { Log.v(TAG, "onTouch | finger move: " + touchInfo); mTouchLogTime = SystemClock.elapsedRealtime(); } - } else if (isFingerDown) { + } else { Log.v(TAG, "onTouch | finger outside"); onFingerUp(); } @@ -451,10 +465,8 @@ public class UdfpsController implements DozeReceiver { mVelocityTracker.recycle(); mVelocityTracker = null; } - if (isFingerDown) { - Log.v(TAG, "onTouch | finger up"); - onFingerUp(); - } + Log.v(TAG, "onTouch | finger up"); + onFingerUp(); mFalsingManager.isFalseTouch(UDFPS_AUTHENTICATION); break; @@ -808,13 +820,16 @@ public class UdfpsController implements DozeReceiver { // This method can be called from the UI thread. private void onFingerUp() { mActivePointerId = -1; + mGoodCaptureReceived = false; mMainHandler.removeCallbacks(mAcquiredVibration); if (mView == null) { Log.w(TAG, "Null view in onFingerUp"); return; } mFingerprintManager.onPointerUp(mSensorProps.sensorId); - mView.stopIllumination(); + if (mView.isIlluminationRequested()) { + mView.stopIllumination(); + } } 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 46c18480c77b8..9322aa9b0ea83 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -275,6 +275,7 @@ public class UdfpsControllerTest extends SysuiTestCase { mScreenObserver.onScreenTurnedOn(); mFgExecutor.runAllReady(); mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); + when(mUdfpsView.isIlluminationRequested()).thenReturn(true); // WHEN it is cancelled mUdfpsController.onCancelUdfps(); // THEN the illumination is hidden @@ -289,6 +290,7 @@ public class UdfpsControllerTest extends SysuiTestCase { mScreenObserver.onScreenTurnedOn(); mFgExecutor.runAllReady(); mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); + when(mUdfpsView.isIlluminationRequested()).thenReturn(true); // WHEN it times out mFgExecutor.advanceClockToNext(); mFgExecutor.runAllReady(); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java index f0e45978c365d..879c8a0317d74 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java @@ -113,6 +113,19 @@ public class UdfpsHelper { } } + public static void onAcquiredGood(int sensorId, + @Nullable IUdfpsOverlayController udfpsOverlayController) { + if (udfpsOverlayController == null) { + return; + } + + try { + udfpsOverlayController.onAcquiredGood(sensorId); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception when sending onAcquiredGood", e); + } + } + public static void onEnrollmentProgress(int sensorId, int remaining, @Nullable IUdfpsOverlayController udfpsOverlayController) { if (udfpsOverlayController == null) { 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 45842677609cf..a5326b352264f 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 @@ -22,6 +22,7 @@ import android.app.TaskStackListener; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricFingerprintConstants; +import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.common.ICancellationSignal; import android.hardware.biometrics.fingerprint.ISession; @@ -80,6 +81,17 @@ class FingerprintAuthenticationClient extends AuthenticationClient imp } } + @Override + public void onAcquired(@FingerprintAcquired int acquiredInfo, int vendorCode) { + // For UDFPS, notify SysUI that the illumination can be turned off. + // See AcquiredInfo#GOOD and AcquiredInfo#RETRYING_CAPTURE + if (acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) { + UdfpsHelper.onAcquiredGood(getSensorId(), mUdfpsOverlayController); + } + + super.onAcquired(acquiredInfo, vendorCode); + } + @Override public void onError(int errorCode, int vendorCode) { super.onError(errorCode, vendorCode); 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 ed886fe166e0d..125cfd2e134df 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 @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricFingerprintConstants; +import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.common.ICancellationSignal; import android.hardware.biometrics.fingerprint.ISession; @@ -85,14 +86,19 @@ class FingerprintEnrollClient extends EnrollClient implements Udfps { } } - @Override - public void onAcquired(int acquiredInfo, int vendorCode) { - super.onAcquired(acquiredInfo, vendorCode); + public void onAcquired(@FingerprintAcquired int acquiredInfo, int vendorCode) { + // For UDFPS, notify SysUI that the illumination can be turned off. + // See AcquiredInfo#GOOD and AcquiredInfo#RETRYING_CAPTURE + if (acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) { + UdfpsHelper.onAcquiredGood(getSensorId(), mUdfpsOverlayController); + } if (UdfpsHelper.isValidAcquisitionMessage(getContext(), acquiredInfo, vendorCode)) { UdfpsHelper.onEnrollmentHelp(getSensorId(), mUdfpsOverlayController); } + + super.onAcquired(acquiredInfo, vendorCode); } @Override