diff options
| author | 2024-01-13 02:35:05 +0000 | |
|---|---|---|
| committer | 2024-01-13 02:35:05 +0000 | |
| commit | d8b2ac7940b00d71ce29840d40b0049c5a3213d3 (patch) | |
| tree | 66c29a6ca22fcba0246e26a177e7031be96907fc | |
| parent | ffb888836aa9433779813091de0289941d420783 (diff) | |
| parent | 81cbe1ebb383775ad66145803bc433042847efc5 (diff) | |
Merge "Integrate isHardwareIgnoringTouches into OperationContext" into main
28 files changed, 324 insertions, 40 deletions
diff --git a/core/java/android/hardware/biometrics/IBiometricContextListener.aidl b/core/java/android/hardware/biometrics/IBiometricContextListener.aidl index 6ac658144164..2f58f51d5483 100644 --- a/core/java/android/hardware/biometrics/IBiometricContextListener.aidl +++ b/core/java/android/hardware/biometrics/IBiometricContextListener.aidl @@ -38,4 +38,8 @@ oneway interface IBiometricContextListener {      // Called when the display state of the device changes.      // Where `displayState` is defined in AuthenticateOptions.DisplayState      void onDisplayStateChanged(int displayState); + +    // Called when the HAL ignoring touches state changes. +    // When true, the HAL ignores touches on the sensor. +    void onHardwareIgnoreTouchesChanged(boolean shouldIgnore);  } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt index b0beab932e21..f7743e2814f0 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt @@ -38,6 +38,7 @@ import com.android.keyguard.KeyguardUpdateMonitor  import com.android.systemui.Flags  import com.android.systemui.SysuiTestCase  import com.android.systemui.animation.ActivityLaunchAnimator +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor  import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams  import com.android.systemui.biometrics.ui.viewmodel.DefaultUdfpsTouchOverlayViewModel  import com.android.systemui.biometrics.ui.viewmodel.DeviceEntryUdfpsTouchOverlayViewModel @@ -118,6 +119,7 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {      @Mock private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor      @Mock private lateinit var shadeInteractor: ShadeInteractor      @Captor private lateinit var layoutParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams> +    @Mock private lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor      private val onTouch = { _: View, _: MotionEvent, _: Boolean -> true }      private var overlayParams: UdfpsOverlayParams = UdfpsOverlayParams() @@ -174,7 +176,8 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {                  mSelectedUserInteractor,                  { deviceEntryUdfpsTouchOverlayViewModel },                  { defaultUdfpsTouchOverlayViewModel }, -                shadeInteractor +                shadeInteractor, +                udfpsOverlayInteractor,              )          block()      } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index a59a4b864ac4..90c3c14bbc4f 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -76,6 +76,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;  import com.android.systemui.Flags;  import com.android.systemui.SysuiTestCase;  import com.android.systemui.animation.ActivityLaunchAnimator; +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor;  import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams;  import com.android.systemui.biometrics.udfps.InteractionEvent;  import com.android.systemui.biometrics.udfps.NormalizedTouchData; @@ -214,6 +215,8 @@ public class UdfpsControllerTest extends SysuiTestCase {      @Mock      private AlternateBouncerInteractor mAlternateBouncerInteractor;      @Mock +    private UdfpsOverlayInteractor mUdfpsOverlayInteractor; +    @Mock      private UdfpsKeyguardAccessibilityDelegate mUdfpsKeyguardAccessibilityDelegate;      @Mock      private SelectedUserInteractor mSelectedUserInteractor; @@ -342,8 +345,8 @@ public class UdfpsControllerTest extends SysuiTestCase {                  mFpsUnlockTracker,                  mKeyguardTransitionInteractor,                  mDeviceEntryUdfpsTouchOverlayViewModel, -                mDefaultUdfpsTouchOverlayViewModel - +                mDefaultUdfpsTouchOverlayViewModel, +                mUdfpsOverlayInteractor          );          verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());          mOverlayController = mOverlayCaptor.getValue(); diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java index 13b53a896b70..7d9c2f96ef58 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java @@ -27,6 +27,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;  import com.android.systemui.Flags;  import com.android.systemui.SysuiTestCase;  import com.android.systemui.animation.ActivityLaunchAnimator; +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor;  import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;  import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;  import com.android.systemui.dump.DumpManager; @@ -76,6 +77,7 @@ public class UdfpsKeyguardViewLegacyControllerBaseTest extends SysuiTestCase {      protected @Mock UdfpsKeyguardAccessibilityDelegate mUdfpsKeyguardAccessibilityDelegate;      protected @Mock SelectedUserInteractor mSelectedUserInteractor;      protected @Mock KeyguardTransitionInteractor mKeyguardTransitionInteractor; +    protected @Mock UdfpsOverlayInteractor mUdfpsOverlayInteractor;      protected FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags(); @@ -152,7 +154,8 @@ public class UdfpsKeyguardViewLegacyControllerBaseTest extends SysuiTestCase {                  mUdfpsKeyguardAccessibilityDelegate,                  mSelectedUserInteractor,                  mKeyguardTransitionInteractor, -                mShadeInteractor); +                mShadeInteractor, +                mUdfpsOverlayInteractor);          return controller;      }  } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt index 335ac9d42e77..0e257bcfecc3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt @@ -24,6 +24,7 @@ import com.android.keyguard.KeyguardSecurityModel  import com.android.systemui.biometrics.UdfpsKeyguardViewLegacy.ANIMATE_APPEAR_ON_SCREEN_OFF  import com.android.systemui.biometrics.UdfpsKeyguardViewLegacy.ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN  import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor  import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository  import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepositoryImpl  import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor @@ -32,6 +33,7 @@ import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor  import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants  import com.android.systemui.bouncer.ui.BouncerView  import com.android.systemui.classifier.FalsingCollector +import com.android.systemui.coroutines.collectLastValue  import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor  import com.android.systemui.keyguard.DismissCallbackRegistry  import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository @@ -45,9 +47,11 @@ import com.android.systemui.log.table.TableLogBuffer  import com.android.systemui.plugins.statusbar.StatusBarStateController  import com.android.systemui.statusbar.StatusBarState  import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.user.domain.interactor.SelectedUserInteractor  import com.android.systemui.util.mockito.whenever  import com.android.systemui.util.time.FakeSystemClock  import com.android.systemui.util.time.SystemClock +import com.google.common.truth.Truth.assertThat  import kotlinx.coroutines.test.StandardTestDispatcher  import kotlinx.coroutines.test.TestScope  import kotlinx.coroutines.test.runCurrent @@ -130,6 +134,13 @@ class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest :                      repository = transitionRepository,                  )                  .keyguardTransitionInteractor +        mUdfpsOverlayInteractor = +            UdfpsOverlayInteractor( +                context, +                mock(AuthController::class.java), +                mock(SelectedUserInteractor::class.java), +                testScope.backgroundScope, +            )          return createUdfpsKeyguardViewController(/* useModernBouncer */ true)      } @@ -239,6 +250,31 @@ class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest :          }      @Test +    fun shouldHandleTouchesChange() = +        testScope.runTest { +            val shouldHandleTouches by collectLastValue(mUdfpsOverlayInteractor.shouldHandleTouches) + +            // GIVEN view is attached + on the keyguard +            mController.onViewAttached() +            captureStatusBarStateListeners() +            sendStatusBarStateChanged(StatusBarState.KEYGUARD) +            whenever(mView.setPauseAuth(true)).thenReturn(true) +            whenever(mView.unpausedAlpha).thenReturn(0) + +            // WHEN panelViewExpansion changes to expanded +            val job = mController.listenForBouncerExpansion(this) +            keyguardBouncerRepository.setPrimaryShow(true) +            keyguardBouncerRepository.setPanelExpansion(KeyguardBouncerConstants.EXPANSION_VISIBLE) +            runCurrent() + +            // THEN UDFPS auth is paused and should not handle touches +            assertThat(mController.shouldPauseAuth()).isTrue() +            assertThat(shouldHandleTouches!!).isFalse() + +            job.cancel() +        } + +    @Test      fun fadeFromDialogSuggestedAlpha() =          testScope.runTest {              // GIVEN view is attached and status bar expansion is 1f diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt index 7d9ec08bcb3b..f5603ed732a5 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt @@ -23,6 +23,7 @@ import androidx.lifecycle.Lifecycle  import androidx.lifecycle.repeatOnLifecycle  import com.android.app.animation.Interpolators  import com.android.systemui.Dumpable +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor  import com.android.systemui.dump.DumpManager  import com.android.systemui.lifecycle.repeatWhenAttached  import com.android.systemui.plugins.statusbar.StatusBarStateController @@ -49,7 +50,8 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>(      protected val statusBarStateController: StatusBarStateController,      protected val shadeInteractor: ShadeInteractor,      protected val dialogManager: SystemUIDialogManager, -    private val dumpManager: DumpManager +    private val dumpManager: DumpManager, +    private val udfpsOverlayInteractor: UdfpsOverlayInteractor,  ) : ViewController<T>(view), Dumpable {      protected abstract val tag: String @@ -130,11 +132,13 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>(      override fun onViewAttached() {          dialogManager.registerListener(dialogListener)          dumpManager.registerDumpable(dumpTag, this) +        udfpsOverlayInteractor.setHandleTouches(shouldHandle = true)      }      override fun onViewDetached() {          dialogManager.unregisterListener(dialogListener)          dumpManager.unregisterDumpable(dumpTag) +        udfpsOverlayInteractor.setHandleTouches(shouldHandle = true)      }      /** @@ -165,6 +169,7 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>(      fun updatePauseAuth() {          if (view.setPauseAuth(shouldPauseAuth())) {              view.postInvalidate() +            udfpsOverlayInteractor.setHandleTouches(shouldHandle = !shouldPauseAuth())          }      } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt index e7b0d9fd9d85..e0455b58b919 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt @@ -15,6 +15,7 @@   */  package com.android.systemui.biometrics +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor  import com.android.systemui.dump.DumpManager  import com.android.systemui.plugins.statusbar.StatusBarStateController  import com.android.systemui.shade.domain.interactor.ShadeInteractor @@ -28,13 +29,15 @@ class UdfpsBpViewController(      statusBarStateController: StatusBarStateController,      shadeInteractor: ShadeInteractor,      systemUIDialogManager: SystemUIDialogManager, -    dumpManager: DumpManager +    dumpManager: DumpManager, +    udfpsOverlayInteractor: UdfpsOverlayInteractor,  ) : UdfpsAnimationViewController<UdfpsBpView>(      view,      statusBarStateController,      shadeInteractor,      systemUIDialogManager, -    dumpManager +    dumpManager, +    udfpsOverlayInteractor,  ) {      override val tag = "UdfpsBpViewController" diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 81de0a283e88..66fe4b36567d 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -68,6 +68,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;  import com.android.systemui.Dumpable;  import com.android.systemui.animation.ActivityLaunchAnimator;  import com.android.systemui.biometrics.dagger.BiometricsBackground; +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor;  import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams;  import com.android.systemui.biometrics.udfps.InteractionEvent;  import com.android.systemui.biometrics.udfps.NormalizedTouchData; @@ -171,6 +172,7 @@ public class UdfpsController implements DozeReceiver, Dumpable {      @NonNull private final Lazy<DefaultUdfpsTouchOverlayViewModel>              mDefaultUdfpsTouchOverlayViewModel;      @NonNull private final AlternateBouncerInteractor mAlternateBouncerInteractor; +    @NonNull private final UdfpsOverlayInteractor mUdfpsOverlayInteractor;      @NonNull private final InputManager mInputManager;      @NonNull private final UdfpsKeyguardAccessibilityDelegate mUdfpsKeyguardAccessibilityDelegate;      @NonNull private final SelectedUserInteractor mSelectedUserInteractor; @@ -293,7 +295,8 @@ public class UdfpsController implements DozeReceiver, Dumpable {                          mSelectedUserInteractor,                          mDeviceEntryUdfpsTouchOverlayViewModel,                          mDefaultUdfpsTouchOverlayViewModel, -                        mShadeInteractor +                        mShadeInteractor, +                        mUdfpsOverlayInteractor                      )));          } @@ -674,7 +677,8 @@ public class UdfpsController implements DozeReceiver, Dumpable {              @NonNull FpsUnlockTracker fpsUnlockTracker,              @NonNull KeyguardTransitionInteractor keyguardTransitionInteractor,              Lazy<DeviceEntryUdfpsTouchOverlayViewModel> deviceEntryUdfpsTouchOverlayViewModel, -            Lazy<DefaultUdfpsTouchOverlayViewModel> defaultUdfpsTouchOverlayViewModel) { +            Lazy<DefaultUdfpsTouchOverlayViewModel> defaultUdfpsTouchOverlayViewModel, +            @NonNull UdfpsOverlayInteractor udfpsOverlayInteractor) {          mContext = context;          mExecution = execution;          mVibrator = vibrator; @@ -715,6 +719,7 @@ public class UdfpsController implements DozeReceiver, Dumpable {          mPrimaryBouncerInteractor = primaryBouncerInteractor;          mShadeInteractor = shadeInteractor;          mAlternateBouncerInteractor = alternateBouncerInteractor; +        mUdfpsOverlayInteractor = udfpsOverlayInteractor;          mInputManager = inputManager;          mUdfpsKeyguardAccessibilityDelegate = udfpsKeyguardAccessibilityDelegate;          mSelectedUserInteractor = selectedUserInteractor; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt index b94a1779e10b..417608336974 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt @@ -45,6 +45,7 @@ import androidx.annotation.LayoutRes  import androidx.annotation.VisibleForTesting  import com.android.keyguard.KeyguardUpdateMonitor  import com.android.systemui.animation.ActivityLaunchAnimator +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor  import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams  import com.android.systemui.biometrics.ui.binder.UdfpsTouchOverlayBinder  import com.android.systemui.biometrics.ui.view.UdfpsTouchOverlay @@ -109,6 +110,7 @@ class UdfpsControllerOverlay @JvmOverloads constructor(      private val deviceEntryUdfpsTouchOverlayViewModel: Lazy<DeviceEntryUdfpsTouchOverlayViewModel>,      private val defaultUdfpsTouchOverlayViewModel: Lazy<DefaultUdfpsTouchOverlayViewModel>,      private val shadeInteractor: ShadeInteractor, +    private val udfpsOverlayInteractor: UdfpsOverlayInteractor,  ) {      private var overlayViewLegacy: UdfpsView? = null          private set @@ -281,7 +283,8 @@ class UdfpsControllerOverlay @JvmOverloads constructor(                      statusBarStateController,                      shadeInteractor,                      dialogManager, -                    dumpManager +                    dumpManager, +                    udfpsOverlayInteractor,                  )              }              REASON_AUTH_KEYGUARD -> { @@ -306,6 +309,7 @@ class UdfpsControllerOverlay @JvmOverloads constructor(                      selectedUserInteractor,                      transitionInteractor,                      shadeInteractor, +                    udfpsOverlayInteractor,                  )              }              REASON_AUTH_BP -> { @@ -315,7 +319,8 @@ class UdfpsControllerOverlay @JvmOverloads constructor(                      statusBarStateController,                      shadeInteractor,                      dialogManager, -                    dumpManager +                    dumpManager, +                    udfpsOverlayInteractor,                  )              }              REASON_AUTH_OTHER, @@ -325,7 +330,8 @@ class UdfpsControllerOverlay @JvmOverloads constructor(                      statusBarStateController,                      shadeInteractor,                      dialogManager, -                    dumpManager +                    dumpManager, +                    udfpsOverlayInteractor,                  )              }              else -> { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyViewController.kt index ab3fbb191527..cfbbc26800d2 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyViewController.kt @@ -15,6 +15,7 @@   */  package com.android.systemui.biometrics +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor  import com.android.systemui.dump.DumpManager  import com.android.systemui.plugins.statusbar.StatusBarStateController  import com.android.systemui.shade.domain.interactor.ShadeInteractor @@ -30,13 +31,15 @@ class UdfpsFpmEmptyViewController(      statusBarStateController: StatusBarStateController,      shadeInteractor: ShadeInteractor,      systemUIDialogManager: SystemUIDialogManager, -    dumpManager: DumpManager +    dumpManager: DumpManager, +    udfpsOverlayInteractor: UdfpsOverlayInteractor,  ) : UdfpsAnimationViewController<UdfpsFpmEmptyView>(      view,      statusBarStateController,      shadeInteractor,      systemUIDialogManager, -    dumpManager +    dumpManager, +    udfpsOverlayInteractor,  ) {      override val tag = "UdfpsFpmOtherViewController"  } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt index 9f170241269d..7020d05350da 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt @@ -27,6 +27,7 @@ import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerPr  import com.android.keyguard.KeyguardUpdateMonitor  import com.android.systemui.animation.ActivityLaunchAnimator  import com.android.systemui.biometrics.UdfpsKeyguardViewLegacy.ANIMATE_APPEAR_ON_SCREEN_OFF +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor  import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor  import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor  import com.android.systemui.dump.DumpManager @@ -75,6 +76,7 @@ open class UdfpsKeyguardViewControllerLegacy(      private val selectedUserInteractor: SelectedUserInteractor,      private val transitionInteractor: KeyguardTransitionInteractor,      shadeInteractor: ShadeInteractor, +    udfpsOverlayInteractor: UdfpsOverlayInteractor,  ) :      UdfpsAnimationViewController<UdfpsKeyguardViewLegacy>(          view, @@ -82,6 +84,7 @@ open class UdfpsKeyguardViewControllerLegacy(          shadeInteractor,          systemUIDialogManager,          dumpManager, +        udfpsOverlayInteractor,      ) {      private val uniqueIdentifier = this.toString()      private var showingUdfpsBouncer = false diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt index 863ba8d15b47..70be0f249b33 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt @@ -63,6 +63,9 @@ interface LogContextInteractor {      /** Current display state, defined as [AuthenticateOptions.DisplayState] */      val displayState: Flow<Int> +    /** If touches on the fingerprint sensor should be ignored by the HAL. */ +    val isHardwareIgnoringTouches: Flow<Boolean> +      /**       * Add a permanent context listener.       * @@ -79,12 +82,11 @@ constructor(      @Application private val applicationScope: CoroutineScope,      private val foldProvider: FoldStateProvider,      keyguardTransitionInteractor: KeyguardTransitionInteractor, +    udfpsOverlayInteractor: UdfpsOverlayInteractor,  ) : LogContextInteractor {      init { -        applicationScope.launch { -            foldProvider.start() -        } +        applicationScope.launch { foldProvider.start() }      }      override val displayState = @@ -102,6 +104,9 @@ constructor(              }          } +    override val isHardwareIgnoringTouches: Flow<Boolean> = +        udfpsOverlayInteractor.shouldHandleTouches.map { shouldHandle -> !shouldHandle } +      override val isAod =          displayState.map { it == AuthenticateOptions.DISPLAY_STATE_AOD }.distinctUntilChanged() @@ -159,6 +164,12 @@ constructor(                  .catch { t -> Log.w(TAG, "failed to notify new display state", t) }                  .launchIn(this) +            isHardwareIgnoringTouches +                .distinctUntilChanged() +                .onEach { state -> listener.onHardwareIgnoreTouchesChanged(state) } +                .catch { t -> Log.w(TAG, "failed to notify new set ignore state", t) } +                .launchIn(this) +              listener.asBinder().linkToDeath({ cancel() }, 0)          }      } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt index f4a2811a1b5a..4fc1b5841047 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt @@ -30,8 +30,10 @@ import javax.inject.Inject  import kotlinx.coroutines.CoroutineScope  import kotlinx.coroutines.channels.awaitClose  import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow  import kotlinx.coroutines.flow.SharingStarted  import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow  import kotlinx.coroutines.flow.map  import kotlinx.coroutines.flow.stateIn @@ -56,6 +58,16 @@ constructor(          return isUdfpsEnrolled && isWithinOverlayBounds      } +    /** Sets whether Udfps overlay should handle touches */ +    fun setHandleTouches(shouldHandle: Boolean = true) { +        _shouldHandleTouches.value = shouldHandle +    } + +    private var _shouldHandleTouches = MutableStateFlow(true) + +    /** Whether Udfps overlay should handle touches */ +    val shouldHandleTouches: StateFlow<Boolean> = _shouldHandleTouches.asStateFlow() +      /** Returns the current udfpsOverlayParams */      val udfpsOverlayParams: StateFlow<UdfpsOverlayParams> =          ConflatedCallbackFlow.conflatedCallbackFlow { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt index 647dae6fd6c2..13306becf6d2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt @@ -20,6 +20,7 @@ import android.testing.TestableLooper  import androidx.test.ext.junit.runners.AndroidJUnit4  import androidx.test.filters.SmallTest  import com.android.systemui.SysuiTestCase +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor  import com.android.systemui.dump.DumpManager  import com.android.systemui.plugins.statusbar.StatusBarStateController  import com.android.systemui.shade.domain.interactor.ShadeInteractor @@ -44,6 +45,7 @@ class UdfpsBpViewControllerTest : SysuiTestCase() {      @Mock lateinit var shadeInteractor: ShadeInteractor      @Mock lateinit var systemUIDialogManager: SystemUIDialogManager      @Mock lateinit var dumpManager: DumpManager +    @Mock lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor      private lateinit var udfpsBpViewController: UdfpsBpViewController @@ -55,7 +57,8 @@ class UdfpsBpViewControllerTest : SysuiTestCase() {                  statusBarStateController,                  shadeInteractor,                  systemUIDialogManager, -                dumpManager +                dumpManager, +                udfpsOverlayInteractor,              )      } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt index 8f8004f1cbb8..b1e471af2e71 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt @@ -5,6 +5,7 @@ import android.hardware.biometrics.IBiometricContextListener  import android.hardware.biometrics.IBiometricContextListener.FoldState  import androidx.test.filters.SmallTest  import com.android.systemui.SysuiTestCase +import com.android.systemui.biometrics.AuthController  import com.android.systemui.coroutines.collectLastValue  import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository  import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory @@ -17,6 +18,7 @@ import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_HALF_OPEN  import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING  import com.android.systemui.unfold.updates.FOLD_UPDATE_START_OPENING  import com.android.systemui.unfold.updates.FoldStateProvider +import com.android.systemui.user.domain.interactor.SelectedUserInteractor  import com.android.systemui.util.mockito.withArgCaptor  import com.google.common.truth.Truth.assertThat  import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -42,7 +44,10 @@ class LogContextInteractorImplTest : SysuiTestCase() {      private val testScope = TestScope()      @Mock private lateinit var foldProvider: FoldStateProvider +    @Mock private lateinit var authController: AuthController +    @Mock private lateinit var selectedUserInteractor: SelectedUserInteractor +    private lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor      private lateinit var keyguardTransitionRepository: FakeKeyguardTransitionRepository      private lateinit var interactor: LogContextInteractorImpl @@ -50,6 +55,13 @@ class LogContextInteractorImplTest : SysuiTestCase() {      @Before      fun setup() {          keyguardTransitionRepository = FakeKeyguardTransitionRepository() +        udfpsOverlayInteractor = +            UdfpsOverlayInteractor( +                context, +                authController, +                selectedUserInteractor, +                testScope.backgroundScope, +            )          interactor =              LogContextInteractorImpl(                  testScope.backgroundScope, @@ -59,6 +71,7 @@ class LogContextInteractorImplTest : SysuiTestCase() {                          scope = testScope.backgroundScope,                      )                      .keyguardTransitionInteractor, +                udfpsOverlayInteractor,              )      } @@ -162,6 +175,18 @@ class LogContextInteractorImplTest : SysuiTestCase() {          }      @Test +    fun isHardwareIgnoringTouchesChanges() = +        testScope.runTest { +            val isHardwareIgnoringTouches by collectLastValue(interactor.isHardwareIgnoringTouches) + +            udfpsOverlayInteractor.setHandleTouches(true) +            assertThat(isHardwareIgnoringTouches).isFalse() + +            udfpsOverlayInteractor.setHandleTouches(false) +            assertThat(isHardwareIgnoringTouches).isTrue() +        } + +    @Test      fun foldStateChanges() =          testScope.runTest {              val foldState = collectLastValue(interactor.foldState) @@ -195,6 +220,7 @@ class LogContextInteractorImplTest : SysuiTestCase() {              var folded: Int? = null              var displayState: Int? = null +            var ignoreTouches: Boolean? = null              val job =                  interactor.addBiometricContextListener(                      object : IBiometricContextListener.Stub() { @@ -205,12 +231,17 @@ class LogContextInteractorImplTest : SysuiTestCase() {                          override fun onDisplayStateChanged(newDisplayState: Int) {                              displayState = newDisplayState                          } + +                        override fun onHardwareIgnoreTouchesChanged(newIgnoreTouches: Boolean) { +                            ignoreTouches = newIgnoreTouches +                        }                      }                  )              runCurrent()              assertThat(folded).isEqualTo(FoldState.FULLY_CLOSED)              assertThat(displayState).isEqualTo(AuthenticateOptions.DISPLAY_STATE_AOD) +            assertThat(ignoreTouches).isFalse()              foldListener.onFoldUpdate(FOLD_UPDATE_START_OPENING)              foldListener.onFoldUpdate(FOLD_UPDATE_FINISH_HALF_OPEN) @@ -220,6 +251,11 @@ class LogContextInteractorImplTest : SysuiTestCase() {              assertThat(folded).isEqualTo(FoldState.HALF_OPENED)              assertThat(displayState).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN) +            udfpsOverlayInteractor.setHandleTouches(false) +            runCurrent() + +            assertThat(ignoreTouches).isTrue() +              job.cancel()              // stale updates should be ignored diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt index 6a686726b959..c0e108ef75f8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt @@ -68,7 +68,7 @@ class UdfpsOverlayInteractorTest : SysuiTestCase() {      @Test      fun testShouldInterceptTouch() =          testScope.runTest { -            createUdpfsOverlayInteractor() +            createUdfpsOverlayInteractor()              // When fingerprint enrolled and touch is within bounds              verify(authController).addCallback(authControllerCallback.capture()) @@ -92,7 +92,7 @@ class UdfpsOverlayInteractorTest : SysuiTestCase() {      @Test      fun testUdfpsOverlayParamsChange() =          testScope.runTest { -            createUdpfsOverlayInteractor() +            createUdfpsOverlayInteractor()              val udfpsOverlayParams = collectLastValue(underTest.udfpsOverlayParams)              runCurrent() @@ -105,7 +105,7 @@ class UdfpsOverlayInteractorTest : SysuiTestCase() {              assertThat(udfpsOverlayParams()).isEqualTo(firstParams)          } -    private fun createUdpfsOverlayInteractor() { +    private fun createUdfpsOverlayInteractor() {          underTest =              UdfpsOverlayInteractor(                  context, diff --git a/services/core/java/com/android/server/biometrics/log/BiometricContext.java b/services/core/java/com/android/server/biometrics/log/BiometricContext.java index 3dcea19b6077..f8a98675c0c7 100644 --- a/services/core/java/com/android/server/biometrics/log/BiometricContext.java +++ b/services/core/java/com/android/server/biometrics/log/BiometricContext.java @@ -77,6 +77,9 @@ public interface BiometricContext {      @AuthenticateOptions.DisplayState      int getDisplayState(); +    /** Gets whether touches on sensor are ignored by HAL */ +    boolean isHardwareIgnoringTouches(); +      /**       * Subscribe to context changes.       * diff --git a/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java b/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java index 95a047faef07..535b7b743625 100644 --- a/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java +++ b/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java @@ -86,8 +86,8 @@ public final class BiometricContextProvider implements BiometricContext {      @Nullable private final Handler mHandler;      private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;      private int mFoldState = IBiometricContextListener.FoldState.UNKNOWN; -      private int mDisplayState = AuthenticateOptions.DISPLAY_STATE_UNKNOWN; +    private boolean mIsHardwareIgnoringTouches = false;      @VisibleForTesting      final BroadcastReceiver mDockStateReceiver = new BroadcastReceiver() {          @Override @@ -129,6 +129,14 @@ public final class BiometricContextProvider implements BiometricContext {                          notifyChanged();                      }                  } + +                @Override +                public void onHardwareIgnoreTouchesChanged(boolean shouldIgnore) { +                    if (mIsHardwareIgnoringTouches != shouldIgnore) { +                        mIsHardwareIgnoringTouches = shouldIgnore; +                        notifyChanged(); +                    } +                }              });              service.registerSessionListener(SESSION_TYPES, new ISessionListener.Stub() {                  @Override @@ -215,6 +223,11 @@ public final class BiometricContextProvider implements BiometricContext {      }      @Override +    public boolean isHardwareIgnoringTouches() { +        return mIsHardwareIgnoringTouches; +    } + +    @Override      public void subscribe(@NonNull OperationContextExt context,              @NonNull Consumer<OperationContext> consumer) {          mSubscribers.put(context, consumer); @@ -254,6 +267,7 @@ public final class BiometricContextProvider implements BiometricContext {                  + "bp session: " + getBiometricPromptSessionInfo() + ", "                  + "displayState: " + getDisplayState() + ", "                  + "isAwake: " + isAwake() +  ", " +                + "isHardwareIgnoring: " + isHardwareIgnoringTouches() +  ", "                  + "isDisplayOn: " + isDisplayOn() +  ", "                  + "dock: " + getDockedState() + ", "                  + "rotation: " + getCurrentRotation() + ", " diff --git a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java index b4e0dff615f5..0045d44af9a1 100644 --- a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java +++ b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java @@ -20,12 +20,14 @@ import android.annotation.NonNull;  import android.annotation.Nullable;  import android.content.Intent;  import android.hardware.biometrics.AuthenticateOptions; +import android.hardware.biometrics.BiometricAuthenticator;  import android.hardware.biometrics.IBiometricContextListener;  import android.hardware.biometrics.common.AuthenticateReason;  import android.hardware.biometrics.common.DisplayState;  import android.hardware.biometrics.common.FoldState;  import android.hardware.biometrics.common.OperationContext;  import android.hardware.biometrics.common.OperationReason; +import android.hardware.biometrics.common.OperationState;  import android.hardware.biometrics.common.WakeReason;  import android.hardware.face.FaceAuthenticateOptions;  import android.hardware.fingerprint.FingerprintAuthenticateOptions; @@ -51,13 +53,26 @@ public class OperationContextExt {      /** Create a context. */      public OperationContextExt(boolean isBP) { -        this(new OperationContext(), isBP); +        this(new OperationContext(), isBP, BiometricAuthenticator.TYPE_NONE); +    } + +    public OperationContextExt(boolean isBP, @BiometricAuthenticator.Modality int modality) { +        this(new OperationContext(), isBP, modality);      }      /** Create a wrapped context. */ -    public OperationContextExt(@NonNull OperationContext context, boolean isBP) { +    public OperationContextExt(@NonNull OperationContext context, boolean isBP, +            @BiometricAuthenticator.Modality int modality) {          mAidlContext = context;          mIsBP = isBP; + +        if (modality == BiometricAuthenticator.TYPE_FINGERPRINT) { +            mAidlContext.operationState = OperationState.fingerprintOperationState( +                    new OperationState.FingerprintOperationState()); +        } else if (modality == BiometricAuthenticator.TYPE_FACE) { +            mAidlContext.operationState = OperationState.faceOperationState( +                    new OperationState.FaceOperationState()); +        }      }      /** @@ -247,12 +262,23 @@ public class OperationContextExt {          return mOrientation;      } +    /** The current operation state  */ +    public OperationState getOperationState() { +        return mAidlContext.operationState; +    } +      /** Update this object with the latest values from the given context. */      OperationContextExt update(@NonNull BiometricContext biometricContext, boolean isCrypto) {          mAidlContext.isAod = biometricContext.isAod();          mAidlContext.displayState = toAidlDisplayState(biometricContext.getDisplayState());          mAidlContext.foldState = toAidlFoldState(biometricContext.getFoldState());          mAidlContext.isCrypto = isCrypto; + +        if (mAidlContext.operationState != null && mAidlContext.operationState.getTag() +                == OperationState.fingerprintOperationState) { +            mAidlContext.operationState.getFingerprintOperationState().isHardwareIgnoringTouches = +                    biometricContext.isHardwareIgnoringTouches(); +        }          setFirstSessionId(biometricContext);          mIsDisplayOn = biometricContext.isDisplayOn(); diff --git a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java index 1a682a9ffefa..1fc7c70de8fb 100644 --- a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java +++ b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java @@ -41,22 +41,42 @@ import android.os.RemoteException;   * a common interface.   */  public class ClientMonitorCallbackConverter { -    private IBiometricSensorReceiver mSensorReceiver; // BiometricService -    private IFaceServiceReceiver mFaceServiceReceiver; // FaceManager -    private IFingerprintServiceReceiver mFingerprintServiceReceiver; // FingerprintManager +    private final IBiometricSensorReceiver mSensorReceiver; // BiometricService +    private final IFaceServiceReceiver mFaceServiceReceiver; // FaceManager +    private final IFingerprintServiceReceiver mFingerprintServiceReceiver; // FingerprintManager      public ClientMonitorCallbackConverter(IBiometricSensorReceiver sensorReceiver) {          mSensorReceiver = sensorReceiver; +        mFaceServiceReceiver = null; +        mFingerprintServiceReceiver = null;      }      public ClientMonitorCallbackConverter(IFaceServiceReceiver faceServiceReceiver) { +        mSensorReceiver = null;          mFaceServiceReceiver = faceServiceReceiver; +        mFingerprintServiceReceiver = null;      }      public ClientMonitorCallbackConverter(IFingerprintServiceReceiver fingerprintServiceReceiver) { +        mSensorReceiver = null; +        mFaceServiceReceiver = null;          mFingerprintServiceReceiver = fingerprintServiceReceiver;      } +    /** +     * Returns an int representing the {@link BiometricAuthenticator.Modality} of the active +     * ServiceReceiver +     */ +    @BiometricAuthenticator.Modality +    public int getModality() { +        if (mFaceServiceReceiver != null) { +            return BiometricAuthenticator.TYPE_FACE; +        } else if (mFingerprintServiceReceiver != null) { +            return BiometricAuthenticator.TYPE_FINGERPRINT; +        } +        return BiometricAuthenticator.TYPE_NONE; +    } +      // The following apply to all clients      public void onAcquired(int sensorId, int acquiredInfo, int vendorCode) throws RemoteException { diff --git a/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java b/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java index 03658ce21fc2..0f01510bd908 100644 --- a/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java +++ b/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java @@ -19,6 +19,7 @@ package com.android.server.biometrics.sensors;  import android.annotation.NonNull;  import android.annotation.Nullable;  import android.content.Context; +import android.hardware.biometrics.BiometricAuthenticator;  import android.os.IBinder;  import com.android.server.biometrics.log.BiometricContext; @@ -58,7 +59,8 @@ public abstract class HalClientMonitor<T> extends BaseClientMonitor {          super(context, token, listener, userId, owner, cookie, sensorId,                  biometricLogger, biometricContext);          mLazyDaemon = lazyDaemon; -        mOperationContext = new OperationContextExt(isBiometricPrompt()); +        int modality = listener != null ? listener.getModality() : BiometricAuthenticator.TYPE_NONE; +        mOperationContext = new OperationContextExt(isBiometricPrompt(), modality);      }      @Nullable diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java index 29c5a3de3a80..145885de5c32 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java @@ -28,6 +28,7 @@ import android.hardware.biometrics.BiometricFingerprintConstants;  import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;  import android.hardware.biometrics.BiometricManager.Authenticators;  import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.common.OperationState;  import android.hardware.biometrics.fingerprint.PointerContext;  import android.hardware.fingerprint.FingerprintAuthenticateOptions;  import android.hardware.fingerprint.FingerprintManager; @@ -326,6 +327,12 @@ public class FingerprintAuthenticationClient              if (session.hasContextMethods()) {                  try {                      session.getSession().onContextChanged(ctx); +                    // TODO(b/317414324): Deprecate setIgnoreDisplayTouches +                    if (ctx.operationState != null && ctx.operationState.getTag() +                            == OperationState.fingerprintOperationState) { +                        session.getSession().setIgnoreDisplayTouches( +                                ctx.operationState.getFingerprintOperationState().isHardwareIgnoringTouches); +                    }                  } catch (RemoteException e) {                      Slog.e(TAG, "Unable to notify context changed", e);                  } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java index e58e5ae117b5..3aab7b300a87 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java @@ -23,6 +23,7 @@ import android.annotation.Nullable;  import android.content.Context;  import android.hardware.biometrics.BiometricRequestConstants;  import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.common.OperationState;  import android.hardware.fingerprint.FingerprintAuthenticateOptions;  import android.hardware.fingerprint.IUdfpsOverlayController;  import android.os.IBinder; @@ -122,6 +123,12 @@ public class FingerprintDetectClient extends AcquisitionClient<AidlSession>              getBiometricContext().subscribe(opContext, ctx -> {                  try {                      session.getSession().onContextChanged(ctx); +                    // TODO(b/317414324): Deprecate setIgnoreDisplayTouches +                    if (ctx.operationState != null && ctx.operationState.getTag() +                            == OperationState.fingerprintOperationState) { +                        session.getSession().setIgnoreDisplayTouches( +                                ctx.operationState.getFingerprintOperationState().isHardwareIgnoringTouches); +                    }                  } catch (RemoteException e) {                      Slog.e(TAG, "Unable to notify context changed", e);                  } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java index c0761ed8f32b..bf5011de1e59 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java @@ -26,6 +26,7 @@ import android.hardware.biometrics.BiometricFingerprintConstants;  import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;  import android.hardware.biometrics.BiometricStateListener;  import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.common.OperationState;  import android.hardware.biometrics.fingerprint.PointerContext;  import android.hardware.fingerprint.Fingerprint;  import android.hardware.fingerprint.FingerprintManager; @@ -220,6 +221,12 @@ public class FingerprintEnrollClient extends EnrollClient<AidlSession> implement              getBiometricContext().subscribe(opContext, ctx -> {                  try {                      session.getSession().onContextChanged(ctx); +                    // TODO(b/317414324): Deprecate setIgnoreDisplayTouches +                    if (ctx.operationState != null && ctx.operationState.getTag() +                            == OperationState.fingerprintOperationState) { +                        session.getSession().setIgnoreDisplayTouches( +                                ctx.operationState.getFingerprintOperationState().isHardwareIgnoringTouches); +                    }                  } catch (RemoteException e) {                      Slog.e(TAG, "Unable to notify context changed", e);                  } diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java index 1b9e6fb6e247..a8eace05de97 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java @@ -153,6 +153,15 @@ public class BiometricContextProviderTest {      }      @Test +    public void testGetIsHardwareIgnoringTouches() throws RemoteException { +        mListener.onHardwareIgnoreTouchesChanged(true); +        assertThat(mProvider.isHardwareIgnoringTouches()).isTrue(); + +        mListener.onHardwareIgnoreTouchesChanged(false); +        assertThat(mProvider.isHardwareIgnoringTouches()).isFalse(); +    } + +    @Test      public void testGetDockedState() {          final List<Integer> states = List.of(Intent.EXTRA_DOCK_STATE_DESK,                  Intent.EXTRA_DOCK_STATE_CAR, Intent.EXTRA_DOCK_STATE_UNDOCKED); diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java index 5cff48dc3c2a..41193527503b 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java @@ -18,6 +18,7 @@ package com.android.server.biometrics.log;  import static com.google.common.truth.Truth.assertThat; +import android.hardware.biometrics.BiometricAuthenticator;  import android.hardware.biometrics.BiometricsProtoEnums;  import android.hardware.biometrics.common.AuthenticateReason;  import android.hardware.biometrics.common.OperationContext; @@ -48,11 +49,13 @@ public class BiometricFrameworkStatsLoggerTest {      public void testConvertsWakeReason_whenPowerReason() {          final OperationContext context = new OperationContext();          context.wakeReason = WakeReason.WAKE_MOTION; -        final OperationContextExt ctx = new OperationContextExt(context, false); +        final OperationContextExt ctx = new OperationContextExt(context, false, +                BiometricAuthenticator.TYPE_NONE);          final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);          final int[] reasonDetails = BiometricFrameworkStatsLogger -                .toProtoWakeReasonDetails(new OperationContextExt(context, false)); +                .toProtoWakeReasonDetails( +                        new OperationContextExt(context, false, BiometricAuthenticator.TYPE_NONE));          assertThat(reason).isEqualTo(BiometricsProtoEnums.WAKE_REASON_WAKE_MOTION);          assertThat(reasonDetails).isEmpty(); @@ -63,7 +66,8 @@ public class BiometricFrameworkStatsLoggerTest {          final OperationContext context = new OperationContext();          context.authenticateReason = AuthenticateReason.faceAuthenticateReason(                  AuthenticateReason.Face.ASSISTANT_VISIBLE); -        final OperationContextExt ctx = new OperationContextExt(context, false); +        final OperationContextExt ctx = new OperationContextExt(context, false, +                BiometricAuthenticator.TYPE_NONE);          final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);          final int[] reasonDetails = BiometricFrameworkStatsLogger @@ -79,7 +83,8 @@ public class BiometricFrameworkStatsLoggerTest {          final OperationContext context = new OperationContext();          context.authenticateReason = AuthenticateReason.vendorAuthenticateReason(                  new AuthenticateReason.Vendor()); -        final OperationContextExt ctx = new OperationContextExt(context, false); +        final OperationContextExt ctx = new OperationContextExt(context, false, +                BiometricAuthenticator.TYPE_NONE);          final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);          final int[] reasonDetails = BiometricFrameworkStatsLogger @@ -96,7 +101,8 @@ public class BiometricFrameworkStatsLoggerTest {          context.wakeReason = WakeReason.WAKE_KEY;          context.authenticateReason = AuthenticateReason.faceAuthenticateReason(                  AuthenticateReason.Face.PRIMARY_BOUNCER_SHOWN); -        final OperationContextExt ctx = new OperationContextExt(context, false); +        final OperationContextExt ctx = new OperationContextExt(context, false, +                BiometricAuthenticator.TYPE_NONE);          final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);          final int[] reasonDetails = BiometricFrameworkStatsLogger @@ -113,7 +119,8 @@ public class BiometricFrameworkStatsLoggerTest {          context.wakeReason = WakeReason.LID;          context.authenticateReason = AuthenticateReason.vendorAuthenticateReason(                  new AuthenticateReason.Vendor()); -        final OperationContextExt ctx = new OperationContextExt(context, false); +        final OperationContextExt ctx = new OperationContextExt(context, false, +                BiometricAuthenticator.TYPE_NONE);          final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);          final int[] reasonDetails = BiometricFrameworkStatsLogger diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java index 32284fd7541a..767b4262bb18 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java @@ -18,17 +18,19 @@ package com.android.server.biometrics.log;  import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.when; +  import android.content.Intent;  import android.hardware.biometrics.AuthenticateOptions; +import android.hardware.biometrics.BiometricAuthenticator;  import android.hardware.biometrics.IBiometricContextListener;  import android.hardware.biometrics.common.DisplayState;  import android.hardware.biometrics.common.OperationContext;  import android.hardware.biometrics.common.OperationReason; +import android.hardware.biometrics.common.OperationState;  import android.platform.test.annotations.Presubmit;  import android.view.Surface; -import static org.mockito.Mockito.when; -  import androidx.test.filters.SmallTest;  import com.android.internal.logging.InstanceId; @@ -58,7 +60,7 @@ public class OperationContextExtTest {          final OperationContext aidlContext = newAidlContext(); -        context = new OperationContextExt(aidlContext, false); +        context = new OperationContextExt(aidlContext, false, BiometricAuthenticator.TYPE_NONE);          assertThat(context.toAidlContext()).isSameInstanceAs(aidlContext);          final int id = 5; @@ -96,7 +98,8 @@ public class OperationContextExtTest {          );          for (Map.Entry<Integer, Integer> entry : map.entrySet()) { -            final OperationContextExt context = new OperationContextExt(newAidlContext(), true); +            final OperationContextExt context = new OperationContextExt(newAidlContext(), true, +                    BiometricAuthenticator.TYPE_NONE);              when(mBiometricContext.getDisplayState()).thenReturn(entry.getKey());              assertThat(context.update(mBiometricContext, context.isCrypto()).getDisplayState())                      .isEqualTo(entry.getValue()); @@ -124,7 +127,7 @@ public class OperationContextExtTest {          updatesFromSource(null, OperationReason.UNKNOWN);      } -    private  void updatesFromSource(BiometricContextSessionInfo sessionInfo, int sessionType) { +    private void updatesFromSource(BiometricContextSessionInfo sessionInfo, int sessionType) {          final int rotation = Surface.ROTATION_270;          final int foldState = IBiometricContextListener.FoldState.HALF_OPENED;          final int dockState = Intent.EXTRA_DOCK_STATE_CAR; @@ -135,9 +138,11 @@ public class OperationContextExtTest {          when(mBiometricContext.getDockedState()).thenReturn(dockState);          when(mBiometricContext.isDisplayOn()).thenReturn(true);          when(mBiometricContext.getDisplayState()).thenReturn(displayState); +        when(mBiometricContext.isHardwareIgnoringTouches()).thenReturn(true);          final OperationContextExt context = new OperationContextExt(newAidlContext(), -                sessionType == OperationReason.BIOMETRIC_PROMPT); +                sessionType == OperationReason.BIOMETRIC_PROMPT, +                BiometricAuthenticator.TYPE_FINGERPRINT);          assertThat(context.update(mBiometricContext, context.isCrypto())).isSameInstanceAs(context); @@ -154,6 +159,46 @@ public class OperationContextExtTest {          assertThat(context.getOrientation()).isEqualTo(rotation);          assertThat(context.isDisplayOn()).isTrue();          assertThat(context.getDisplayState()).isEqualTo(DisplayState.AOD); +        assertThat( +            context.getOperationState().getFingerprintOperationState().isHardwareIgnoringTouches +        ).isTrue(); +    } + +    @Test +    public void hasNullOperationState() { +        OperationContextExt context = new OperationContextExt(false); +        assertThat(context.toAidlContext()).isNotNull(); + +        final OperationContext aidlContext = newAidlContext(); + +        context = new OperationContextExt(aidlContext, false, BiometricAuthenticator.TYPE_NONE); +        assertThat(context.getOperationState()).isNull(); +    } + +    @Test +    public void hasFaceOperationState() { +        OperationContextExt context = new OperationContextExt(false); +        assertThat(context.toAidlContext()).isNotNull(); + +        final OperationContext aidlContext = newAidlContext(); + +        context = new OperationContextExt(aidlContext, false, +                BiometricAuthenticator.TYPE_FACE); +        assertThat(context.getOperationState().getTag()).isEqualTo( +                OperationState.faceOperationState); +    } + +    @Test +    public void hasFingerprintOperationState() { +        OperationContextExt context = new OperationContextExt(false); +        assertThat(context.toAidlContext()).isNotNull(); + +        final OperationContext aidlContext = newAidlContext(); + +        context = new OperationContextExt(aidlContext, false, +                BiometricAuthenticator.TYPE_FINGERPRINT); +        assertThat(context.getOperationState().getTag()).isEqualTo( +                OperationState.fingerprintOperationState);      }      private static OperationContext newAidlContext() { diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/AcquisitionClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/AcquisitionClientTest.java index 2d9d868f2f74..4604b310edf7 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/AcquisitionClientTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/AcquisitionClientTest.java @@ -72,6 +72,7 @@ public class AcquisitionClientTest {                  mToken, mClientCallback);          client.start(mSchedulerCallback);          assertTrue(client.mHalOperationRunning); +        verify(mClientCallback).getModality();          verify(mSchedulerCallback).onClientStarted(eq(client));          // Pretend that it got canceled by the user.  |