Remove all GHBM logic

Removing GHBM logic from codebase since it has been replaced by LHBM.
This will simplify the current implementation, and assist with future
refactors and the transition to Kotlin.

Fixes: 227229729
Test: atest UdfpsViewTest
Test: atest DisplayModeDirectorTest
Change-Id: I0d1e7ffb610154f4d56afab8385883a0389f89db
This commit is contained in:
Grace Cheng
2022-03-29 22:28:08 +00:00
parent b07646b6e3
commit c532376c60
9 changed files with 21 additions and 307 deletions

View File

@@ -24,31 +24,20 @@ package android.hardware.fingerprint;
* @hide
*/
oneway interface IUdfpsHbmListener {
/** HBM that applies to the whole screen. */
const int GLOBAL_HBM = 0;
/** HBM that only applies to a portion of the screen. */
const int LOCAL_HBM = 1;
/**
* UdfpsController will call this method when the HBM is enabled.
*
* @param hbmType The type of HBM that was enabled. See
* {@link com.android.systemui.biometrics.UdfpsHbmTypes}.
* @param displayId The displayId for which the HBM is enabled. See
* {@link android.view.Display#getDisplayId()}.
*/
void onHbmEnabled(int hbmType, int displayId);
void onHbmEnabled(int displayId);
/**
* UdfpsController will call this method when the HBM is disabled.
*
* @param hbmType The type of HBM that was disabled. See
* {@link com.android.systemui.biometrics.UdfpsHbmTypes}.
* @param displayId The displayId for which the HBM is disabled. See
* {@link android.view.Display#getDisplayId()}.
*/
void onHbmDisabled(int hbmType, int displayId);
void onHbmDisabled(int displayId);
}

View File

@@ -28,10 +28,4 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.android.systemui.biometrics.UdfpsSurfaceView
android:id="@+id/hbm_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible"/>
</com.android.systemui.biometrics.UdfpsView>

View File

@@ -17,9 +17,6 @@
package com.android.systemui.biometrics;
import android.annotation.Nullable;
import android.view.Surface;
import com.android.systemui.biometrics.UdfpsHbmTypes.HbmType;
/**
* Interface for controlling the high-brightness mode (HBM). UdfpsView can use this callback to
@@ -36,24 +33,21 @@ public interface UdfpsHbmProvider {
* This method must be called 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,
@Nullable Runnable onHbmEnabled);
void enableHbm(@Nullable Runnable onHbmEnabled);
/**
* UdfpsView will call this to disable the HBM when the illumination is not longer needed.
* UdfpsView will call this to disable HBM when illumination is no longer needed.
*
* This method is a no-op when HBM is already disabled. If HBM is enabled, this method will
* disable HBM for the {@code hbmType} and {@code surface} that were provided to the
* corresponding {@link #enableHbm(int, Surface, Runnable)}.
* This method will disable HBM if HBM is enabled. Otherwise, if HBM is already disabled,
* this method is a no-op.
*
* The call must be made from the UI thread. The callback, if provided, will also be invoked
* from the UI thread.
*
*
*
* @param onHbmDisabled A runnable that will be executed once HBM is disabled.
*/
void disableHbm(@Nullable Runnable onHbmDisabled);

View File

@@ -1,39 +0,0 @@
/*
* 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 android.hardware.fingerprint.IUdfpsHbmListener;
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 UdfpsHbmTypes {
/** HBM that applies to the whole screen. */
public static final int GLOBAL_HBM = IUdfpsHbmListener.GLOBAL_HBM;
/** HBM that only applies to a portion of the screen. */
public static final int LOCAL_HBM = IUdfpsHbmListener.LOCAL_HBM;
@Retention(RetentionPolicy.SOURCE)
@IntDef({GLOBAL_HBM, LOCAL_HBM})
public @interface HbmType {
}
}

View File

