Ensure new InputConsumer resampling behavior does not change

Added the last test from TouchResampling_test.cpp to
InputConsumerResampling_test.cpp. This should guarantee that the
resampling part of InputConsumer refactor remains consistent with the
legacy consumer.

Bug: 297226446
Flag: EXEMPT refactor
Test: atest
Change-Id: I69b59af8d63956d7cba42514d3420340ba93b842
diff --git a/libs/input/tests/InputConsumerResampling_test.cpp b/libs/input/tests/InputConsumerResampling_test.cpp
index a7feeeb..97688a8 100644
--- a/libs/input/tests/InputConsumerResampling_test.cpp
+++ b/libs/input/tests/InputConsumerResampling_test.cpp
@@ -38,6 +38,8 @@
 using std::chrono::nanoseconds;
 using namespace std::chrono_literals;
 
+const std::chrono::milliseconds RESAMPLE_LATENCY{5};
+
 struct Pointer {
     int32_t id{0};
     float x{0.0f};
@@ -440,7 +442,7 @@
             {20ms, {Pointer{.id = 0, .x = 30.0f, .y = 30.0f}}, AMOTION_EVENT_ACTION_MOVE}));
 
     invokeLooperCallback();
-    mConsumer->consumeBatchedInputEvents(nanoseconds{20ms + 5ms /*RESAMPLE_LATENCY*/}.count());
+    mConsumer->consumeBatchedInputEvents(nanoseconds{20ms + RESAMPLE_LATENCY}.count());
 
     // MotionEvent should not resampled because the resample time falls exactly on the existing
     // event time.
@@ -496,14 +498,15 @@
             {40ms, {Pointer{.id = 0, .x = 30.0f, .y = 30.0f}}, AMOTION_EVENT_ACTION_MOVE}));
 
     invokeLooperCallback();
-    mConsumer->consumeBatchedInputEvents(nanoseconds{45ms + 5ms /*RESAMPLE_LATENCY*/}.count());
+    mConsumer->consumeBatchedInputEvents(nanoseconds{45ms + RESAMPLE_LATENCY}.count());
+    // Original and resampled event should be both overwritten.
     assertReceivedMotionEvent(
             {InputEventEntry{40ms,
                              {Pointer{.id = 0, .x = 35.0f, .y = 30.0f, .isResampled = true}},
-                             AMOTION_EVENT_ACTION_MOVE}, // original event, rewritten
+                             AMOTION_EVENT_ACTION_MOVE},
              InputEventEntry{45ms,
                              {Pointer{.id = 0, .x = 35.0f, .y = 30.0f, .isResampled = true}},
-                             AMOTION_EVENT_ACTION_MOVE}}); // resampled event, rewritten
+                             AMOTION_EVENT_ACTION_MOVE}});
 
     mClientTestChannel->assertFinishMessage(/*seq=*/1, /*handled=*/true);
     mClientTestChannel->assertFinishMessage(/*seq=*/2, /*handled=*/true);
@@ -552,13 +555,14 @@
 
     invokeLooperCallback();
     mConsumer->consumeBatchedInputEvents(nanoseconds{50ms}.count());
+    // Original and resampled event should be both overwritten.
     assertReceivedMotionEvent(
             {InputEventEntry{24ms,
                              {Pointer{.id = 0, .x = 35.0f, .y = 30.0f, .isResampled = true}},
-                             AMOTION_EVENT_ACTION_MOVE}, // original event, rewritten
+                             AMOTION_EVENT_ACTION_MOVE},
              InputEventEntry{26ms,
                              {Pointer{.id = 0, .x = 45.0f, .y = 30.0f, .isResampled = true}},
-                             AMOTION_EVENT_ACTION_MOVE}}); // resampled event, rewritten
+                             AMOTION_EVENT_ACTION_MOVE}});
 
     mClientTestChannel->assertFinishMessage(/*seq=*/1, /*handled=*/true);
     mClientTestChannel->assertFinishMessage(/*seq=*/2, /*handled=*/true);
@@ -594,4 +598,147 @@
     mClientTestChannel->assertFinishMessage(/*seq=*/3, /*handled=*/true);
 }
 
