blob: 6504738fc78dfef1b0035ec241234320bcc8060f [file] [log] [blame]
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -08001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "EventHub.h"
18
19#include <android-base/stringprintf.h>
20#include <gtest/gtest.h>
21#include <inttypes.h>
22#include <linux/uinput.h>
23#include <log/log.h>
24#include <chrono>
25
26#define TAG "EventHub_test"
27
28using android::EventHub;
29using android::EventHubInterface;
30using android::InputDeviceIdentifier;
31using android::RawEvent;
32using android::sp;
33using android::base::StringPrintf;
34using std::chrono_literals::operator""ms;
35
36static constexpr bool DEBUG = false;
37static const char* DEVICE_NAME = "EventHub Test Device";
38
39static void dumpEvents(const std::vector<RawEvent>& events) {
40 for (const RawEvent& event : events) {
41 if (event.type >= EventHubInterface::FIRST_SYNTHETIC_EVENT) {
42 switch (event.type) {
43 case EventHubInterface::DEVICE_ADDED:
44 ALOGI("Device added: %i", event.deviceId);
45 break;
46 case EventHubInterface::DEVICE_REMOVED:
47 ALOGI("Device removed: %i", event.deviceId);
48 break;
49 case EventHubInterface::FINISHED_DEVICE_SCAN:
50 ALOGI("Finished device scan.");
51 break;
52 }
53 } else {
54 ALOGI("Device %" PRId32 " : time = %" PRId64 ", type %i, code %i, value %i",
55 event.deviceId, event.when, event.type, event.code, event.value);
56 }
57 }
58}
59
60// --- EventHubTest ---
61class EventHubTest : public testing::Test {
62protected:
63 std::unique_ptr<EventHubInterface> mEventHub;
64 // We are only going to emulate a single input device currently.
65 android::base::unique_fd mDeviceFd;
66 int32_t mDeviceId;
67 virtual void SetUp() override {
68 mEventHub = std::make_unique<EventHub>();
69 consumeInitialDeviceAddedEvents();
70 createDevice();
71 mDeviceId = waitForDeviceCreation();
72 }
73 virtual void TearDown() override {
74 mDeviceFd.reset();
75 waitForDeviceClose(mDeviceId);
76 }
77
78 void createDevice();
79 /**
80 * Return the device id of the created device.
81 */
82 int32_t waitForDeviceCreation();
83 void waitForDeviceClose(int32_t deviceId);
84 void consumeInitialDeviceAddedEvents();
85 void sendEvent(uint16_t type, uint16_t code, int32_t value);
86 std::vector<RawEvent> getEvents(std::chrono::milliseconds timeout = 5ms);
87};
88
89std::vector<RawEvent> EventHubTest::getEvents(std::chrono::milliseconds timeout) {
90 static constexpr size_t EVENT_BUFFER_SIZE = 256;
91 std::array<RawEvent, EVENT_BUFFER_SIZE> eventBuffer;
92 std::vector<RawEvent> events;
93
94 while (true) {
95 size_t count =
96 mEventHub->getEvents(timeout.count(), eventBuffer.data(), eventBuffer.size());
97 if (count == 0) {
98 break;
99 }
100 events.insert(events.end(), eventBuffer.begin(), eventBuffer.begin() + count);
101 }
102 if (DEBUG) {
103 dumpEvents(events);
104 }
105 return events;
106}
107
108void EventHubTest::createDevice() {
109 mDeviceFd = android::base::unique_fd(open("/dev/uinput", O_WRONLY | O_NONBLOCK));
110 if (mDeviceFd < 0) {
111 FAIL() << "Can't open /dev/uinput :" << strerror(errno);
112 }
113
114 /**
115 * Signal which type of events this input device supports.
116 * We will emulate a keyboard here.
117 */
118 // enable key press/release event
119 if (ioctl(mDeviceFd, UI_SET_EVBIT, EV_KEY)) {
120 ADD_FAILURE() << "Error in ioctl : UI_SET_EVBIT : EV_KEY: " << strerror(errno);
121 }
122
123 // enable set of KEY events
124 if (ioctl(mDeviceFd, UI_SET_KEYBIT, KEY_HOME)) {
125 ADD_FAILURE() << "Error in ioctl : UI_SET_KEYBIT : KEY_HOME: " << strerror(errno);
126 }
127
128 // enable synchronization event
129 if (ioctl(mDeviceFd, UI_SET_EVBIT, EV_SYN)) {
130 ADD_FAILURE() << "Error in ioctl : UI_SET_EVBIT : EV_SYN: " << strerror(errno);
131 }
132
133 struct uinput_user_dev keyboard = {};
134 strlcpy(keyboard.name, DEVICE_NAME, UINPUT_MAX_NAME_SIZE);
135 keyboard.id.bustype = BUS_USB;
136 keyboard.id.vendor = 0x01;
137 keyboard.id.product = 0x01;
138 keyboard.id.version = 1;
139
140 if (write(mDeviceFd, &keyboard, sizeof(keyboard)) < 0) {
141 FAIL() << "Could not write uinput_user_dev struct into uinput file descriptor: "
142 << strerror(errno);
143 }
144
145 if (ioctl(mDeviceFd, UI_DEV_CREATE)) {
146 FAIL() << "Error in ioctl : UI_DEV_CREATE: " << strerror(errno);
147 }
148}
149
150/**
151 * Since the test runs on a real platform, there will be existing devices
152 * in addition to the test devices being added. Therefore, when EventHub is first created,
153 * it will return a lot of "device added" type of events.
154 */
155void EventHubTest::consumeInitialDeviceAddedEvents() {
156 std::vector<RawEvent> events = getEvents(0ms);
157 std::set<int32_t /*deviceId*/> existingDevices;
158 // All of the events should be DEVICE_ADDED type, except the last one.
159 for (size_t i = 0; i < events.size() - 1; i++) {
160 const RawEvent& event = events[i];
161 EXPECT_EQ(EventHubInterface::DEVICE_ADDED, event.type);
162 existingDevices.insert(event.deviceId);
163 }
164 // None of the existing system devices should be changing while this test is run.
165 // Check that the returned device ids are unique for all of the existing devices.
166 EXPECT_EQ(existingDevices.size(), events.size() - 1);
167 // The last event should be "finished device scan"
168 EXPECT_EQ(EventHubInterface::FINISHED_DEVICE_SCAN, events[events.size() - 1].type);
169}
170
171int32_t EventHubTest::waitForDeviceCreation() {
172 // Wait a little longer than usual, to ensure input device has time to be created
173 std::vector<RawEvent> events = getEvents(20ms);
174 EXPECT_EQ(2U, events.size()); // Using "expect" because the function is non-void.
175 const RawEvent& deviceAddedEvent = events[0];
176 EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_ADDED), deviceAddedEvent.type);
177 InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceAddedEvent.deviceId);
178 const int32_t deviceId = deviceAddedEvent.deviceId;
179 EXPECT_EQ(identifier.name, DEVICE_NAME);
180 const RawEvent& finishedDeviceScanEvent = events[1];
181 EXPECT_EQ(static_cast<int32_t>(EventHubInterface::FINISHED_DEVICE_SCAN),
182 finishedDeviceScanEvent.type);
183 return deviceId;
184}
185
186void EventHubTest::waitForDeviceClose(int32_t deviceId) {
187 std::vector<RawEvent> events = getEvents(20ms);
188 ASSERT_EQ(2U, events.size());
189 const RawEvent& deviceRemovedEvent = events[0];
190 EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_REMOVED), deviceRemovedEvent.type);
191 EXPECT_EQ(deviceId, deviceRemovedEvent.deviceId);
192 const RawEvent& finishedDeviceScanEvent = events[1];
193 EXPECT_EQ(static_cast<int32_t>(EventHubInterface::FINISHED_DEVICE_SCAN),
194 finishedDeviceScanEvent.type);
195}
196
197void EventHubTest::sendEvent(uint16_t type, uint16_t code, int32_t value) {
198 struct input_event event = {};
199 event.type = type;
200 event.code = code;
201 event.value = value;
202 event.time = {}; // uinput ignores the timestamp
203
204 if (write(mDeviceFd, &event, sizeof(input_event)) < 0) {
205 std::string msg = StringPrintf("Could not write event %" PRIu16 " %" PRIu16
206 " with value %" PRId32 " : %s",
207 type, code, value, strerror(errno));
208 ALOGE("%s", msg.c_str());
209 ADD_FAILURE() << msg.c_str();
210 }
211}
212
213/**
214 * Ensure that input_events are generated with monotonic clock.
215 * That means input_event should receive a timestamp that is in the future of the time
216 * before the event was sent.
217 * Input system uses CLOCK_MONOTONIC everywhere in the code base.
218 */
219TEST_F(EventHubTest, InputEvent_TimestampIsMonotonic) {
220 nsecs_t lastEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
221 // key press
222 sendEvent(EV_KEY, KEY_HOME, 1);
223 sendEvent(EV_SYN, SYN_REPORT, 0);
224
225 // key release
226 sendEvent(EV_KEY, KEY_HOME, 0);
227 sendEvent(EV_SYN, SYN_REPORT, 0);
228
229 std::vector<RawEvent> events = getEvents();
230 ASSERT_EQ(4U, events.size()) << "Expected to receive 2 keys and 2 syncs, total of 4 events";
231 for (const RawEvent& event : events) {
232 // Cannot use strict comparison because the events may happen too quickly
233 ASSERT_LE(lastEventTime, event.when) << "Event must have occurred after the key was sent";
234 ASSERT_LT(std::chrono::nanoseconds(event.when - lastEventTime), 100ms)
235 << "Event times are too far apart";
236 lastEventTime = event.when; // Ensure all returned events are monotonic
237 }
238}