@@ -1,145 +0,0 @@
/*
* 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.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/**
* Surface View for providing the Global High-Brightness Mode (GHBM) illumination for UDFPS.
*/
public class UdfpsSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "UdfpsSurfaceView";
/**
* Notifies {@link UdfpsView} when to enable GHBM illumination.
*/
interface GhbmIlluminationListener {
/**
* @param surface the surface for which GHBM should be enabled.
* @param onIlluminatedRunnable a runnable that should be run after GHBM is enabled.
*/
void enableGhbm(@NonNull Surface surface, @Nullable Runnable onIlluminatedRunnable);
}
@NonNull private final SurfaceHolder mHolder;
@NonNull private final Paint mSensorPaint;
@Nullable private GhbmIlluminationListener mGhbmIlluminationListener;
@Nullable private Runnable mOnIlluminatedRunnable;
boolean mAwaitingSurfaceToStartIllumination;
boolean mHasValidSurface;
public UdfpsSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
// Make this SurfaceView draw on top of everything else in this window. This allows us to
// 1) Always show the HBM circle on top of everything else, and
// 2) Properly composite this view with any other animations in the same window no matter
// what contents are added in which order to this view hierarchy.
setZOrderOnTop(true);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setFormat(PixelFormat.RGBA_8888);
mSensorPaint = new Paint(0 /* flags */);
mSensorPaint.setAntiAlias(true);
mSensorPaint.setARGB(255, 255, 255, 255);
mSensorPaint.setStyle(Paint.Style.FILL);
}
@Override public void surfaceCreated(SurfaceHolder holder) {
mHasValidSurface = true;
if (mAwaitingSurfaceToStartIllumination) {
doIlluminate(mOnIlluminatedRunnable);
mOnIlluminatedRunnable = null;
mAwaitingSurfaceToStartIllumination = false;
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// Unused.
}
@Override public void surfaceDestroyed(SurfaceHolder holder) {
mHasValidSurface = false;
}
void setGhbmIlluminationListener(@Nullable GhbmIlluminationListener listener) {
mGhbmIlluminationListener = listener;
}
/**
* Note: there is no corresponding method to stop GHBM illumination. It is expected that
* {@link UdfpsView} will hide this view, which would destroy the surface and remove the
* illumination dot.
*/
void startGhbmIllumination(@Nullable Runnable onIlluminatedRunnable) {
if (mGhbmIlluminationListener == null) {
Log.e(TAG, "startIllumination | mGhbmIlluminationListener is null");
return;
}
if (mHasValidSurface) {
doIlluminate(onIlluminatedRunnable);
} else {
mAwaitingSurfaceToStartIllumination = true;
mOnIlluminatedRunnable = onIlluminatedRunnable;
}
}
private void doIlluminate(@Nullable Runnable onIlluminatedRunnable) {
if (mGhbmIlluminationListener == null) {
Log.e(TAG, "doIlluminate | mGhbmIlluminationListener is null");
return;
}
mGhbmIlluminationListener.enableGhbm(mHolder.getSurface(), onIlluminatedRunnable);
}
/**
* Immediately draws the illumination dot on this SurfaceView's surface.
*/
void drawIlluminationDot(@NonNull RectF sensorRect) {
if (!mHasValidSurface) {
Log.e(TAG, "drawIlluminationDot | the surface is destroyed or was never created.");
return;
}
Canvas canvas = null;
try {
canvas = mHolder.lockCanvas();
canvas.drawOval(sensorRect, mSensorPaint);
} finally {
// Make sure the surface is never left in a bad state.
if (canvas != null) {
mHolder.unlockCanvasAndPost(canvas);
}
}
}
}

View File

