Move Process_PointerCapture to CursorInputMapper_test

This test will now be using the new test infra set up in
CursorInputMapper_test instead of the one in InputReader_test.

This specific test documents the behaviour of pointer capture - the
generation of ACTION_MOVE events during pointer capture, and the use of
SOURCE_MOUSE_RELATIVE.

Bug: 283812079
Test: atest inputflinger_tests
Change-Id: I87d707dfd418ab7d6203571a4acf7a090d247304
diff --git a/services/inputflinger/tests/CursorInputMapper_test.cpp b/services/inputflinger/tests/CursorInputMapper_test.cpp
index 6774b17..e630915 100644
--- a/services/inputflinger/tests/CursorInputMapper_test.cpp
+++ b/services/inputflinger/tests/CursorInputMapper_test.cpp
@@ -28,6 +28,7 @@
 
 namespace android {
 
+using testing::AllOf;
 using testing::Return;
 using testing::VariantWith;
 constexpr auto ACTION_DOWN = AMOTION_EVENT_ACTION_DOWN;
@@ -36,6 +37,7 @@
 constexpr auto BUTTON_PRESS = AMOTION_EVENT_ACTION_BUTTON_PRESS;
 constexpr auto BUTTON_RELEASE = AMOTION_EVENT_ACTION_BUTTON_RELEASE;
 constexpr auto HOVER_MOVE = AMOTION_EVENT_ACTION_HOVER_MOVE;
+constexpr auto INVALID_CURSOR_POSITION = AMOTION_EVENT_INVALID_CURSOR_POSITION;
 
 /**
  * Unit tests for CursorInputMapper.
@@ -58,10 +60,23 @@
         EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_HWHEEL))
                 .WillRepeatedly(Return(false));
 
-        EXPECT_CALL(mMockInputReaderContext, bumpGeneration()).WillRepeatedly(Return(1));
-
         mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);
     }
+
+    void setPointerCapture(bool enabled) {
+        mReaderConfiguration.pointerCaptureRequest.enable = enabled;
+        mReaderConfiguration.pointerCaptureRequest.seq = 1;
+        int32_t generation = mDevice->getGeneration();
+        std::list<NotifyArgs> args =
+                mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
+                                     InputReaderConfiguration::Change::POINTER_CAPTURE);
+        ASSERT_THAT(args,
+                    ElementsAre(
+                            VariantWith<NotifyDeviceResetArgs>(AllOf(WithDeviceId(DEVICE_ID)))));
+
+        // Check that generation also got bumped
+        ASSERT_GT(mDevice->getGeneration(), generation);
+    }
 };
 
 /**
@@ -102,4 +117,83 @@
                             VariantWith<NotifyMotionArgs>(WithMotionAction(HOVER_MOVE))));
 }
 
+/**
+ * Set pointer capture and check that ACTION_MOVE events are emitted from CursorInputMapper.
+ * During pointer capture, source should be set to MOUSE_RELATIVE. When the capture is disabled,
+ * the events should be generated normally:
+ *   1) The source should return to SOURCE_MOUSE
+ *   2) Cursor position should be incremented by the relative device movements
+ *   3) Cursor position of NotifyMotionArgs should now be getting populated.
+ * When it's not SOURCE_MOUSE, CursorInputMapper doesn't populate cursor position values.
+ */
+TEST_F(CursorInputMapperUnitTest, ProcessPointerCapture) {
+    setPointerCapture(true);
+    std::list<NotifyArgs> args;
+
+    // Move.
+    args += process(EV_REL, REL_X, 10);
+    args += process(EV_REL, REL_Y, 20);
+    args += process(EV_SYN, SYN_REPORT, 0);
+
+    ASSERT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                        AllOf(WithMotionAction(ACTION_MOVE),
+                              WithSource(AINPUT_SOURCE_MOUSE_RELATIVE), WithCoords(10.0f, 20.0f),
+                              WithCursorPosition(INVALID_CURSOR_POSITION,
+                                                 INVALID_CURSOR_POSITION)))));
+
+    // Button press.
+    args.clear();
+    args += process(EV_KEY, BTN_MOUSE, 1);
+    args += process(EV_SYN, SYN_REPORT, 0);
+    ASSERT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithMotionAction(ACTION_DOWN),
+                                          WithSource(AINPUT_SOURCE_MOUSE_RELATIVE),
+                                          WithCoords(0.0f, 0.0f), WithPressure(1.0f))),
+                            VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithMotionAction(BUTTON_PRESS),
+                                          WithSource(AINPUT_SOURCE_MOUSE_RELATIVE),
+                                          WithCoords(0.0f, 0.0f), WithPressure(1.0f)))));
+
+    // Button release.
+    args.clear();
+    args += process(EV_KEY, BTN_MOUSE, 0);
+    args += process(EV_SYN, SYN_REPORT, 0);
+    ASSERT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithMotionAction(BUTTON_RELEASE),
+                                          WithSource(AINPUT_SOURCE_MOUSE_RELATIVE),
+                                          WithCoords(0.0f, 0.0f), WithPressure(0.0f))),
+                            VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithMotionAction(ACTION_UP),
+                                          WithSource(AINPUT_SOURCE_MOUSE_RELATIVE),
+                                          WithCoords(0.0f, 0.0f), WithPressure(0.0f)))));
+
+    // Another move.
+    args.clear();
+    args += process(EV_REL, REL_X, 30);
+    args += process(EV_REL, REL_Y, 40);
+    args += process(EV_SYN, SYN_REPORT, 0);
+    ASSERT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                        AllOf(WithMotionAction(ACTION_MOVE),
+                              WithSource(AINPUT_SOURCE_MOUSE_RELATIVE),
+                              WithCoords(30.0f, 40.0f)))));
+
+    // Disable pointer capture. Afterwards, events should be generated the usual way.
+    setPointerCapture(false);
+
+    args.clear();
+    args += process(EV_REL, REL_X, 10);
+    args += process(EV_REL, REL_Y, 20);
+    args += process(EV_SYN, SYN_REPORT, 0);
+    ASSERT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                        AllOf(WithMotionAction(HOVER_MOVE), WithSource(AINPUT_SOURCE_MOUSE),
+                              WithCoords(INITIAL_CURSOR_X + 10.0f, INITIAL_CURSOR_Y + 20.0f),
+                              WithCursorPosition(INITIAL_CURSOR_X + 10.0f,
+                                                 INITIAL_CURSOR_Y + 20.0f)))));
+}
+
 } // namespace android