+TEST_F(InputConsumerResamplingTest, TwoPointersAreResampledIndependently) {
+    // Full action for when a pointer with index=1 appears (some other pointer must already be
+    // present)
+    const int32_t actionPointer1Down =
+            AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
+
+    // Full action for when a pointer with index=0 disappears (some other pointer must still remain)
+    const int32_t actionPointer0Up =
+            AMOTION_EVENT_ACTION_POINTER_UP + (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
+
+    mClientTestChannel->enqueueMessage(nextPointerMessage(
+            {0ms, {Pointer{.id = 0, .x = 100.0f, .y = 100.0f}}, AMOTION_EVENT_ACTION_DOWN}));
+
+    mClientTestChannel->assertNoSentMessages();
+
+    invokeLooperCallback();
+    assertReceivedMotionEvent({InputEventEntry{0ms,
+                                               {Pointer{.id = 0, .x = 100.0f, .y = 100.0f}},
+                                               AMOTION_EVENT_ACTION_DOWN}});
+
+    mClientTestChannel->enqueueMessage(nextPointerMessage(
+            {10ms, {Pointer{.id = 0, .x = 100.0f, .y = 100.0f}}, AMOTION_EVENT_ACTION_MOVE}));
+
+    invokeLooperCallback();
+    mConsumer->consumeBatchedInputEvents(nanoseconds{10ms + RESAMPLE_LATENCY}.count());
+    // Not resampled value because requestedFrameTime - RESAMPLE_LATENCY == eventTime
+    assertReceivedMotionEvent({InputEventEntry{10ms,
+                                               {Pointer{.id = 0, .x = 100.0f, .y = 100.0f}},
+                                               AMOTION_EVENT_ACTION_MOVE}});
+
+    // Second pointer id=1 appears
+    mClientTestChannel->enqueueMessage(
+            nextPointerMessage({15ms,
+                                {Pointer{.id = 0, .x = 100.0f, .y = 100.0f},
+                                 Pointer{.id = 1, .x = 500.0f, .y = 500.0f}},
+                                actionPointer1Down}));
+
+    invokeLooperCallback();
+    mConsumer->consumeBatchedInputEvents(nanoseconds{20ms + RESAMPLE_LATENCY}.count());
+    // Not resampled value because requestedFrameTime - RESAMPLE_LATENCY == eventTime.
+    assertReceivedMotionEvent({InputEventEntry{15ms,
+                                               {Pointer{.id = 0, .x = 100.0f, .y = 100.0f},
+                                                Pointer{.id = 1, .x = 500.0f, .y = 500.0f}},
+                                               actionPointer1Down}});
+
+    // Both pointers move
+    mClientTestChannel->enqueueMessage(
+            nextPointerMessage({30ms,
+                                {Pointer{.id = 0, .x = 100.0f, .y = 100.0f},
+                                 Pointer{.id = 1, .x = 500.0f, .y = 500.0f}},
+                                AMOTION_EVENT_ACTION_MOVE}));
+    mClientTestChannel->enqueueMessage(
+            nextPointerMessage({40ms,
+                                {Pointer{.id = 0, .x = 120.0f, .y = 120.0f},
+                                 Pointer{.id = 1, .x = 600.0f, .y = 600.0f}},
+                                AMOTION_EVENT_ACTION_MOVE}));
+
+    invokeLooperCallback();
+    mConsumer->consumeBatchedInputEvents(nanoseconds{45ms + RESAMPLE_LATENCY}.count());
+    assertReceivedMotionEvent(
+            {InputEventEntry{30ms,
+                             {Pointer{.id = 0, .x = 100.0f, .y = 100.0f},
+                              Pointer{.id = 1, .x = 500.0f, .y = 500.0f}},
+                             AMOTION_EVENT_ACTION_MOVE},
+             InputEventEntry{40ms,
+                             {Pointer{.id = 0, .x = 120.0f, .y = 120.0f},
+                              Pointer{.id = 1, .x = 600.0f, .y = 600.0f}},
+                             AMOTION_EVENT_ACTION_MOVE},
+             InputEventEntry{45ms,
+                             {Pointer{.id = 0, .x = 130.0f, .y = 130.0f, .isResampled = true},
+                              Pointer{.id = 1, .x = 650.0f, .y = 650.0f, .isResampled = true}},
+                             AMOTION_EVENT_ACTION_MOVE}});
+
+    // Both pointers move again
+    mClientTestChannel->enqueueMessage(
+            nextPointerMessage({60ms,
+                                {Pointer{.id = 0, .x = 120.0f, .y = 120.0f},
+                                 Pointer{.id = 1, .x = 600.0f, .y = 600.0f}},
+                                AMOTION_EVENT_ACTION_MOVE}));
+    mClientTestChannel->enqueueMessage(
+            nextPointerMessage({70ms,
+                                {Pointer{.id = 0, .x = 130.0f, .y = 130.0f},
+                                 Pointer{.id = 1, .x = 700.0f, .y = 700.0f}},
+                                AMOTION_EVENT_ACTION_MOVE}));
+
+    invokeLooperCallback();
+    mConsumer->consumeBatchedInputEvents(nanoseconds{75ms + RESAMPLE_LATENCY}.count());
+
+    /*
+     * The pointer id 0 at t = 60 should not be equal to 120 because the value was received twice,
+     * and resampled to 130. Therefore, if we reported 130, then we should continue to report it as
+     * such. Likewise, with pointer id 1.
+     */
+
+    // Not 120 because it matches a previous real event.
+    assertReceivedMotionEvent(
+            {InputEventEntry{60ms,
+                             {Pointer{.id = 0, .x = 130.0f, .y = 130.0f, .isResampled = true},
+                              Pointer{.id = 1, .x = 650.0f, .y = 650.0f, .isResampled = true}},
+                             AMOTION_EVENT_ACTION_MOVE},
+             InputEventEntry{70ms,
+                             {Pointer{.id = 0, .x = 130.0f, .y = 130.0f},
+                              Pointer{.id = 1, .x = 700.0f, .y = 700.0f}},
+                             AMOTION_EVENT_ACTION_MOVE},
+             InputEventEntry{75ms,
+                             {Pointer{.id = 0, .x = 135.0f, .y = 135.0f, .isResampled = true},
+                              Pointer{.id = 1, .x = 750.0f, .y = 750.0f, .isResampled = true}},
+                             AMOTION_EVENT_ACTION_MOVE}});
+
+    // First pointer id=0 leaves the screen
+    mClientTestChannel->enqueueMessage(
+            nextPointerMessage({80ms,
+                                {Pointer{.id = 0, .x = 120.0f, .y = 120.0f},
+                                 Pointer{.id = 1, .x = 600.0f, .y = 600.0f}},
+                                actionPointer0Up}));
+
+    invokeLooperCallback();
+    // Not resampled event for ACTION_POINTER_UP
+    assertReceivedMotionEvent({InputEventEntry{80ms,
+                                               {Pointer{.id = 0, .x = 120.0f, .y = 120.0f},
+                                                Pointer{.id = 1, .x = 600.0f, .y = 600.0f}},
+                                               actionPointer0Up}});
+
+    // Remaining pointer id=1 is still present, but doesn't move
+    mClientTestChannel->enqueueMessage(nextPointerMessage(
+            {90ms, {Pointer{.id = 1, .x = 600.0f, .y = 600.0f}}, AMOTION_EVENT_ACTION_MOVE}));
+
+    invokeLooperCallback();
+    mConsumer->consumeBatchedInputEvents(nanoseconds{100ms}.count());
+
+    /*
+     * The latest event with ACTION_MOVE was at t = 70 with value = 700. Thus, the resampled value
+     * is 700 + ((95 - 70)/(90 - 70))*(600 - 700) = 575.
+     */
+    assertReceivedMotionEvent(
+            {InputEventEntry{90ms,
+                             {Pointer{.id = 1, .x = 600.0f, .y = 600.0f}},
+                             AMOTION_EVENT_ACTION_MOVE},
+             InputEventEntry{95ms,
+                             {Pointer{.id = 1, .x = 575.0f, .y = 575.0f, .isResampled = true}},
+                             AMOTION_EVENT_ACTION_MOVE}});
+}
+
 } // namespace android