Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f6ff170d authored by Kevin Chyn's avatar Kevin Chyn
Browse files

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
parent 5e70b5ef
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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);

+27 −12
Original line number Diff line number Diff line
@@ -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();
                }
                mFalsingManager.isFalseTouch(UDFPS_AUTHENTICATION);

                break;
@@ -808,14 +820,17 @@ 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);
        if (mView.isIlluminationRequested()) {
            mView.stopIllumination();
        }
    }


    private VibrationEffect getVibration(String effect, VibrationEffect defaultEffect) {
+2 −0
Original line number Diff line number Diff line
@@ -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();
+13 −0
Original line number Diff line number Diff line
@@ -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) {
+12 −0
Original line number Diff line number Diff line
@@ -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<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);
Loading