diff --git a/services/inputflinger/tests/InputMapperTest.cpp b/services/inputflinger/tests/InputMapperTest.cpp
index 0eee2b9..dac4ea0 100644
--- a/services/inputflinger/tests/InputMapperTest.cpp
+++ b/services/inputflinger/tests/InputMapperTest.cpp
@@ -27,7 +27,7 @@
 void InputMapperUnitTest::SetUp() {
     mFakePointerController = std::make_shared<FakePointerController>();
     mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
-    mFakePointerController->setPosition(400, 240);
+    mFakePointerController->setPosition(INITIAL_CURSOR_X, INITIAL_CURSOR_Y);
 
     EXPECT_CALL(mMockInputReaderContext, getPointerController(DEVICE_ID))
             .WillRepeatedly(Return(mFakePointerController));
diff --git a/services/inputflinger/tests/InputMapperTest.h b/services/inputflinger/tests/InputMapperTest.h
index 909bd9c..c2ac258 100644
--- a/services/inputflinger/tests/InputMapperTest.h
+++ b/services/inputflinger/tests/InputMapperTest.h
@@ -39,6 +39,8 @@
 protected:
     static constexpr int32_t EVENTHUB_ID = 1;
     static constexpr int32_t DEVICE_ID = END_RESERVED_ID + 1000;
+    static constexpr float INITIAL_CURSOR_X = 400;
+    static constexpr float INITIAL_CURSOR_Y = 240;
     virtual void SetUp() override;
 
     void setupAxis(int axis, bool valid, int32_t min, int32_t max, int32_t resolution);
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 6539593..6032e30 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -4744,92 +4744,6 @@
     ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(110.0f, 220.0f));
 }
 
