diff options
6 files changed, 102 insertions, 37 deletions
diff --git a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl index d2cb5bfe6910..f18360ff4108 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 5c360a649af0..3726ae132b64 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. @@ -225,48 +230,69 @@ public class UdfpsController implements DozeReceiver { @Override public void showUdfpsOverlay(int sensorId, int reason, @NonNull IUdfpsOverlayControllerCallback callback) { - final UdfpsEnrollHelper enrollHelper; - if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR - || reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING) { - enrollHelper = new UdfpsEnrollHelper(mContext, reason); - } else { - enrollHelper = null; - } - - mServerRequest = new ServerRequest(reason, callback, enrollHelper); - updateOverlay(); + mFgExecutor.execute(() -> { + final UdfpsEnrollHelper enrollHelper; + if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR + || reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING) { + enrollHelper = new UdfpsEnrollHelper(mContext, reason); + } else { + enrollHelper = null; + } + mServerRequest = new ServerRequest(reason, callback, enrollHelper); + updateOverlay(); + }); } @Override public void hideUdfpsOverlay(int sensorId) { - mServerRequest = null; - updateOverlay(); + mFgExecutor.execute(() -> { + mServerRequest = null; + updateOverlay(); + }); + } + + @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) { - if (mServerRequest == null) { - Log.e(TAG, "onEnrollProgress received but serverRequest is null"); - return; - } - mServerRequest.onEnrollmentProgress(remaining); + mFgExecutor.execute(() -> { + if (mServerRequest == null) { + Log.e(TAG, "onEnrollProgress received but serverRequest is null"); + return; + } + mServerRequest.onEnrollmentProgress(remaining); + }); } @Override public void onEnrollmentHelp(int sensorId) { - if (mServerRequest == null) { - Log.e(TAG, "onEnrollmentHelp received but serverRequest is null"); - return; - } - mServerRequest.onEnrollmentHelp(); + mFgExecutor.execute(() -> { + if (mServerRequest == null) { + Log.e(TAG, "onEnrollmentHelp received but serverRequest is null"); + return; + } + mServerRequest.onEnrollmentHelp(); + }); } @Override public void setDebugMessage(int sensorId, String message) { - if (mView == null) { - return; - } - mView.setDebugMessage(message); + mFgExecutor.execute(() -> { + if (mView == null) { + return; + } + mView.setDebugMessage(message); + }); } } @@ -333,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: @@ -388,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(); @@ -423,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(); } @@ -438,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; @@ -795,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 46c18480c77b..9322aa9b0ea8 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 f0e45978c365..879c8a0317d7 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 45842677609c..a5326b352264 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; @@ -81,6 +82,17 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> 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 ed886fe166e0..125cfd2e134d 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<ISession> 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 |