Loading services/inputflinger/tests/InputReader_test.cpp +130 −2 Original line number Diff line number Diff line Loading @@ -1748,7 +1748,7 @@ protected: 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); Loading Loading @@ -1847,6 +1847,135 @@ TEST_F(InputReaderIntegrationTest, SendsEventsToInputListener) { 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: Loading Loading @@ -7032,5 +7161,4 @@ TEST_F(MultiTouchInputMapperTest_ExternalDevice, Viewports_Fallback) { ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId); } } // namespace android services/inputflinger/tests/TestInputListener.cpp +5 −14 Original line number Diff line number Diff line Loading @@ -19,20 +19,11 @@ #include "TestInputListener.h" namespace { using std::chrono_literals::operator""ms; // Timeout for waiting for an expected event static constexpr std::chrono::duration WAIT_TIMEOUT = 5ms; } // namespace namespace android { // --- TestInputListener --- TestInputListener::TestInputListener() { } TestInputListener::TestInputListener(const std::chrono::milliseconds timeout) : mTimeout(timeout) {} TestInputListener::~TestInputListener() { } Loading Loading @@ -95,9 +86,9 @@ void TestInputListener::assertCalled(NotifyArgsType* outEventArgs, std::string m std::vector<NotifyArgsType>& queue = std::get<std::vector<NotifyArgsType>>(mQueues); if (queue.empty()) { const bool eventReceived = mCondition.wait_for(lock, WAIT_TIMEOUT, [&queue]() REQUIRES(mLock) { return !queue.empty(); }); const bool eventReceived = mCondition.wait_for(lock, mTimeout, [&queue]() REQUIRES(mLock) { return !queue.empty(); }); if (!eventReceived) { FAIL() << "Timed out waiting for event: " << message.c_str(); } Loading @@ -114,7 +105,7 @@ void TestInputListener::assertNotCalled(std::string message) { base::ScopedLockAssertion assumeLocked(mLock); std::vector<NotifyArgsType>& queue = std::get<std::vector<NotifyArgsType>>(mQueues); const bool eventReceived = mCondition.wait_for(lock, WAIT_TIMEOUT, [&queue]() REQUIRES(mLock) { const bool eventReceived = mCondition.wait_for(lock, mTimeout, [&queue]() REQUIRES(mLock) { return !queue.empty(); }); if (eventReceived) { Loading services/inputflinger/tests/TestInputListener.h +4 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ #include <gtest/gtest.h> #include "InputListener.h" using std::chrono_literals::operator""ms; namespace android { // --- TestInputListener --- Loading @@ -30,7 +32,7 @@ protected: virtual ~TestInputListener(); public: TestInputListener(); TestInputListener(const std::chrono::milliseconds timeout = 5ms); void assertNotifyConfigurationChangedWasCalled( NotifyConfigurationChangedArgs* outEventArgs = nullptr); Loading Loading @@ -73,6 +75,7 @@ private: std::mutex mLock; std::condition_variable mCondition; const std::chrono::milliseconds mTimeout; std::tuple<std::vector<NotifyConfigurationChangedArgs>, // std::vector<NotifyDeviceResetArgs>, // Loading services/inputflinger/tests/UinputDevice.cpp +68 −1 Original line number Diff line number Diff line Loading @@ -127,4 +127,71 @@ void UinputHomeKey::pressAndReleaseHomeKey() { EXPECT_NO_FATAL_FAILURE(pressAndReleaseKey(KEY_HOME)); } // --- UinputTouchScreen --- UinputTouchScreen::UinputTouchScreen(const Rect* size) : UinputDevice(UinputTouchScreen::DEVICE_NAME), mSize(*size) {} void UinputTouchScreen::configureDevice(int fd, uinput_user_dev* device) { // Setup the touch screen device ioctl(fd, UI_SET_EVBIT, EV_KEY); ioctl(fd, UI_SET_EVBIT, EV_REL); ioctl(fd, UI_SET_EVBIT, EV_ABS); ioctl(fd, UI_SET_ABSBIT, ABS_MT_SLOT); ioctl(fd, UI_SET_ABSBIT, ABS_MT_TOUCH_MAJOR); ioctl(fd, UI_SET_ABSBIT, ABS_MT_POSITION_X); ioctl(fd, UI_SET_ABSBIT, ABS_MT_POSITION_Y); ioctl(fd, UI_SET_ABSBIT, ABS_MT_TRACKING_ID); ioctl(fd, UI_SET_ABSBIT, ABS_MT_TOOL_TYPE); ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT); ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH); device->absmin[ABS_MT_SLOT] = RAW_SLOT_MIN; device->absmax[ABS_MT_SLOT] = RAW_SLOT_MAX; device->absmin[ABS_MT_TOUCH_MAJOR] = RAW_TOUCH_MIN; device->absmax[ABS_MT_TOUCH_MAJOR] = RAW_TOUCH_MAX; device->absmin[ABS_MT_POSITION_X] = mSize.left; device->absmax[ABS_MT_POSITION_X] = mSize.right - 1; device->absmin[ABS_MT_POSITION_Y] = mSize.top; device->absmax[ABS_MT_POSITION_Y] = mSize.bottom - 1; device->absmin[ABS_MT_TRACKING_ID] = RAW_ID_MIN; device->absmax[ABS_MT_TRACKING_ID] = RAW_ID_MAX; } void UinputTouchScreen::sendSlot(int32_t slot) { EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_SLOT, slot)); } void UinputTouchScreen::sendTrackingId(int32_t trackingId) { EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_TRACKING_ID, trackingId)); } void UinputTouchScreen::sendDown(const Point& point) { EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, BTN_TOUCH, 1)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0)); } void UinputTouchScreen::sendMove(const Point& point) { EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0)); } void UinputTouchScreen::sendUp() { sendTrackingId(0xffffffff); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, BTN_TOUCH, 0)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0)); } void UinputTouchScreen::sendToolType(int32_t toolType) { EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_TOOL_TYPE, toolType)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0)); } // Get the center x, y base on the range definition. const Point UinputTouchScreen::getCenterPoint() { return Point(mSize.left + mSize.width() / 2, mSize.top + mSize.height() / 2); } } // namespace android services/inputflinger/tests/UinputDevice.h +36 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ #include <inttypes.h> #include <linux/uinput.h> #include <log/log.h> #include <ui/Point.h> #include <ui/Rect.h> #include <memory> Loading Loading @@ -106,6 +108,40 @@ private: UinputHomeKey(); }; // --- UinputTouchScreen --- // A touch screen device with specific size. class UinputTouchScreen : public UinputDevice { public: static constexpr const char* DEVICE_NAME = "Test Touch Screen"; static const int32_t RAW_TOUCH_MIN = 0; static const int32_t RAW_TOUCH_MAX = 31; static const int32_t RAW_ID_MIN = 0; static const int32_t RAW_ID_MAX = 9; static const int32_t RAW_SLOT_MIN = 0; static const int32_t RAW_SLOT_MAX = 9; static const int32_t RAW_PRESSURE_MIN = 0; static const int32_t RAW_PRESSURE_MAX = 255; template <class D, class... Ts> friend std::unique_ptr<D> createUinputDevice(Ts... args); void sendSlot(int32_t slot); void sendTrackingId(int32_t trackingId); void sendDown(const Point& point); void sendMove(const Point& point); void sendUp(); void sendToolType(int32_t toolType); const Point getCenterPoint(); protected: UinputTouchScreen(const Rect* size); private: void configureDevice(int fd, uinput_user_dev* device) override; const Rect mSize; }; } // namespace android #endif // _UI_TEST_INPUT_UINPUT_INJECTOR_H Loading
services/inputflinger/tests/InputReader_test.cpp +130 −2 Original line number Diff line number Diff line Loading @@ -1748,7 +1748,7 @@ protected: 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); Loading Loading @@ -1847,6 +1847,135 @@ TEST_F(InputReaderIntegrationTest, SendsEventsToInputListener) { 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: Loading Loading @@ -7032,5 +7161,4 @@ TEST_F(MultiTouchInputMapperTest_ExternalDevice, Viewports_Fallback) { ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId); } } // namespace android
services/inputflinger/tests/TestInputListener.cpp +5 −14 Original line number Diff line number Diff line Loading @@ -19,20 +19,11 @@ #include "TestInputListener.h" namespace { using std::chrono_literals::operator""ms; // Timeout for waiting for an expected event static constexpr std::chrono::duration WAIT_TIMEOUT = 5ms; } // namespace namespace android { // --- TestInputListener --- TestInputListener::TestInputListener() { } TestInputListener::TestInputListener(const std::chrono::milliseconds timeout) : mTimeout(timeout) {} TestInputListener::~TestInputListener() { } Loading Loading @@ -95,9 +86,9 @@ void TestInputListener::assertCalled(NotifyArgsType* outEventArgs, std::string m std::vector<NotifyArgsType>& queue = std::get<std::vector<NotifyArgsType>>(mQueues); if (queue.empty()) { const bool eventReceived = mCondition.wait_for(lock, WAIT_TIMEOUT, [&queue]() REQUIRES(mLock) { return !queue.empty(); }); const bool eventReceived = mCondition.wait_for(lock, mTimeout, [&queue]() REQUIRES(mLock) { return !queue.empty(); }); if (!eventReceived) { FAIL() << "Timed out waiting for event: " << message.c_str(); } Loading @@ -114,7 +105,7 @@ void TestInputListener::assertNotCalled(std::string message) { base::ScopedLockAssertion assumeLocked(mLock); std::vector<NotifyArgsType>& queue = std::get<std::vector<NotifyArgsType>>(mQueues); const bool eventReceived = mCondition.wait_for(lock, WAIT_TIMEOUT, [&queue]() REQUIRES(mLock) { const bool eventReceived = mCondition.wait_for(lock, mTimeout, [&queue]() REQUIRES(mLock) { return !queue.empty(); }); if (eventReceived) { Loading
services/inputflinger/tests/TestInputListener.h +4 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ #include <gtest/gtest.h> #include "InputListener.h" using std::chrono_literals::operator""ms; namespace android { // --- TestInputListener --- Loading @@ -30,7 +32,7 @@ protected: virtual ~TestInputListener(); public: TestInputListener(); TestInputListener(const std::chrono::milliseconds timeout = 5ms); void assertNotifyConfigurationChangedWasCalled( NotifyConfigurationChangedArgs* outEventArgs = nullptr); Loading Loading @@ -73,6 +75,7 @@ private: std::mutex mLock; std::condition_variable mCondition; const std::chrono::milliseconds mTimeout; std::tuple<std::vector<NotifyConfigurationChangedArgs>, // std::vector<NotifyDeviceResetArgs>, // Loading
services/inputflinger/tests/UinputDevice.cpp +68 −1 Original line number Diff line number Diff line Loading @@ -127,4 +127,71 @@ void UinputHomeKey::pressAndReleaseHomeKey() { EXPECT_NO_FATAL_FAILURE(pressAndReleaseKey(KEY_HOME)); } // --- UinputTouchScreen --- UinputTouchScreen::UinputTouchScreen(const Rect* size) : UinputDevice(UinputTouchScreen::DEVICE_NAME), mSize(*size) {} void UinputTouchScreen::configureDevice(int fd, uinput_user_dev* device) { // Setup the touch screen device ioctl(fd, UI_SET_EVBIT, EV_KEY); ioctl(fd, UI_SET_EVBIT, EV_REL); ioctl(fd, UI_SET_EVBIT, EV_ABS); ioctl(fd, UI_SET_ABSBIT, ABS_MT_SLOT); ioctl(fd, UI_SET_ABSBIT, ABS_MT_TOUCH_MAJOR); ioctl(fd, UI_SET_ABSBIT, ABS_MT_POSITION_X); ioctl(fd, UI_SET_ABSBIT, ABS_MT_POSITION_Y); ioctl(fd, UI_SET_ABSBIT, ABS_MT_TRACKING_ID); ioctl(fd, UI_SET_ABSBIT, ABS_MT_TOOL_TYPE); ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT); ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH); device->absmin[ABS_MT_SLOT] = RAW_SLOT_MIN; device->absmax[ABS_MT_SLOT] = RAW_SLOT_MAX; device->absmin[ABS_MT_TOUCH_MAJOR] = RAW_TOUCH_MIN; device->absmax[ABS_MT_TOUCH_MAJOR] = RAW_TOUCH_MAX; device->absmin[ABS_MT_POSITION_X] = mSize.left; device->absmax[ABS_MT_POSITION_X] = mSize.right - 1; device->absmin[ABS_MT_POSITION_Y] = mSize.top; device->absmax[ABS_MT_POSITION_Y] = mSize.bottom - 1; device->absmin[ABS_MT_TRACKING_ID] = RAW_ID_MIN; device->absmax[ABS_MT_TRACKING_ID] = RAW_ID_MAX; } void UinputTouchScreen::sendSlot(int32_t slot) { EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_SLOT, slot)); } void UinputTouchScreen::sendTrackingId(int32_t trackingId) { EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_TRACKING_ID, trackingId)); } void UinputTouchScreen::sendDown(const Point& point) { EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, BTN_TOUCH, 1)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0)); } void UinputTouchScreen::sendMove(const Point& point) { EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0)); } void UinputTouchScreen::sendUp() { sendTrackingId(0xffffffff); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, BTN_TOUCH, 0)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0)); } void UinputTouchScreen::sendToolType(int32_t toolType) { EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_TOOL_TYPE, toolType)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0)); } // Get the center x, y base on the range definition. const Point UinputTouchScreen::getCenterPoint() { return Point(mSize.left + mSize.width() / 2, mSize.top + mSize.height() / 2); } } // namespace android
services/inputflinger/tests/UinputDevice.h +36 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ #include <inttypes.h> #include <linux/uinput.h> #include <log/log.h> #include <ui/Point.h> #include <ui/Rect.h> #include <memory> Loading Loading @@ -106,6 +108,40 @@ private: UinputHomeKey(); }; // --- UinputTouchScreen --- // A touch screen device with specific size. class UinputTouchScreen : public UinputDevice { public: static constexpr const char* DEVICE_NAME = "Test Touch Screen"; static const int32_t RAW_TOUCH_MIN = 0; static const int32_t RAW_TOUCH_MAX = 31; static const int32_t RAW_ID_MIN = 0; static const int32_t RAW_ID_MAX = 9; static const int32_t RAW_SLOT_MIN = 0; static const int32_t RAW_SLOT_MAX = 9; static const int32_t RAW_PRESSURE_MIN = 0; static const int32_t RAW_PRESSURE_MAX = 255; template <class D, class... Ts> friend std::unique_ptr<D> createUinputDevice(Ts... args); void sendSlot(int32_t slot); void sendTrackingId(int32_t trackingId); void sendDown(const Point& point); void sendMove(const Point& point); void sendUp(); void sendToolType(int32_t toolType); const Point getCenterPoint(); protected: UinputTouchScreen(const Rect* size); private: void configureDevice(int fd, uinput_user_dev* device) override; const Rect mSize; }; } // namespace android #endif // _UI_TEST_INPUT_UINPUT_INJECTOR_H