diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
index 94b5fb2861b1179fb054d1161c78c71b0c15a823..21451dc0ffdf5106a2693ac6e3b35507228e5821 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
@@ -58,6 +58,7 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>(
         // Notification shade can be expanded but not visible (fraction: 0.0), for example
         // when a heads-up notification (HUN) is showing.
         notificationShadeVisible = event.expanded && event.fraction > 0f
+        notificationShadeTracking = event.tracking
         view.onExpansionChanged(event.fraction)
         updatePauseAuth()
     }
@@ -65,6 +66,9 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>(
     /** If the notification shade is visible. */
     var notificationShadeVisible: Boolean = false
 
+    /** If the notification shade is currently being dragged */
+    var notificationShadeTracking: Boolean = false
+
     /**
      * The amount of translation needed if the view currently requires the user to touch
      * somewhere other than the exact center of the sensor. For example, this can happen
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt
index 802eea300bd4b146407587be57024968d49ad850..96354c2a99ff48eff998a8d52c8ae15cd7a581fe 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.internal.annotations.VisibleForTesting
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.shade.ShadeExpansionStateManager
@@ -39,6 +40,12 @@ class UdfpsBpViewController(
     override val tag = "UdfpsBpViewController"
 
     override fun shouldPauseAuth(): Boolean {
-        return false
+        // Do not auth while notification shade is being dragged
+        return notificationShadeTracking
+    }
+
+    @VisibleForTesting
+    public override fun onViewAttached() {
+        super.onViewAttached()
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index a36870346b9ad4e1a069a0d8999968ab748a9b59..c29f884c848dc5286cb55c26b20ce24bcd855e10 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -549,8 +549,12 @@ public class UdfpsController implements DozeReceiver, Dumpable {
             Log.e(TAG, "ignoring the touch injected from outside of UdfpsView");
             return false;
         }
-        if (mOverlay == null) {
-            Log.w(TAG, "ignoring onTouch with null overlay");
+        if (mOverlay == null || mOverlay.getAnimationViewController() == null) {
+            Log.w(TAG, "ignoring onTouch with null overlay or animation view controller");
+            return false;
+        }
+        if (mOverlay.getAnimationViewController().shouldPauseAuth()) {
+            Log.w(TAG, "ignoring onTouch with shouldPauseAuth = true");
             return false;
         }
         if (!mOverlay.matchesRequestId(requestId)) {
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 7de78a60b73e5f62226be204b2f968e4922b4b98..9be3d820105375e9e0771a0a6dff10478e498d24 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt
@@ -23,14 +23,19 @@ import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.shade.ShadeExpansionChangeEvent
 import com.android.systemui.shade.ShadeExpansionStateManager
 import com.android.systemui.statusbar.phone.SystemUIDialogManager
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.mockito.withArgCaptor
 import org.junit.Assert.assertFalse
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
+import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
 
 @SmallTest
@@ -51,6 +56,8 @@ class UdfpsBpViewControllerTest : SysuiTestCase() {
 
     @Before
     fun setup() {
+        whenever(shadeExpansionStateManager.addExpansionListener(any()))
+            .thenReturn(ShadeExpansionChangeEvent(0f, false, false, 0f))
         udfpsBpViewController =
             UdfpsBpViewController(
                 udfpsBpView,
@@ -62,7 +69,32 @@ class UdfpsBpViewControllerTest : SysuiTestCase() {
     }
 
     @Test
-    fun testShouldNeverPauseAuth() {
+    fun testPauseAuthWhenNotificationShadeDragging() {
+        udfpsBpViewController.onViewAttached()
+        val shadeExpansionListener = withArgCaptor {
+            verify(shadeExpansionStateManager).addExpansionListener(capture())
+        }
+
+        // When shade is tracking, should pause auth
+        shadeExpansionListener.onPanelExpansionChanged(
+            ShadeExpansionChangeEvent(
+                fraction = 0f,
+                expanded = false,
+                tracking = true,
+                dragDownPxAmount = 10f
+            )
+        )
+        assert(udfpsBpViewController.shouldPauseAuth())
+
+        // When shade is not tracking, don't pause auth even if expanded
+        shadeExpansionListener.onPanelExpansionChanged(
+            ShadeExpansionChangeEvent(
+                fraction = 0f,
+                expanded = true,
+                tracking = false,
+                dragDownPxAmount = 10f
+            )
+        )
         assertFalse(udfpsBpViewController.shouldPauseAuth())
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index e56b5c7406b60324964e05f41e32d6af825d91d7..7dd88b437f1767c8726f9e1b9cd2546502268e6f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -207,6 +207,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
     private final UdfpsAnimationViewController mUdfpsKeyguardViewController =
             mock(UdfpsKeyguardViewControllerLegacy.class);
     @Mock
+    private UdfpsAnimationViewController mUdfpsAnimationViewController;
+    @Mock
     private SystemUIDialogManager mSystemUIDialogManager;
     @Mock
     private ActivityLaunchAnimator mActivityLaunchAnimator;
@@ -267,6 +269,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
         when(mSessionTracker.getSessionId(anyInt())).thenReturn(
                 (new InstanceIdSequence(1 << 20)).newInstanceId());
         when(mUdfpsView.getViewRootImpl()).thenReturn(mViewRootImpl);
+        when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsAnimationViewController);
 
         final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
         componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
@@ -1379,6 +1382,50 @@ public class UdfpsControllerTest extends SysuiTestCase {
         downEvent.recycle();
     }
 
+    @Test
+    public void onTouch_withNewTouchDetection_ignoreIfAuthPaused() throws RemoteException {
+        final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L,
+                0L);
+        final TouchProcessorResult processorResultDown =
+                new TouchProcessorResult.ProcessedTouch(InteractionEvent.DOWN,
+                        1 /* pointerId */, touchData);
+
+        // Enable new touch detection.
+        when(mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)).thenReturn(true);
+
+        // Configure UdfpsController to use FingerprintManager as opposed to AlternateTouchProvider.
+        initUdfpsController(mOpticalProps, false /* hasAlternateTouchProvider */);
+
+        // Configure UdfpsView to not accept the ACTION_DOWN event
+        when(mUdfpsView.isDisplayConfigured()).thenReturn(true);
+        when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
+
+        // GIVEN that auth is paused
+        when(mUdfpsAnimationViewController.shouldPauseAuth()).thenReturn(true);
+
+        // GIVEN that the overlay is showing and a11y touch exploration NOT enabled
+        when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
+        mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
+                BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
+        mFgExecutor.runAllReady();
+
+        verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
+
+        // WHEN ACTION_DOWN is received and touch is within sensor
+        when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn(
+                processorResultDown);
+        MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
+        mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
+        mBiometricExecutor.runAllReady();
+        downEvent.recycle();
+
+        // THEN the touch is ignored
+        verify(mInputManager, never()).pilferPointers(any());
+        verify(mFingerprintManager, never()).onPointerDown(anyLong(), anyInt(), anyInt(),
+                anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyLong(), anyLong(),
+                anyBoolean());
+    }
+
     @Test
     public void onTouch_withNewTouchDetection_pilferPointer() throws RemoteException {
         final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L,