@@ -22,26 +22,17 @@ import android.graphics.Paint
import android.graphics.PointF
import android.graphics.RectF
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
import android.os.Build
import android.os.UserHandle
import android.provider.Settings
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.Surface
import android.widget.FrameLayout
import com.android.systemui.R
import com.android.systemui.doze.DozeReceiver
import com.android.systemui.biometrics.UdfpsHbmTypes.HbmType
private const val TAG = "UdfpsView"
private const val SETTING_HBM_TYPE = "com.android.systemui.biometrics.UdfpsSurfaceView.hbmType"
@HbmType
private const val DEFAULT_HBM_TYPE = UdfpsHbmTypes.LOCAL_HBM
/**
* A view containing 1) A SurfaceView for HBM, and 2) A normal drawable view for all other
* animations.
* The main view group containing all UDFPS animations.
*/
class UdfpsView(
context: Context,
@@ -68,21 +59,6 @@ class UdfpsView(
com.android.internal.R.integer.config_udfps_illumination_transition_ms
).toLong()
@HbmType
private val hbmType = if (Build.IS_ENG || Build.IS_USERDEBUG) {
Settings.Secure.getIntForUser(
context.contentResolver,
SETTING_HBM_TYPE,
DEFAULT_HBM_TYPE,
UserHandle.USER_CURRENT
)
} else {
DEFAULT_HBM_TYPE
}
// Only used for UdfpsHbmTypes.GLOBAL_HBM.
private var ghbmView: UdfpsSurfaceView? = null
/** View controller (can be different for enrollment, BiometricPrompt, Keyguard, etc.). */
var animationViewController: UdfpsAnimationViewController<*>? = null
@@ -109,12 +85,6 @@ class UdfpsView(
return (animationViewController == null || !animationViewController!!.shouldPauseAuth())
}
override fun onFinishInflate() {
if (hbmType == UdfpsHbmTypes.GLOBAL_HBM) {
ghbmView = findViewById(R.id.hbm_view)
}
}
override fun dozeTimeTick() {
animationViewController?.dozeTimeTick()
}
@@ -180,24 +150,11 @@ class UdfpsView(
override fun startIllumination(onIlluminatedRunnable: Runnable?) {
isIlluminationRequested = true
animationViewController?.onIlluminationStarting()
val gView = ghbmView
if (gView != null) {
gView.setGhbmIlluminationListener(this::doIlluminate)
gView.visibility = VISIBLE
gView.startGhbmIllumination(onIlluminatedRunnable)
} else {
doIlluminate(null /* surface */, onIlluminatedRunnable)
}
doIlluminate(onIlluminatedRunnable)
}
private fun doIlluminate(surface: Surface?, onIlluminatedRunnable: Runnable?) {
if (ghbmView != null && surface == null) {
Log.e(TAG, "doIlluminate | surface must be non-null for GHBM")
}
hbmProvider?.enableHbm(hbmType, surface) {
ghbmView?.drawIlluminationDot(sensorRect)
private fun doIlluminate(onIlluminatedRunnable: Runnable?) {
hbmProvider?.enableHbm() {
if (onIlluminatedRunnable != null) {
// No framework API can reliably tell when a frame reaches the panel. A timeout
// is the safest solution.
@@ -211,10 +168,6 @@ class UdfpsView(
override fun stopIllumination() {
isIlluminationRequested = false
animationViewController?.onIlluminationStopped()
ghbmView?.let { view ->
view.setGhbmIlluminationListener(null)
view.visibility = INVISIBLE
}
hbmProvider?.disableHbm(null /* onHbmDisabled */)
}
}

View File

@@ -23,7 +23,6 @@ import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.ViewUtils
import android.view.LayoutInflater
import android.view.Surface
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -37,7 +36,6 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.never
import org.mockito.Mockito.nullable
import org.mockito.Mockito.verify
@@ -148,7 +146,7 @@ class UdfpsViewTest : SysuiTestCase() {
view.startIllumination(onDone)
val illuminator = withArgCaptor<Runnable> {
verify(hbmProvider).enableHbm(anyInt(), nullable(Surface::class.java), capture())
verify(hbmProvider).enableHbm(capture())
}
assertThat(view.isIlluminationRequested).isTrue()

View File

@@ -2098,7 +2098,6 @@ public class DisplayModeDirector {
private class UdfpsObserver extends IUdfpsHbmListener.Stub {
private final SparseBooleanArray mLocalHbmEnabled = new SparseBooleanArray();
private final SparseBooleanArray mGlobalHbmEnabled = new SparseBooleanArray();
public void observe() {
StatusBarManagerInternal statusBar =
@@ -2109,39 +2108,27 @@ public class DisplayModeDirector {
}
@Override
public void onHbmEnabled(int hbmType, int displayId) {
public void onHbmEnabled(int displayId) {
synchronized (mLock) {
updateHbmStateLocked(hbmType, displayId, true /*enabled*/);
updateHbmStateLocked(displayId, true /*enabled*/);
}
}
@Override
public void onHbmDisabled(int hbmType, int displayId) {
public void onHbmDisabled(int displayId) {
synchronized (mLock) {
updateHbmStateLocked(hbmType, displayId, false /*enabled*/);
updateHbmStateLocked(displayId, false /*enabled*/);
}
}
private void updateHbmStateLocked(int hbmType, int displayId, boolean enabled) {
switch (hbmType) {
case UdfpsObserver.LOCAL_HBM:
mLocalHbmEnabled.put(displayId, enabled);
break;
case UdfpsObserver.GLOBAL_HBM:
mGlobalHbmEnabled.put(displayId, enabled);
break;
default:
Slog.w(TAG, "Unknown HBM type reported. Ignoring.");
return;
}
private void updateHbmStateLocked(int displayId, boolean enabled) {
mLocalHbmEnabled.put(displayId, enabled);
updateVoteLocked(displayId);
}
private void updateVoteLocked(int displayId) {
final Vote vote;
if (mGlobalHbmEnabled.get(displayId)) {
vote = Vote.forRefreshRates(60f, 60f);
} else if (mLocalHbmEnabled.get(displayId)) {
if (mLocalHbmEnabled.get(displayId)) {
Display.Mode[] modes = mSupportedModesByDisplay.get(displayId);
float maxRefreshRate = 0f;
for (Display.Mode mode : modes) {
@@ -2165,13 +2152,6 @@ public class DisplayModeDirector {
final String enabled = mLocalHbmEnabled.valueAt(i) ? "enabled" : "disabled";
pw.println(" Display " + displayId + ": " + enabled);
}
pw.println(" mGlobalHbmEnabled: ");
for (int i = 0; i < mGlobalHbmEnabled.size(); i++) {
final int displayId = mGlobalHbmEnabled.keyAt(i);
final String enabled = mGlobalHbmEnabled.valueAt(i) ? "enabled" : "disabled";
pw.println(" Display " + displayId + ": " + enabled);
}
}
}

View File

@@ -20,8 +20,8 @@ import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REF
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_HIGH_DISPLAY_BRIGHTNESS_THRESHOLDS;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_LOW_AMBIENT_BRIGHTNESS_THRESHOLDS;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_LOW_DISPLAY_BRIGHTNESS_THRESHOLDS;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_SUNLIGHT;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_HDR;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_SUNLIGHT;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HIGH_ZONE;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_LOW_ZONE;
@@ -919,16 +919,6 @@ public class DisplayModeDirectorTest {
// Should be no vote initially
Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
assertNull(vote);
// Enabling GHBM votes for 60hz
hbmListener.onHbmEnabled(IUdfpsHbmListener.GLOBAL_HBM, DISPLAY_ID);
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
assertVoteForRefreshRate(vote, 60.f);
// Disabling GHBM removes the vote
hbmListener.onHbmDisabled(IUdfpsHbmListener.GLOBAL_HBM, DISPLAY_ID);
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
assertNull(vote);
}
@Test