Add TouchIntegrationTest tests
Base on InputReaderIntegrationTest which would test the threading
functionality. This would emulate the touch screen device and
send the raw events to verify if InputListener could really
receive the MotionEvent.
- Add tests for handling single touch and multi touch.
- Add test for handling MT_TOOL_PALM.
Bug: 117933934
Test: atest TouchIntegrationTest
Change-Id: I450c0159ac60d7da0471235407b3c537ab94fa6f
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 3ae8b56..618aefc 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -1748,7 +1748,7 @@
virtual void SetUp() override {
mFakePolicy = new FakeInputReaderPolicy();
- mTestListener = new TestInputListener();
+ mTestListener = new TestInputListener(50ms);
mReader = new InputReader(std::make_shared<EventHub>(), mFakePolicy, mTestListener);
ASSERT_EQ(mReader->start(), OK);
@@ -1847,6 +1847,135 @@
ASSERT_LE(prevTimestamp, keyArgs.eventTime);
}
+// --- TouchProcessTest ---
+class TouchIntegrationTest : public InputReaderIntegrationTest {
+protected:
+ static const int32_t FIRST_SLOT = 0;
+ static const int32_t SECOND_SLOT = 1;
+ static const int32_t FIRST_TRACKING_ID = 0;
+ static const int32_t SECOND_TRACKING_ID = 1;
+ const std::string UNIQUE_ID = "local:0";
+
+ virtual void SetUp() override {
+ InputReaderIntegrationTest::SetUp();
+ // At least add an internal display.
+ setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
+ DISPLAY_ORIENTATION_0, UNIQUE_ID, NO_PORT,
+ ViewportType::VIEWPORT_INTERNAL);
+
+ mDevice = createUinputDevice<UinputTouchScreen>(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT));
+ ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
+ }
+
+ void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
+ int32_t orientation, const std::string& uniqueId,
+ std::optional<uint8_t> physicalPort,
+ ViewportType viewportType) {
+ mFakePolicy->addDisplayViewport(displayId, width, height, orientation, uniqueId,
+ physicalPort, viewportType);
+ mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+ }
+
+ std::unique_ptr<UinputTouchScreen> mDevice;
+};
+
+TEST_F(TouchIntegrationTest, InputEvent_ProcessSingleTouch) {
+ NotifyMotionArgs args;
+ const Point centerPoint = mDevice->getCenterPoint();
+
+ // ACTION_DOWN
+ mDevice->sendDown(centerPoint);
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
+
+ // ACTION_MOVE
+ mDevice->sendMove(centerPoint + Point(1, 1));
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
+
+ // ACTION_UP
+ mDevice->sendUp();
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
+}
+
+TEST_F(TouchIntegrationTest, InputEvent_ProcessMultiTouch) {
+ NotifyMotionArgs args;
+ const Point centerPoint = mDevice->getCenterPoint();
+
+ // ACTION_DOWN
+ mDevice->sendDown(centerPoint);
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
+
+ // ACTION_POINTER_DOWN (Second slot)
+ const Point secondPoint = centerPoint + Point(100, 100);
+ mDevice->sendSlot(SECOND_SLOT);
+ mDevice->sendTrackingId(SECOND_TRACKING_ID);
+ mDevice->sendDown(secondPoint + Point(1, 1));
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ args.action);
+
+ // ACTION_MOVE (Second slot)
+ mDevice->sendMove(secondPoint);
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
+
+ // ACTION_POINTER_UP (Second slot)
+ mDevice->sendUp();
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ args.action);
+
+ // ACTION_UP
+ mDevice->sendSlot(FIRST_SLOT);
+ mDevice->sendUp();
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
+}
+
+TEST_F(TouchIntegrationTest, InputEvent_ProcessPalm) {
+ NotifyMotionArgs args;
+ const Point centerPoint = mDevice->getCenterPoint();
+
+ // ACTION_DOWN
+ mDevice->sendDown(centerPoint);
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
+
+ // ACTION_POINTER_DOWN (Second slot)
+ const Point secondPoint = centerPoint + Point(100, 100);
+ mDevice->sendSlot(SECOND_SLOT);
+ mDevice->sendTrackingId(SECOND_TRACKING_ID);
+ mDevice->sendDown(secondPoint);
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ args.action);
+
+ // ACTION_MOVE (Second slot)
+ mDevice->sendMove(secondPoint + Point(1, 1));
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
+
+ // Send MT_TOOL_PALM, which indicates that the touch IC has determined this to be a grip event.
+ // Expect to receive ACTION_CANCEL, to abort the entire gesture.
+ mDevice->sendToolType(MT_TOOL_PALM);
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, args.action);
+
+ // ACTION_POINTER_UP (Second slot)
+ mDevice->sendUp();
+
+ // ACTION_UP
+ mDevice->sendSlot(FIRST_SLOT);
+ mDevice->sendUp();
+
+ // Expect no event received after abort the entire gesture.
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
+}
+
// --- InputDeviceTest ---
class InputDeviceTest : public testing::Test {
protected:
@@ -7032,5 +7161,4 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
}
-
} // namespace android