-TEST_F(CursorInputMapperTest, Process_PointerCapture) {
-    addConfigurationProperty("cursor.mode", "pointer");
-    mFakePolicy->setPointerCapture(true);
-    CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
-
-    NotifyDeviceResetArgs resetArgs;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
-    ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
-
-    mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
-    mFakePointerController->setPosition(100, 200);
-
-    NotifyMotionArgs args;
-
-    // Move.
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            10.0f, 20.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(100.0f, 200.0f));
-
-    // Button press.
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    // Button release.
-    process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, BTN_MOUSE, 0);
-    process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    // Another move.
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 30);
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 40);
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            30.0f, 40.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(100.0f, 200.0f));
-
-    // Disable pointer capture and check that the device generation got bumped
-    // and events are generated the usual way.
-    const uint32_t generation = mReader->getContext()->getGeneration();
-    mFakePolicy->setPointerCapture(false);
-    configureDevice(InputReaderConfiguration::Change::POINTER_CAPTURE);
-    ASSERT_TRUE(mReader->getContext()->getGeneration() != generation);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
-    ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
-
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(110.0f, 220.0f));
-}
-
 /**
  * When Pointer Capture is enabled, we expect to report unprocessed relative movements, so any
  * pointer acceleration or speed processing should not be applied.
diff --git a/services/inputflinger/tests/InterfaceMocks.h b/services/inputflinger/tests/InterfaceMocks.h
index 5d50b94..05823cd 100644
--- a/services/inputflinger/tests/InterfaceMocks.h
+++ b/services/inputflinger/tests/InterfaceMocks.h
@@ -59,7 +59,7 @@
                 (int32_t deviceId), (override));
 
     MOCK_METHOD(void, requestTimeoutAtTime, (nsecs_t when), (override));
-    MOCK_METHOD(int32_t, bumpGeneration, (), (override));
+    int32_t bumpGeneration() override { return ++mGeneration; }
 
     MOCK_METHOD(void, getExternalStylusDevices, (std::vector<InputDeviceInfo> & outDevices),
                 (override));
@@ -76,6 +76,9 @@
 
     MOCK_METHOD(void, setPreventingTouchpadTaps, (bool prevent), (override));
     MOCK_METHOD(bool, isPreventingTouchpadTaps, (), (override));
+
+private:
+    int32_t mGeneration = 0;
 };
 
 class MockEventHubInterface : public EventHubInterface {
diff --git a/services/inputflinger/tests/TestInputListenerMatchers.h b/services/inputflinger/tests/TestInputListenerMatchers.h
index 183383f..31ad569 100644
--- a/services/inputflinger/tests/TestInputListenerMatchers.h
+++ b/services/inputflinger/tests/TestInputListenerMatchers.h
@@ -185,6 +185,14 @@
     return argX == x && argY == y;
 }
 
+MATCHER_P2(WithCursorPosition, x, y, "InputEvent with specified cursor position") {
+    const auto argX = arg.xCursorPosition;
+    const auto argY = arg.yCursorPosition;
+    *result_listener << "expected cursor position (" << x << ", " << y << "), but got (" << argX
+                     << ", " << argY << ")";
+    return (isnan(x) ? isnan(argX) : x == argX) && (isnan(y) ? isnan(argY) : y == argY);
+}
+
 MATCHER_P3(WithPointerCoords, pointer, x, y, "InputEvent with specified coords for pointer") {
     const auto argX = arg.pointerCoords[pointer].getX();
     const auto argY = arg.pointerCoords[pointer].getY();