diff options
author | Arian <arian.kulmer@web.de> | 2022-08-20 23:38:25 +0200 |
---|---|---|
committer | alk3pInjection <webmaster@raspii.tech> | 2023-04-20 00:08:54 +0800 |
commit | 8424f4a5235b417daa977241cdd9384b5e7639b9 (patch) | |
tree | 5fc58c8a762d0d952e9ee960d27615d4771ed066 | |
parent | 9c9e6d6cb09347ad52eaa99a99d288ceb4bd6ba9 (diff) |
udfps: Restore illumination dot for global hbm
UdfpsSurfaceView.java is imported from android-12.1.0_r22
Change-Id: I4a4e85a7437a9a444a4f952fd62e4fe12f56ce5a
3 files changed, 181 insertions, 1 deletions
diff --git a/packages/SystemUI/res/layout/udfps_view.xml b/packages/SystemUI/res/layout/udfps_view.xml index 257d238f5c54..0fcbfa161ddf 100644 --- a/packages/SystemUI/res/layout/udfps_view.xml +++ b/packages/SystemUI/res/layout/udfps_view.xml @@ -28,4 +28,10 @@ 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> diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java new file mode 100644 index 000000000000..f5ada948dab7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java @@ -0,0 +1,145 @@ +/* + * 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 onDisplayConfigured a runnable that should be run after GHBM is enabled. + */ + void enableGhbm(@NonNull Surface surface, @Nullable Runnable onDisplayConfigured); + } + + @NonNull private final SurfaceHolder mHolder; + @NonNull private final Paint mSensorPaint; + + @Nullable private GhbmIlluminationListener mGhbmIlluminationListener; + @Nullable private Runnable mOnDisplayConfigured; + 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(mOnDisplayConfigured); + mOnDisplayConfigured = 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 onDisplayConfigured) { + if (mGhbmIlluminationListener == null) { + Log.e(TAG, "startIllumination | mGhbmIlluminationListener is null"); + return; + } + + if (mHasValidSurface) { + doIlluminate(onDisplayConfigured); + } else { + mAwaitingSurfaceToStartIllumination = true; + mOnDisplayConfigured = onDisplayConfigured; + } + } + + private void doIlluminate(@Nullable Runnable onDisplayConfigured) { + if (mGhbmIlluminationListener == null) { + Log.e(TAG, "doIlluminate | mGhbmIlluminationListener is null"); + return; + } + + mGhbmIlluminationListener.enableGhbm(mHolder.getSurface(), onDisplayConfigured); + } + + /** + * 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); + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt index 4a8877edfa53..97590822a3fb 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt @@ -25,6 +25,7 @@ import android.graphics.RectF 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 @@ -60,6 +61,8 @@ class UdfpsView( a.getFloat(R.styleable.UdfpsView_sensorTouchAreaCoefficient, 0f) } + private var ghbmView: UdfpsSurfaceView? = null + /** View controller (can be different for enrollment, BiometricPrompt, Keyguard, etc.). */ var animationViewController: UdfpsAnimationViewController<*>? = null @@ -86,6 +89,10 @@ class UdfpsView( return (animationViewController == null || !animationViewController!!.shouldPauseAuth()) } + override fun onFinishInflate() { + ghbmView = findViewById(R.id.hbm_view) + } + override fun dozeTimeTick() { animationViewController?.dozeTimeTick() } @@ -153,12 +160,34 @@ class UdfpsView( fun configureDisplay(onDisplayConfigured: Runnable) { isDisplayConfigured = true animationViewController?.onDisplayConfiguring() - mUdfpsDisplayMode?.enable(onDisplayConfigured) + val gView = ghbmView + if (gView != null) { + gView.setGhbmIlluminationListener(this::doIlluminate) + gView.visibility = VISIBLE + gView.startGhbmIllumination(onDisplayConfigured) + } else { + doIlluminate(null /* surface */, onDisplayConfigured) + } + } + + private fun doIlluminate(surface: Surface?, onDisplayConfigured: Runnable?) { + if (ghbmView != null && surface == null) { + Log.e(TAG, "doIlluminate | surface must be non-null for GHBM") + } + + mUdfpsDisplayMode?.enable { + onDisplayConfigured?.run() + ghbmView?.drawIlluminationDot(RectF(sensorRect)) + } } fun unconfigureDisplay() { isDisplayConfigured = false animationViewController?.onDisplayUnconfigured() + ghbmView?.let { view -> + view.setGhbmIlluminationListener(null) + view.visibility = INVISIBLE + } mUdfpsDisplayMode?.disable(null /* onDisabled */) } } |