Loading services/inputflinger/tests/EventHub_test.cpp +36 −9 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ using android::RawEvent; using android::sp; using android::UinputHomeKey; using std::chrono_literals::operator""ms; using std::chrono_literals::operator""s; static constexpr bool DEBUG = false; Loading Loading @@ -70,11 +71,12 @@ protected: mEventHub = std::make_unique<EventHub>(); consumeInitialDeviceAddedEvents(); mKeyboard = createUinputDevice<UinputHomeKey>(); mDeviceId = waitForDeviceCreation(); ASSERT_NO_FATAL_FAILURE(mDeviceId = waitForDeviceCreation()); } virtual void TearDown() override { mKeyboard.reset(); waitForDeviceClose(mDeviceId); assertNoMoreEvents(); } /** Loading @@ -83,21 +85,38 @@ protected: int32_t waitForDeviceCreation(); void waitForDeviceClose(int32_t deviceId); void consumeInitialDeviceAddedEvents(); std::vector<RawEvent> getEvents(std::chrono::milliseconds timeout = 5ms); void assertNoMoreEvents(); /** * Read events from the EventHub. * * If expectedEvents is set, wait for a significant period of time to try and ensure that * the expected number of events has been read. The number of returned events * may be smaller (if timeout has been reached) or larger than expectedEvents. * * If expectedEvents is not set, return all of the immediately available events. */ std::vector<RawEvent> getEvents(std::optional<size_t> expectedEvents = std::nullopt); }; std::vector<RawEvent> EventHubTest::getEvents(std::chrono::milliseconds timeout) { std::vector<RawEvent> EventHubTest::getEvents(std::optional<size_t> expectedEvents) { static constexpr size_t EVENT_BUFFER_SIZE = 256; std::array<RawEvent, EVENT_BUFFER_SIZE> eventBuffer; std::vector<RawEvent> events; while (true) { size_t count = std::chrono::milliseconds timeout = 0s; if (expectedEvents) { timeout = 2s; } const size_t count = mEventHub->getEvents(timeout.count(), eventBuffer.data(), eventBuffer.size()); if (count == 0) { break; } events.insert(events.end(), eventBuffer.begin(), eventBuffer.begin() + count); if (expectedEvents && events.size() >= *expectedEvents) { break; } } if (DEBUG) { dumpEvents(events); Loading @@ -111,7 +130,7 @@ std::vector<RawEvent> EventHubTest::getEvents(std::chrono::milliseconds timeout) * it will return a lot of "device added" type of events. */ void EventHubTest::consumeInitialDeviceAddedEvents() { std::vector<RawEvent> events = getEvents(0ms); std::vector<RawEvent> events = getEvents(); std::set<int32_t /*deviceId*/> existingDevices; // All of the events should be DEVICE_ADDED type, except the last one. for (size_t i = 0; i < events.size() - 1; i++) { Loading @@ -128,8 +147,11 @@ void EventHubTest::consumeInitialDeviceAddedEvents() { int32_t EventHubTest::waitForDeviceCreation() { // Wait a little longer than usual, to ensure input device has time to be created std::vector<RawEvent> events = getEvents(20ms); EXPECT_EQ(2U, events.size()); // Using "expect" because the function is non-void. std::vector<RawEvent> events = getEvents(2); if (events.size() != 2) { ADD_FAILURE() << "Instead of 2 events, received " << events.size(); return 0; // this value is unused } const RawEvent& deviceAddedEvent = events[0]; EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_ADDED), deviceAddedEvent.type); InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceAddedEvent.deviceId); Loading @@ -142,7 +164,7 @@ int32_t EventHubTest::waitForDeviceCreation() { } void EventHubTest::waitForDeviceClose(int32_t deviceId) { std::vector<RawEvent> events = getEvents(20ms); std::vector<RawEvent> events = getEvents(2); ASSERT_EQ(2U, events.size()); const RawEvent& deviceRemovedEvent = events[0]; EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_REMOVED), deviceRemovedEvent.type); Loading @@ -152,6 +174,11 @@ void EventHubTest::waitForDeviceClose(int32_t deviceId) { finishedDeviceScanEvent.type); } void EventHubTest::assertNoMoreEvents() { std::vector<RawEvent> events = getEvents(); ASSERT_TRUE(events.empty()); } /** * Ensure that input_events are generated with monotonic clock. * That means input_event should receive a timestamp that is in the future of the time Loading @@ -162,7 +189,7 @@ TEST_F(EventHubTest, InputEvent_TimestampIsMonotonic) { nsecs_t lastEventTime = systemTime(SYSTEM_TIME_MONOTONIC); ASSERT_NO_FATAL_FAILURE(mKeyboard->pressAndReleaseHomeKey()); std::vector<RawEvent> events = getEvents(); std::vector<RawEvent> events = getEvents(4); ASSERT_EQ(4U, events.size()) << "Expected to receive 2 keys and 2 syncs, total of 4 events"; for (const RawEvent& event : events) { // Cannot use strict comparison because the events may happen too quickly Loading services/inputflinger/tests/UinputDevice.cpp +27 −29 Original line number Diff line number Diff line Loading @@ -44,9 +44,7 @@ void UinputDevice::init() { device.id.product = 0x01; device.id.version = 1; // Using EXPECT instead of ASSERT to allow the device creation to continue even when // some failures are reported when configuring the device. EXPECT_NO_FATAL_FAILURE(configureDevice(mDeviceFd, &device)); ASSERT_NO_FATAL_FAILURE(configureDevice(mDeviceFd, &device)); if (write(mDeviceFd, &device, sizeof(device)) < 0) { FAIL() << "Could not write uinput_user_dev struct into uinput file descriptor: " Loading @@ -70,7 +68,7 @@ void UinputDevice::injectEvent(uint16_t type, uint16_t code, int32_t value) { " with value %" PRId32 " : %s", type, code, value, strerror(errno)); ALOGE("%s", msg.c_str()); ADD_FAILURE() << msg.c_str(); FAIL() << msg.c_str(); } } Loading @@ -82,41 +80,41 @@ UinputKeyboard::UinputKeyboard(std::initializer_list<int> keys) void UinputKeyboard::configureDevice(int fd, uinput_user_dev* device) { // enable key press/release event if (ioctl(fd, UI_SET_EVBIT, EV_KEY)) { ADD_FAILURE() << "Error in ioctl : UI_SET_EVBIT : EV_KEY: " << strerror(errno); FAIL() << "Error in ioctl : UI_SET_EVBIT : EV_KEY: " << strerror(errno); } // enable set of KEY events std::for_each(mKeys.begin(), mKeys.end(), [fd](int key) { if (ioctl(fd, UI_SET_KEYBIT, key)) { ADD_FAILURE() << "Error in ioctl : UI_SET_KEYBIT : " << key << " : " << strerror(errno); FAIL() << "Error in ioctl : UI_SET_KEYBIT : " << key << " : " << strerror(errno); } }); // enable synchronization event if (ioctl(fd, UI_SET_EVBIT, EV_SYN)) { ADD_FAILURE() << "Error in ioctl : UI_SET_EVBIT : EV_SYN: " << strerror(errno); FAIL() << "Error in ioctl : UI_SET_EVBIT : EV_SYN: " << strerror(errno); } } void UinputKeyboard::pressKey(int key) { if (mKeys.find(key) == mKeys.end()) { ADD_FAILURE() << mName << ": Cannot inject key press: Key not found: " << key; FAIL() << mName << ": Cannot inject key press: Key not found: " << key; } EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, key, 1)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0)); injectEvent(EV_KEY, key, 1); injectEvent(EV_SYN, SYN_REPORT, 0); } void UinputKeyboard::releaseKey(int key) { if (mKeys.find(key) == mKeys.end()) { ADD_FAILURE() << mName << ": Cannot inject key release: Key not found: " << key; FAIL() << mName << ": Cannot inject key release: Key not found: " << key; } EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, key, 0)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0)); injectEvent(EV_KEY, key, 0); injectEvent(EV_SYN, SYN_REPORT, 0); } void UinputKeyboard::pressAndReleaseKey(int key) { EXPECT_NO_FATAL_FAILURE(pressKey(key)); EXPECT_NO_FATAL_FAILURE(releaseKey(key)); pressKey(key); releaseKey(key); } // --- UinputHomeKey --- Loading @@ -124,7 +122,7 @@ void UinputKeyboard::pressAndReleaseKey(int key) { UinputHomeKey::UinputHomeKey() : UinputKeyboard({KEY_HOME}) {} void UinputHomeKey::pressAndReleaseHomeKey() { EXPECT_NO_FATAL_FAILURE(pressAndReleaseKey(KEY_HOME)); pressAndReleaseKey(KEY_HOME); } // --- UinputTouchScreen --- Loading Loading @@ -158,35 +156,35 @@ void UinputTouchScreen::configureDevice(int fd, uinput_user_dev* device) { } void UinputTouchScreen::sendSlot(int32_t slot) { EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_SLOT, slot)); 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)); 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)); injectEvent(EV_KEY, BTN_TOUCH, 1); injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x); injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y); 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)); injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x); injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y); 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)); injectEvent(EV_KEY, BTN_TOUCH, 0); 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)); injectEvent(EV_ABS, ABS_MT_TOOL_TYPE, toolType); injectEvent(EV_SYN, SYN_REPORT, 0); } // Get the center x, y base on the range definition. Loading Loading
services/inputflinger/tests/EventHub_test.cpp +36 −9 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ using android::RawEvent; using android::sp; using android::UinputHomeKey; using std::chrono_literals::operator""ms; using std::chrono_literals::operator""s; static constexpr bool DEBUG = false; Loading Loading @@ -70,11 +71,12 @@ protected: mEventHub = std::make_unique<EventHub>(); consumeInitialDeviceAddedEvents(); mKeyboard = createUinputDevice<UinputHomeKey>(); mDeviceId = waitForDeviceCreation(); ASSERT_NO_FATAL_FAILURE(mDeviceId = waitForDeviceCreation()); } virtual void TearDown() override { mKeyboard.reset(); waitForDeviceClose(mDeviceId); assertNoMoreEvents(); } /** Loading @@ -83,21 +85,38 @@ protected: int32_t waitForDeviceCreation(); void waitForDeviceClose(int32_t deviceId); void consumeInitialDeviceAddedEvents(); std::vector<RawEvent> getEvents(std::chrono::milliseconds timeout = 5ms); void assertNoMoreEvents(); /** * Read events from the EventHub. * * If expectedEvents is set, wait for a significant period of time to try and ensure that * the expected number of events has been read. The number of returned events * may be smaller (if timeout has been reached) or larger than expectedEvents. * * If expectedEvents is not set, return all of the immediately available events. */ std::vector<RawEvent> getEvents(std::optional<size_t> expectedEvents = std::nullopt); }; std::vector<RawEvent> EventHubTest::getEvents(std::chrono::milliseconds timeout) { std::vector<RawEvent> EventHubTest::getEvents(std::optional<size_t> expectedEvents) { static constexpr size_t EVENT_BUFFER_SIZE = 256; std::array<RawEvent, EVENT_BUFFER_SIZE> eventBuffer; std::vector<RawEvent> events; while (true) { size_t count = std::chrono::milliseconds timeout = 0s; if (expectedEvents) { timeout = 2s; } const size_t count = mEventHub->getEvents(timeout.count(), eventBuffer.data(), eventBuffer.size()); if (count == 0) { break; } events.insert(events.end(), eventBuffer.begin(), eventBuffer.begin() + count); if (expectedEvents && events.size() >= *expectedEvents) { break; } } if (DEBUG) { dumpEvents(events); Loading @@ -111,7 +130,7 @@ std::vector<RawEvent> EventHubTest::getEvents(std::chrono::milliseconds timeout) * it will return a lot of "device added" type of events. */ void EventHubTest::consumeInitialDeviceAddedEvents() { std::vector<RawEvent> events = getEvents(0ms); std::vector<RawEvent> events = getEvents(); std::set<int32_t /*deviceId*/> existingDevices; // All of the events should be DEVICE_ADDED type, except the last one. for (size_t i = 0; i < events.size() - 1; i++) { Loading @@ -128,8 +147,11 @@ void EventHubTest::consumeInitialDeviceAddedEvents() { int32_t EventHubTest::waitForDeviceCreation() { // Wait a little longer than usual, to ensure input device has time to be created std::vector<RawEvent> events = getEvents(20ms); EXPECT_EQ(2U, events.size()); // Using "expect" because the function is non-void. std::vector<RawEvent> events = getEvents(2); if (events.size() != 2) { ADD_FAILURE() << "Instead of 2 events, received " << events.size(); return 0; // this value is unused } const RawEvent& deviceAddedEvent = events[0]; EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_ADDED), deviceAddedEvent.type); InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceAddedEvent.deviceId); Loading @@ -142,7 +164,7 @@ int32_t EventHubTest::waitForDeviceCreation() { } void EventHubTest::waitForDeviceClose(int32_t deviceId) { std::vector<RawEvent> events = getEvents(20ms); std::vector<RawEvent> events = getEvents(2); ASSERT_EQ(2U, events.size()); const RawEvent& deviceRemovedEvent = events[0]; EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_REMOVED), deviceRemovedEvent.type); Loading @@ -152,6 +174,11 @@ void EventHubTest::waitForDeviceClose(int32_t deviceId) { finishedDeviceScanEvent.type); } void EventHubTest::assertNoMoreEvents() { std::vector<RawEvent> events = getEvents(); ASSERT_TRUE(events.empty()); } /** * Ensure that input_events are generated with monotonic clock. * That means input_event should receive a timestamp that is in the future of the time Loading @@ -162,7 +189,7 @@ TEST_F(EventHubTest, InputEvent_TimestampIsMonotonic) { nsecs_t lastEventTime = systemTime(SYSTEM_TIME_MONOTONIC); ASSERT_NO_FATAL_FAILURE(mKeyboard->pressAndReleaseHomeKey()); std::vector<RawEvent> events = getEvents(); std::vector<RawEvent> events = getEvents(4); ASSERT_EQ(4U, events.size()) << "Expected to receive 2 keys and 2 syncs, total of 4 events"; for (const RawEvent& event : events) { // Cannot use strict comparison because the events may happen too quickly Loading
services/inputflinger/tests/UinputDevice.cpp +27 −29 Original line number Diff line number Diff line Loading @@ -44,9 +44,7 @@ void UinputDevice::init() { device.id.product = 0x01; device.id.version = 1; // Using EXPECT instead of ASSERT to allow the device creation to continue even when // some failures are reported when configuring the device. EXPECT_NO_FATAL_FAILURE(configureDevice(mDeviceFd, &device)); ASSERT_NO_FATAL_FAILURE(configureDevice(mDeviceFd, &device)); if (write(mDeviceFd, &device, sizeof(device)) < 0) { FAIL() << "Could not write uinput_user_dev struct into uinput file descriptor: " Loading @@ -70,7 +68,7 @@ void UinputDevice::injectEvent(uint16_t type, uint16_t code, int32_t value) { " with value %" PRId32 " : %s", type, code, value, strerror(errno)); ALOGE("%s", msg.c_str()); ADD_FAILURE() << msg.c_str(); FAIL() << msg.c_str(); } } Loading @@ -82,41 +80,41 @@ UinputKeyboard::UinputKeyboard(std::initializer_list<int> keys) void UinputKeyboard::configureDevice(int fd, uinput_user_dev* device) { // enable key press/release event if (ioctl(fd, UI_SET_EVBIT, EV_KEY)) { ADD_FAILURE() << "Error in ioctl : UI_SET_EVBIT : EV_KEY: " << strerror(errno); FAIL() << "Error in ioctl : UI_SET_EVBIT : EV_KEY: " << strerror(errno); } // enable set of KEY events std::for_each(mKeys.begin(), mKeys.end(), [fd](int key) { if (ioctl(fd, UI_SET_KEYBIT, key)) { ADD_FAILURE() << "Error in ioctl : UI_SET_KEYBIT : " << key << " : " << strerror(errno); FAIL() << "Error in ioctl : UI_SET_KEYBIT : " << key << " : " << strerror(errno); } }); // enable synchronization event if (ioctl(fd, UI_SET_EVBIT, EV_SYN)) { ADD_FAILURE() << "Error in ioctl : UI_SET_EVBIT : EV_SYN: " << strerror(errno); FAIL() << "Error in ioctl : UI_SET_EVBIT : EV_SYN: " << strerror(errno); } } void UinputKeyboard::pressKey(int key) { if (mKeys.find(key) == mKeys.end()) { ADD_FAILURE() << mName << ": Cannot inject key press: Key not found: " << key; FAIL() << mName << ": Cannot inject key press: Key not found: " << key; } EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, key, 1)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0)); injectEvent(EV_KEY, key, 1); injectEvent(EV_SYN, SYN_REPORT, 0); } void UinputKeyboard::releaseKey(int key) { if (mKeys.find(key) == mKeys.end()) { ADD_FAILURE() << mName << ": Cannot inject key release: Key not found: " << key; FAIL() << mName << ": Cannot inject key release: Key not found: " << key; } EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, key, 0)); EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0)); injectEvent(EV_KEY, key, 0); injectEvent(EV_SYN, SYN_REPORT, 0); } void UinputKeyboard::pressAndReleaseKey(int key) { EXPECT_NO_FATAL_FAILURE(pressKey(key)); EXPECT_NO_FATAL_FAILURE(releaseKey(key)); pressKey(key); releaseKey(key); } // --- UinputHomeKey --- Loading @@ -124,7 +122,7 @@ void UinputKeyboard::pressAndReleaseKey(int key) { UinputHomeKey::UinputHomeKey() : UinputKeyboard({KEY_HOME}) {} void UinputHomeKey::pressAndReleaseHomeKey() { EXPECT_NO_FATAL_FAILURE(pressAndReleaseKey(KEY_HOME)); pressAndReleaseKey(KEY_HOME); } // --- UinputTouchScreen --- Loading Loading @@ -158,35 +156,35 @@ void UinputTouchScreen::configureDevice(int fd, uinput_user_dev* device) { } void UinputTouchScreen::sendSlot(int32_t slot) { EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_SLOT, slot)); 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)); 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)); injectEvent(EV_KEY, BTN_TOUCH, 1); injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x); injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y); 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)); injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x); injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y); 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)); injectEvent(EV_KEY, BTN_TOUCH, 0); 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)); injectEvent(EV_ABS, ABS_MT_TOOL_TYPE, toolType); injectEvent(EV_SYN, SYN_REPORT, 0); } // Get the center x, y base on the range definition. Loading