Only pilfer once in InputSession.

This change modifies the behavior of InputSession to only pilfer
motion events once.

Fixes: 333596426
Test: atest InputSessionTest#testPilferOnce
Flag: ACONFIG com.android.systemui.dream_input_session_pilfer_once DISABLED
Change-Id: Ied60cbabcb4bed53f9ec77e580d722338f4de448
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 15c31d5..94fd991 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -760,4 +760,14 @@
   metadata {
     purpose: PURPOSE_BUGFIX
   }
-}
\ No newline at end of file
+}
+
+flag {
+    name: "dream_input_session_pilfer_once"
+    namespace: "systemui"
+    description: "Pilfer at most once per input session"
+    bug: "324600132"
+    metadata {
+      purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/InputSession.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/InputSession.java
index e72839f..cddba04 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/InputSession.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/InputSession.java
@@ -23,6 +23,7 @@
 import android.view.GestureDetector;
 import android.view.MotionEvent;
 
+import com.android.systemui.Flags;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.shared.system.InputChannelCompat;
 import com.android.systemui.shared.system.InputMonitorCompat;
@@ -41,6 +42,12 @@
     private final InputChannelCompat.InputEventReceiver mInputEventReceiver;
     private final GestureDetector mGestureDetector;
 
+    // Pilfering is a destructive operation. Once pilfering starts, the all events will be captured
+    // by the associated monitor. We track whether we're pilfering since initiating pilfering
+    // requires reaching out to the InputManagerService, which can be a heavy operation. This is
+    // especially costly if this is happening on a continuous stream of motion events.
+    private boolean mPilfering;
+
     /**
      * Default session constructor.
      * @param inputMonitor Input monitor to track input events.
@@ -70,7 +77,9 @@
 
                     if (ev instanceof MotionEvent
                             && mGestureDetector.onTouchEvent((MotionEvent) ev)
-                            && pilferOnGestureConsume) {
+                            && pilferOnGestureConsume
+                            && !(mPilfering && Flags.dreamInputSessionPilferOnce())) {
+                        mPilfering = true;
                         mInputMonitor.pilferPointers();
                     }
                 });
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/InputSessionTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/InputSessionTest.java
index 3180e75..8685384 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/InputSessionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/InputSessionTest.java
@@ -19,9 +19,11 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.platform.test.annotations.EnableFlags;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.Choreographer;
@@ -31,6 +33,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.shared.system.InputChannelCompat;
 import com.android.systemui.shared.system.InputMonitorCompat;
@@ -127,6 +130,18 @@
         verify(mInputMonitor, never()).pilferPointers();
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_DREAM_INPUT_SESSION_PILFER_ONCE)
+    public void testPilferOnce() {
+        createSession(true);
+        final MotionEvent event = Mockito.mock(MotionEvent.class);
+        when(mGestureDetector.onTouchEvent(event)).thenReturn(true);
+        mEventListener.onInputEvent(event);
+        mEventListener.onInputEvent(event);
+        verify(mInputEventListener, times(2)).onInputEvent(eq(event));
+        verify(mInputMonitor, times(1)).pilferPointers();
+    }
+
     /**
      * Ensures components are properly disposed.
      */