From eaa86690358b80684c1b5667ab2b84c45f16438c Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 3 Jun 2021 11:19:39 -0700 Subject: [PATCH] Refactor the HBM layer and add completion callbacks Bug: 187081118 Test: atest UdfpsControllerTest Change-Id: Ief24c426baa2acd34719581fed0a5ef112cb7d64 --- .../systemui/biometrics/UdfpsController.java | 8 +-- ...HbmCallback.java => UdfpsHbmProvider.java} | 17 +++++-- .../systemui/biometrics/UdfpsIlluminator.java | 4 +- .../systemui/biometrics/UdfpsSurfaceView.java | 50 +++++++++++-------- .../systemui/biometrics/UdfpsView.java | 4 +- .../systemui/dagger/SystemUIModule.java | 4 +- .../biometrics/UdfpsControllerTest.java | 4 +- 7 files changed, 54 insertions(+), 37 deletions(-) rename packages/SystemUI/src/com/android/systemui/biometrics/{UdfpsHbmCallback.java => UdfpsHbmProvider.java} (77%) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 3726ae132b648..cef3e7de3478e 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -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 hbmCallback) { + @NonNull Optional 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); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmCallback.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java similarity index 77% rename from packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmCallback.java rename to packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java index 85f0d278e3f14..52141c0d6a623 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmCallback.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java @@ -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); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsIlluminator.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsIlluminator.java index 1676bcd57afc0..f85e9361ecf21 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsIlluminator.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsIlluminator.java @@ -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. diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java index aa5f0f6cf7f47..86e3ae6cae243 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java @@ -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()); + 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. + postDelayed(onIlluminatedRunnable, 50 /* delayMillis */); + } else { + Log.w(TAG, "startIllumination | onIlluminatedRunnable is null"); + } + }; + + mHbmProvider.enableHbm(mHbmType, surface, onHbmEnabled); } else { - Log.e(TAG, "startIllumination | mHbmCallback is null"); - } - - 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. - postDelayed(onIlluminatedRunnable, 50 /* delayMillis */); + 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) { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java index a1d30403e0b8d..5e5584cf30ea5 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index f422e9e40d33b..556f95642deb3 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -29,7 +29,7 @@ import com.android.systemui.BootCompleteCacheImpl; import com.android.systemui.SystemUIFactory; import com.android.systemui.appops.dagger.AppOpsModule; import com.android.systemui.assist.AssistModule; -import com.android.systemui.biometrics.UdfpsHbmCallback; +import com.android.systemui.biometrics.UdfpsHbmProvider; import com.android.systemui.classifier.FalsingModule; import com.android.systemui.controls.dagger.ControlsModule; import com.android.systemui.dagger.qualifiers.Main; @@ -163,7 +163,7 @@ public abstract class SystemUIModule { abstract StatusBar optionalStatusBar(); @BindsOptionalOf - abstract UdfpsHbmCallback optionalUdfpsHbmCallback(); + abstract UdfpsHbmProvider optionalUdfpsHbmProvider(); @SysUISingleton @Binds diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index 9322aa9b0ea83..41f9877278606 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -95,7 +95,7 @@ public class UdfpsControllerTest extends SysuiTestCase { @Mock private WindowManager mWindowManager; @Mock - private UdfpsHbmCallback mHbmCallback; + private UdfpsHbmProvider mHbmProvider; @Mock private StatusBarStateController mStatusBarStateController; @Mock @@ -178,7 +178,7 @@ public class UdfpsControllerTest extends SysuiTestCase { mAccessibilityManager, mScreenLifecycle, mVibrator, - Optional.of(mHbmCallback)); + Optional.of(mHbmProvider)); verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture()); mOverlayController = mOverlayCaptor.getValue(); verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());