From 5e70b5efb7094a78d05ecf7fb8f3bb0fdabc17f0 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Tue, 1 Jun 2021 15:49:43 -0700 Subject: Do not handle requests on system_server thread 1) Do not block system_server for sysui stuff 2) Access sysui variables from correct thread Bug: 187460696 Test: Manual Change-Id: I81f1dfc1122728dff37e8c7eccbf987bf1741435 --- .../systemui/biometrics/UdfpsController.java | 63 +++++++++++++--------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 5c360a649af0..5d2fef7a7a03 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -225,48 +225,61 @@ 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; - } + 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(); + mServerRequest = new ServerRequest(reason, callback, enrollHelper); + updateOverlay(); + }); } @Override public void hideUdfpsOverlay(int sensorId) { - mServerRequest = null; - updateOverlay(); + mFgExecutor.execute(() -> { + mServerRequest = null; + updateOverlay(); + }); } @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); + }); } } -- cgit v1.2.3-59-g8ed1b From f6ff170d53e68a5997070fdd90c7d5d6147c8376 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Tue, 1 Jun 2021 14:36:09 -0700 Subject: Turn off HBM when AcquiredInfo#GOOD Prevent unnecessary use of HBM. This change decouples illumination state from touch state. onFingerUp should always be called whenever the finger leaves the HBM area, and not only when illumination was requested (isFingerDown was actually isIlluminationRequested()). Moves the check to onFingerUp to stop illumination only if illumination was actually happening. Bug: 187460696 Test: atest UdfpsControllerTest Change-Id: I2eebe32990761d2fbf86cab228e4a7221a209b42 --- .../fingerprint/IUdfpsOverlayController.aidl | 4 +++ .../systemui/biometrics/UdfpsController.java | 39 +++++++++++++++------- .../systemui/biometrics/UdfpsControllerTest.java | 2 ++ .../sensors/fingerprint/UdfpsHelper.java | 13 ++++++++ .../aidl/FingerprintAuthenticationClient.java | 12 +++++++ .../fingerprint/aidl/FingerprintEnrollClient.java | 12 +++++-- 6 files changed, 67 insertions(+), 15 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 5d2fef7a7a03..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. @@ -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 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; @@ -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 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 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 -- cgit v1.2.3-59-g8ed1b