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

Commit 0aedb5a5 authored by Ilya Matyukhin's avatar Ilya Matyukhin
Browse files

Implement LHBM/GHBM switch

Bug: 182520014
Test: on device
Test: adb shell settings put secure com.android.systemui.biometrics.UdfpsSurfaceView.hbmType 1
Change-Id: I7274fac1ba54d0b577ea63ae4ea3f175afff3a01
parent 24923769
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -16,9 +16,11 @@

package com.android.systemui.biometrics;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.view.Surface;

import com.android.systemui.biometrics.HbmTypes.HbmType;

/**
 * Interface for controlling the high-brightness mode (HBM). UdfpsView can use this callback to
 * enable the HBM while showing the fingerprint illumination, and to disable the HBM after the
@@ -26,16 +28,20 @@ import android.view.Surface;
 */
public interface HbmCallback {
    /**
     * UdfpsView will call this to enable the HBM before drawing the illumination dot.
     * UdfpsView will call this to enable the HBM when the fingerprint illumination is needed.
     *
     * @param surface A valid surface for which the HBM should be enabled.
     * @param hbmType The type of HBM that should be enabled. See {@link HbmTypes}.
     * @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.
     */
    void enableHbm(@NonNull Surface surface);
    void enableHbm(@HbmType int hbmType, @Nullable Surface surface);

    /**
     * UdfpsView will call this to disable the HBM when the illumination is not longer needed.
     *
     * @param surface A valid surface for which the HBM should be disabled.
     * @param hbmType The type of HBM that should be disabled. See {@link HbmTypes}.
     * @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.
     */
    void disableHbm(@NonNull Surface surface);
    void disableHbm(@HbmType int hbmType, @Nullable Surface surface);
}
+38 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.biometrics;

import android.annotation.IntDef;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Different high-brightness mode (HBM) types that are relevant to this package.
 */
public final class HbmTypes {
    /** HBM that applies to the whole screen. */
    public static final int GLOBAL_HBM = 0;

    /** HBM that only applies to a portion of the screen. */
    public static final int LOCAL_HBM = 1;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({GLOBAL_HBM, LOCAL_HBM})
    public @interface HbmType {
    }
}
+6 −6
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.systemui.biometrics;
import static com.android.internal.util.Preconditions.checkArgument;
import static com.android.internal.util.Preconditions.checkNotNull;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -42,11 +44,9 @@ import android.view.Surface;
import android.view.VelocityTracker;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
import com.android.systemui.biometrics.HbmTypes.HbmType;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeReceiver;
@@ -95,7 +95,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
    // Tracks the velocity of a touch to help filter out the touches that move too fast.
    @Nullable private VelocityTracker mVelocityTracker;
    // The ID of the pointer for which ACTION_DOWN has occurred. -1 means no pointer is active.
    private int mActivePointerId;
    private int mActivePointerId = -1;
    // The timestamp of the most recent touch log.
    private long mTouchLogTime;

@@ -580,13 +580,13 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
    }

    @Override
    public void enableHbm(@NonNull Surface surface) {
    public void enableHbm(@HbmType int hbmType, @Nullable Surface surface) {
        // Do nothing. This method can be implemented for devices that require the high-brightness
        // mode for fingerprint illumination.
    }

    @Override
    public void disableHbm(@NonNull Surface surface) {
    public void disableHbm(@HbmType int hbmType, @Nullable Surface surface) {
        // Do nothing. This method can be implemented for devices that require the high-brightness
        // mode for fingerprint illumination.
    }
+29 −5
Original line number Diff line number Diff line
@@ -23,16 +23,25 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.os.Build;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.android.systemui.biometrics.HbmTypes.HbmType;

/**
 * Under-display fingerprint sensor Surface View. The surface should be used for HBM-specific things
 * only. All other animations should be done on the other view.
 */
public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator {
    private static final String TAG = "UdfpsSurfaceView";
    private static final String SETTING_HBM_TYPE =
            "com.android.systemui.biometrics.UdfpsSurfaceView.hbmType";
    private static final @HbmType int DEFAULT_HBM_TYPE = HbmTypes.GLOBAL_HBM;

    /**
     * This is used instead of {@link android.graphics.drawable.Drawable}, because the latter has
@@ -45,6 +54,7 @@ public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator {
    @NonNull private final SurfaceHolder mHolder;
    @NonNull private final Paint mSensorPaint;
    @NonNull private final SimpleDrawable mIlluminationDotDrawable;
    private final @HbmType int mHbmType;

    @NonNull private RectF mSensorRect;
    @Nullable private HbmCallback mHbmCallback;
@@ -70,6 +80,13 @@ public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator {
        mIlluminationDotDrawable = canvas -> {
            canvas.drawOval(mSensorRect, mSensorPaint);
        };

        if (Build.IS_ENG || Build.IS_USERDEBUG) {
            mHbmType = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                    SETTING_HBM_TYPE, DEFAULT_HBM_TYPE, UserHandle.USER_CURRENT);
        } else {
            mHbmType = DEFAULT_HBM_TYPE;
        }
    }

    @Override
@@ -79,10 +96,15 @@ public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator {

    @Override
    public void startIllumination(@Nullable Runnable onIlluminatedRunnable) {
        if (mHbmCallback != null && mHolder.getSurface().isValid()) {
            mHbmCallback.enableHbm(mHolder.getSurface());
        if (mHbmCallback != null) {
            mHbmCallback.enableHbm(mHbmType, mHolder.getSurface());
        } else {
            Log.e(TAG, "startIllumination | mHbmCallback is null");
        }

        if (mHbmType == HbmTypes.GLOBAL_HBM) {
            drawImmediately(mIlluminationDotDrawable);
        }

        if (onIlluminatedRunnable != null) {
            // No framework API can reliably tell when a frame reaches the panel. A timeout is the
@@ -94,8 +116,10 @@ public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator {

    @Override
    public void stopIllumination() {
        if (mHbmCallback != null && mHolder.getSurface().isValid()) {
            mHbmCallback.disableHbm(mHolder.getSurface());
        if (mHbmCallback != null) {
            mHbmCallback.disableHbm(mHbmType, mHolder.getSurface());
        } else {
            Log.e(TAG, "stopIllumination | mHbmCallback is null");
        }

        invalidate();