Merge "Remove all GHBM logic" into tm-dev am: 3c984e8bf5

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17491204

Change-Id: If44f9090b55ab3f3fa953aa767ff78c3bfbc872b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Grace Cheng
2022-04-04 16:26:51 +00:00
committed by Automerger Merge Worker
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