Integrate isHardwareIgnoringTouches into OperationContext

Test: atest SystemUITests:com.android.systemui.biometrics
Bug: 313763144
Flag: None
Change-Id: Ic7597b6edfdad2b8c9d0d60588809b0e254e095c
diff --git a/core/java/android/hardware/biometrics/IBiometricContextListener.aidl b/core/java/android/hardware/biometrics/IBiometricContextListener.aidl
index 6ac6581..2f58f51 100644
--- a/core/java/android/hardware/biometrics/IBiometricContextListener.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricContextListener.aidl
@@ -38,4 +38,8 @@
     // 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 b0beab9..f7743e2 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.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 @@
     @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 @@
                 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 a59a4b8..90c3c14 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.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 @@
     @Mock
     private AlternateBouncerInteractor mAlternateBouncerInteractor;
     @Mock
+    private UdfpsOverlayInteractor mUdfpsOverlayInteractor;
+    @Mock
     private UdfpsKeyguardAccessibilityDelegate mUdfpsKeyguardAccessibilityDelegate;
     @Mock
     private SelectedUserInteractor mSelectedUserInteractor;
@@ -342,8 +345,8 @@
                 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 13b53a8..7d9c2f9 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.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 @@
     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 @@
                 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 335ac9d..0e257bc 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.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.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.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 @@
                     repository = transitionRepository,
                 )
                 .keyguardTransitionInteractor
+        mUdfpsOverlayInteractor =
+            UdfpsOverlayInteractor(
+                context,
+                mock(AuthController::class.java),
+                mock(SelectedUserInteractor::class.java),
+                testScope.backgroundScope,
+            )
         return createUdfpsKeyguardViewController(/* useModernBouncer */ true)
     }
 
@@ -239,6 +250,31 @@
         }
 
     @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 7d9ec08..f5603ed 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.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 @@
     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 @@
     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 @@
     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 e7b0d9f..e0455b5 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 @@
     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 81de0a2..66fe4b3 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.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 @@
     @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 @@
                         mSelectedUserInteractor,
                         mDeviceEntryUdfpsTouchOverlayViewModel,
                         mDefaultUdfpsTouchOverlayViewModel,
-                        mShadeInteractor
+                        mShadeInteractor,
+                        mUdfpsOverlayInteractor
                     )));
         }
 
@@ -674,7 +677,8 @@
             @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 @@
         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 b94a177..4176083 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.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 @@
     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 @@
                     statusBarStateController,
                     shadeInteractor,
                     dialogManager,
-                    dumpManager
+                    dumpManager,
+                    udfpsOverlayInteractor,
                 )
             }
             REASON_AUTH_KEYGUARD -> {
@@ -306,6 +309,7 @@
                     selectedUserInteractor,
                     transitionInteractor,
                     shadeInteractor,
+                    udfpsOverlayInteractor,
                 )
             }
             REASON_AUTH_BP -> {
@@ -315,7 +319,8 @@
                     statusBarStateController,
                     shadeInteractor,
                     dialogManager,
-                    dumpManager
+                    dumpManager,
+                    udfpsOverlayInteractor,
                 )
             }
             REASON_AUTH_OTHER,
@@ -325,7 +330,8 @@
                     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 ab3fbb1..cfbbc26 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 @@
     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 9f17024..7020d05 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.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 @@
     private val selectedUserInteractor: SelectedUserInteractor,
     private val transitionInteractor: KeyguardTransitionInteractor,
     shadeInteractor: ShadeInteractor,
+    udfpsOverlayInteractor: UdfpsOverlayInteractor,
 ) :
     UdfpsAnimationViewController<UdfpsKeyguardViewLegacy>(
         view,
@@ -82,6 +84,7 @@
         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 863ba8d..70be0f2 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 @@
     /** 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 @@
     @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 @@
             }
         }
 
+    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 @@
                 .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 f4a2811..4fc1b58 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 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 @@
         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 647dae6..13306be 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 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 @@
     @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 @@
                 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 8f8004f..b1e471a 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.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_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 @@
     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 @@
     @Before
     fun setup() {
         keyguardTransitionRepository = FakeKeyguardTransitionRepository()
+        udfpsOverlayInteractor =
+            UdfpsOverlayInteractor(
+                context,
+                authController,
+                selectedUserInteractor,
+                testScope.backgroundScope,
+            )
         interactor =
             LogContextInteractorImpl(
                 testScope.backgroundScope,
@@ -59,6 +71,7 @@
                         scope = testScope.backgroundScope,
                     )
                     .keyguardTransitionInteractor,
+                udfpsOverlayInteractor,
             )
     }
 
@@ -162,6 +175,18 @@
         }
 
     @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 @@
 
             var folded: Int? = null
             var displayState: Int? = null
+            var ignoreTouches: Boolean? = null
             val job =
                 interactor.addBiometricContextListener(
                     object : IBiometricContextListener.Stub() {
@@ -205,12 +231,17 @@
                         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 @@
             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 6a68672..c0e108e 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 @@
     @Test
     fun testShouldInterceptTouch() =
         testScope.runTest {
-            createUdpfsOverlayInteractor()
+            createUdfpsOverlayInteractor()
 
             // When fingerprint enrolled and touch is within bounds
             verify(authController).addCallback(authControllerCallback.capture())
@@ -92,7 +92,7 @@
     @Test
     fun testUdfpsOverlayParamsChange() =
         testScope.runTest {
-            createUdpfsOverlayInteractor()
+            createUdfpsOverlayInteractor()
             val udfpsOverlayParams = collectLastValue(underTest.udfpsOverlayParams)
             runCurrent()
 
@@ -105,7 +105,7 @@
             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 3dcea19..f8a9867 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 @@
     @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 95a047f..535b7b7 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 @@
     @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 @@
                         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 @@
     }
 
     @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 @@
                 + "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 b4e0dff..0045d44 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.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 @@
 
     /** 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 @@
         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 1a682a9..1fc7c70 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 @@
  * 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 03658ce..0f01510 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 @@
 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 @@
         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 29c5a3d..145885d 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.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 @@
             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 e58e5ae..3aab7b3 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.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 @@
             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 c0761ed..bf5011d 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.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 @@
             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 1b9e6fb..a8eace0 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 @@
     }
 
     @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 5cff48d..4119352 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 @@
 
 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 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 @@
         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 @@
         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 @@
         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 @@
         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 32284fd..767b426 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 @@
 
 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 @@
 
         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 @@
         );
 
         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 @@
         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 @@
         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 @@
         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 2d9d868..4604b31 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 @@
                 mToken, mClientCallback);
         client.start(mSchedulerCallback);
         assertTrue(client.mHalOperationRunning);
+        verify(mClientCallback).getModality();
         verify(mSchedulerCallback).onClientStarted(eq(client));
 
         // Pretend that it got canceled by the user.