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

Commit eaa86690 authored by Ilya Matyukhin's avatar Ilya Matyukhin
Browse files

Refactor the HBM layer and add completion callbacks

Bug: 187081118
Test: atest UdfpsControllerTest
Change-Id: Ief24c426baa2acd34719581fed0a5ef112cb7d64
parent e5c0addd
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ public class UdfpsController implements DozeReceiver {
    @NonNull private final FalsingManager mFalsingManager;
    @NonNull private final PowerManager mPowerManager;
    @NonNull private final AccessibilityManager mAccessibilityManager;
    @Nullable private final UdfpsHbmCallback mHbmCallback;
    @Nullable private final UdfpsHbmProvider mHbmProvider;
    // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
    // sensors, this, in addition to a lot of the code here, will be updated.
    @VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps;
@@ -494,7 +494,7 @@ public class UdfpsController implements DozeReceiver {
            @NonNull AccessibilityManager accessibilityManager,
            @NonNull ScreenLifecycle screenLifecycle,
            @Nullable Vibrator vibrator,
            @NonNull Optional<UdfpsHbmCallback> hbmCallback) {
            @NonNull Optional<UdfpsHbmProvider> hbmProvider) {
        mContext = context;
        // TODO (b/185124905): inject main handler and vibrator once done prototyping
        mMainHandler = new Handler(Looper.getMainLooper());
@@ -514,7 +514,7 @@ public class UdfpsController implements DozeReceiver {
        mFalsingManager = falsingManager;
        mPowerManager = powerManager;
        mAccessibilityManager = accessibilityManager;
        mHbmCallback = hbmCallback.orElse(null);
        mHbmProvider = hbmProvider.orElse(null);
        screenLifecycle.addObserver(mScreenObserver);
        mScreenOn = screenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON;

@@ -649,7 +649,7 @@ public class UdfpsController implements DozeReceiver {
                    Log.v(TAG, "showUdfpsOverlay | adding window reason=" + reason);
                    mView = (UdfpsView) mInflater.inflate(R.layout.udfps_view, null, false);
                    mView.setSensorProperties(mSensorProps);
                    mView.setHbmCallback(mHbmCallback);
                    mView.setHbmProvider(mHbmProvider);
                    UdfpsAnimationViewController animation = inflateUdfpsAnimation(reason);
                    animation.init();
                    mView.setAnimationViewController(animation);
+14 −3
Original line number Diff line number Diff line
@@ -26,22 +26,33 @@ import com.android.systemui.biometrics.UdfpsHbmTypes.HbmType;
 * enable the HBM while showing the fingerprint illumination, and to disable the HBM after the
 * illumination is no longer necessary.
 */
public interface UdfpsHbmCallback {
public interface UdfpsHbmProvider {

    /**
     * UdfpsView will call this to enable the HBM when the fingerprint illumination is needed.
     *
     * The call must be made from the UI thread. The callback, if provided, will also be invoked
     * from the UI thread.
     *
     * @param hbmType The type of HBM that should be enabled. See {@link UdfpsHbmTypes}.
     * @param surface The surface for which the HBM is requested, in case the HBM implementation
     *                needs to set special surface flags to enable the HBM. Can be null.
     * @param onHbmEnabled A runnable that will be executed once HBM is enabled.
     */
    void enableHbm(@HbmType int hbmType, @Nullable Surface surface);
    void enableHbm(@HbmType int hbmType, @Nullable Surface surface,
            @Nullable Runnable onHbmEnabled);

    /**
     * UdfpsView will call this to disable the HBM when the illumination is not longer needed.
     *
     * The call must be made from the UI thread. The callback, if provided, will also be invoked
     * from the UI thread.
     *
     * @param hbmType The type of HBM that should be disabled. See {@link UdfpsHbmTypes}.
     * @param surface The surface for which the HBM is requested, in case the HBM implementation
     *                needs to unset special surface flags to disable the HBM. Can be null.
     * @param onHbmDisabled A runnable that will be executed once HBM is disabled.
     */
    void disableHbm(@HbmType int hbmType, @Nullable Surface surface);
    void disableHbm(@HbmType int hbmType, @Nullable Surface surface,
            @Nullable Runnable onHbmDisabled);
}
+2 −2
Original line number Diff line number Diff line
@@ -24,9 +24,9 @@ import android.annotation.Nullable;
 */
interface UdfpsIlluminator {
    /**
     * @param callback Invoked when HBM should be enabled or disabled.
     * @param hbmProvider Invoked when HBM should be enabled or disabled.
     */
    void setHbmCallback(@Nullable UdfpsHbmCallback callback);
    void setHbmProvider(@Nullable UdfpsHbmProvider hbmProvider);

    /**
     * Invoked when illumination should start.
+28 −22
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

@@ -57,7 +58,7 @@ public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator {
    private final @HbmType int mHbmType;

    @NonNull private RectF mSensorRect;
    @Nullable private UdfpsHbmCallback mHbmCallback;
    @Nullable private UdfpsHbmProvider mHbmProvider;

    public UdfpsSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
@@ -90,39 +91,44 @@ public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator {
    }

    @Override
    public void setHbmCallback(@Nullable UdfpsHbmCallback callback) {
        mHbmCallback = callback;
    public void setHbmProvider(@Nullable UdfpsHbmProvider hbmProvider) {
        mHbmProvider = hbmProvider;
    }

    @Override
    public void startIllumination(@Nullable Runnable onIlluminatedRunnable) {
        if (mHbmCallback != null) {
            mHbmCallback.enableHbm(mHbmType, mHolder.getSurface());
        } else {
            Log.e(TAG, "startIllumination | mHbmCallback is null");
        }
        if (mHbmProvider != null) {
            final Surface surface =
                    (mHbmType == UdfpsHbmTypes.GLOBAL_HBM) ? mHolder.getSurface() : null;

            final Runnable onHbmEnabled = () -> {
                if (mHbmType == UdfpsHbmTypes.GLOBAL_HBM) {
                    drawImmediately(mIlluminationDotDrawable);
                }

                if (onIlluminatedRunnable != null) {
            // No framework API can reliably tell when a frame reaches the panel. A timeout is the
            // safest solution. The frame should be displayed within 3 refresh cycles, which on a
            // 60 Hz panel equates to 50 milliseconds.
                    // No framework API can reliably tell when a frame reaches the panel. A timeout
                    // is the safest solution. The frame should be displayed within 3 refresh
                    // cycles, which on a 60 Hz panel equates to 50 milliseconds.
                    postDelayed(onIlluminatedRunnable, 50 /* delayMillis */);
                } else {
                    Log.w(TAG, "startIllumination | onIlluminatedRunnable is null");
                }
            };

            mHbmProvider.enableHbm(mHbmType, surface, onHbmEnabled);
        } else {
            Log.e(TAG, "startIllumination | mHbmProvider is null");
        }
    }

    @Override
    public void stopIllumination() {
        if (mHbmCallback != null) {
            mHbmCallback.disableHbm(mHbmType, mHolder.getSurface());
        if (mHbmProvider != null) {
            final Runnable onHbmDisabled = this::invalidate;
            mHbmProvider.disableHbm(mHbmType, mHolder.getSurface(), onHbmDisabled);
        } else {
            Log.e(TAG, "stopIllumination | mHbmCallback is null");
            Log.e(TAG, "stopIllumination | mHbmProvider is null");
        }

        invalidate();
    }

    void onSensorRectUpdated(@NonNull RectF sensorRect) {
+2 −2
Original line number Diff line number Diff line
@@ -101,8 +101,8 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin
    }

    @Override
    public void setHbmCallback(@Nullable UdfpsHbmCallback callback) {
        mHbmSurfaceView.setHbmCallback(callback);
    public void setHbmProvider(@Nullable UdfpsHbmProvider hbmProvider) {
        mHbmSurfaceView.setHbmProvider(hbmProvider);
    }

    @Override
Loading