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.
*/