Merge "Refactor the HBM layer and add completion callbacks" into sc-dev am: bfc5b7abeb

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

Change-Id: I7fa5da5bd39cce08fe6cff7b274a69a8edaf2c4f
This commit is contained in:
Ilya Matyukhin
2021-06-03 22:30:07 +00:00
committed by Automerger Merge Worker
7 changed files with 54 additions and 37 deletions

View File

@@ -111,7 +111,7 @@ public class UdfpsController implements DozeReceiver {
@NonNull private final FalsingManager mFalsingManager; @NonNull private final FalsingManager mFalsingManager;
@NonNull private final PowerManager mPowerManager; @NonNull private final PowerManager mPowerManager;
@NonNull private final AccessibilityManager mAccessibilityManager; @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 // 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. // sensors, this, in addition to a lot of the code here, will be updated.
@VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps; @VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps;
@@ -494,7 +494,7 @@ public class UdfpsController implements DozeReceiver {
@NonNull AccessibilityManager accessibilityManager, @NonNull AccessibilityManager accessibilityManager,
@NonNull ScreenLifecycle screenLifecycle, @NonNull ScreenLifecycle screenLifecycle,
@Nullable Vibrator vibrator, @Nullable Vibrator vibrator,
@NonNull Optional<UdfpsHbmCallback> hbmCallback) { @NonNull Optional<UdfpsHbmProvider> hbmProvider) {
mContext = context; mContext = context;
// TODO (b/185124905): inject main handler and vibrator once done prototyping // TODO (b/185124905): inject main handler and vibrator once done prototyping
mMainHandler = new Handler(Looper.getMainLooper()); mMainHandler = new Handler(Looper.getMainLooper());
@@ -514,7 +514,7 @@ public class UdfpsController implements DozeReceiver {
mFalsingManager = falsingManager; mFalsingManager = falsingManager;
mPowerManager = powerManager; mPowerManager = powerManager;
mAccessibilityManager = accessibilityManager; mAccessibilityManager = accessibilityManager;
mHbmCallback = hbmCallback.orElse(null); mHbmProvider = hbmProvider.orElse(null);
screenLifecycle.addObserver(mScreenObserver); screenLifecycle.addObserver(mScreenObserver);
mScreenOn = screenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON; mScreenOn = screenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON;
@@ -649,7 +649,7 @@ public class UdfpsController implements DozeReceiver {
Log.v(TAG, "showUdfpsOverlay | adding window reason=" + reason); Log.v(TAG, "showUdfpsOverlay | adding window reason=" + reason);
mView = (UdfpsView) mInflater.inflate(R.layout.udfps_view, null, false); mView = (UdfpsView) mInflater.inflate(R.layout.udfps_view, null, false);
mView.setSensorProperties(mSensorProps); mView.setSensorProperties(mSensorProps);
mView.setHbmCallback(mHbmCallback); mView.setHbmProvider(mHbmProvider);
UdfpsAnimationViewController animation = inflateUdfpsAnimation(reason); UdfpsAnimationViewController animation = inflateUdfpsAnimation(reason);
animation.init(); animation.init();
mView.setAnimationViewController(animation); mView.setAnimationViewController(animation);

View File

@@ -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 * enable the HBM while showing the fingerprint illumination, and to disable the HBM after the
* illumination is no longer necessary. * 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. * 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 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 * @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. * 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. * 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 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 * @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. * 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);
} }

View File

@@ -24,9 +24,9 @@ import android.annotation.Nullable;
*/ */
interface UdfpsIlluminator { 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. * Invoked when illumination should start.

View File

@@ -28,6 +28,7 @@ import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
import android.view.SurfaceView; import android.view.SurfaceView;
@@ -57,7 +58,7 @@ public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator {
private final @HbmType int mHbmType; private final @HbmType int mHbmType;
@NonNull private RectF mSensorRect; @NonNull private RectF mSensorRect;
@Nullable private UdfpsHbmCallback mHbmCallback; @Nullable private UdfpsHbmProvider mHbmProvider;
public UdfpsSurfaceView(Context context, AttributeSet attrs) { public UdfpsSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
@@ -90,39 +91,44 @@ public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator {
} }
@Override @Override
public void setHbmCallback(@Nullable UdfpsHbmCallback callback) { public void setHbmProvider(@Nullable UdfpsHbmProvider hbmProvider) {
mHbmCallback = callback; mHbmProvider = hbmProvider;
} }
@Override @Override
public void startIllumination(@Nullable Runnable onIlluminatedRunnable) { public void startIllumination(@Nullable Runnable onIlluminatedRunnable) {
if (mHbmCallback != null) { if (mHbmProvider != null) {
mHbmCallback.enableHbm(mHbmType, mHolder.getSurface()); 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 { } else {
Log.e(TAG, "startIllumination | mHbmCallback is null"); Log.e(TAG, "startIllumination | mHbmProvider 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 */);
} }
} }
@Override @Override
public void stopIllumination() { public void stopIllumination() {
if (mHbmCallback != null) { if (mHbmProvider != null) {
mHbmCallback.disableHbm(mHbmType, mHolder.getSurface()); final Runnable onHbmDisabled = this::invalidate;
mHbmProvider.disableHbm(mHbmType, mHolder.getSurface(), onHbmDisabled);
} else { } else {
Log.e(TAG, "stopIllumination | mHbmCallback is null"); Log.e(TAG, "stopIllumination | mHbmProvider is null");
} }
invalidate();
} }
void onSensorRectUpdated(@NonNull RectF sensorRect) { void onSensorRectUpdated(@NonNull RectF sensorRect) {

View File

@@ -101,8 +101,8 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin
} }
@Override @Override
public void setHbmCallback(@Nullable UdfpsHbmCallback callback) { public void setHbmProvider(@Nullable UdfpsHbmProvider hbmProvider) {
mHbmSurfaceView.setHbmCallback(callback); mHbmSurfaceView.setHbmProvider(hbmProvider);
} }
@Override @Override

View File

@@ -29,7 +29,7 @@ import com.android.systemui.BootCompleteCacheImpl;
import com.android.systemui.SystemUIFactory; import com.android.systemui.SystemUIFactory;
import com.android.systemui.appops.dagger.AppOpsModule; import com.android.systemui.appops.dagger.AppOpsModule;
import com.android.systemui.assist.AssistModule; 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.classifier.FalsingModule;
import com.android.systemui.controls.dagger.ControlsModule; import com.android.systemui.controls.dagger.ControlsModule;
import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.Main;
@@ -163,7 +163,7 @@ public abstract class SystemUIModule {
abstract StatusBar optionalStatusBar(); abstract StatusBar optionalStatusBar();
@BindsOptionalOf @BindsOptionalOf
abstract UdfpsHbmCallback optionalUdfpsHbmCallback(); abstract UdfpsHbmProvider optionalUdfpsHbmProvider();
@SysUISingleton @SysUISingleton
@Binds @Binds

View File

@@ -95,7 +95,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Mock @Mock
private WindowManager mWindowManager; private WindowManager mWindowManager;
@Mock @Mock
private UdfpsHbmCallback mHbmCallback; private UdfpsHbmProvider mHbmProvider;
@Mock @Mock
private StatusBarStateController mStatusBarStateController; private StatusBarStateController mStatusBarStateController;
@Mock @Mock
@@ -178,7 +178,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
mAccessibilityManager, mAccessibilityManager,
mScreenLifecycle, mScreenLifecycle,
mVibrator, mVibrator,
Optional.of(mHbmCallback)); Optional.of(mHbmProvider));
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture()); verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
mOverlayController = mOverlayCaptor.getValue(); mOverlayController = mOverlayCaptor.getValue();
verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture()); verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());