blob: 0e3d15a1ac50d4d4389ae01c307b6c82a3a4bab3 [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
Prabir Pradhane0105c92019-12-26 12:32:13 -080019#include "UinputDevice.h"
20
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -080021#include <gtest/gtest.h>
22#include <inttypes.h>
23#include <linux/uinput.h>
24#include <log/log.h>
25#include <chrono>
26
27#define TAG "EventHub_test"
28
Prabir Pradhane0105c92019-12-26 12:32:13 -080029using android::createUinputDevice;
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -080030using android::EventHub;
31using android::EventHubInterface;
32using android::InputDeviceIdentifier;
33using android::RawEvent;
34using android::sp;
Prabir Pradhane0105c92019-12-26 12:32:13 -080035using android::UinputHomeKey;
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -080036using std::chrono_literals::operator""ms;
Siarhei Vishniakoue5b5e452020-04-02 17:59:16 -070037using std::chrono_literals::operator""s;
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -080038
39static constexpr bool DEBUG = false;
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -080040
41static void dumpEvents(const std::vector<RawEvent>& events) {
42 for (const RawEvent& event : events) {
43 if (event.type >= EventHubInterface::FIRST_SYNTHETIC_EVENT) {
44 switch (event.type) {
45 case EventHubInterface::DEVICE_ADDED:
46 ALOGI("Device added: %i", event.deviceId);
47 break;
48 case EventHubInterface::DEVICE_REMOVED:
49 ALOGI("Device removed: %i", event.deviceId);
50 break;
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -080051 }
52 } else {
53 ALOGI("Device %" PRId32 " : time = %" PRId64 ", type %i, code %i, value %i",
54 event.deviceId, event.when, event.type, event.code, event.value);
55 }
56 }
57}
58
59// --- EventHubTest ---
60class EventHubTest : public testing::Test {
61protected:
62 std::unique_ptr<EventHubInterface> mEventHub;
63 // We are only going to emulate a single input device currently.
Prabir Pradhane0105c92019-12-26 12:32:13 -080064 std::unique_ptr<UinputHomeKey> mKeyboard;
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -080065 int32_t mDeviceId;
Prabir Pradhane0105c92019-12-26 12:32:13 -080066
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -080067 virtual void SetUp() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -070068#if !defined(__ANDROID__)
69 GTEST_SKIP() << "It's only possible to interact with uinput on device";
70#endif
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -080071 mEventHub = std::make_unique<EventHub>();
72 consumeInitialDeviceAddedEvents();
Prabir Pradhane0105c92019-12-26 12:32:13 -080073 mKeyboard = createUinputDevice<UinputHomeKey>();
Siarhei Vishniakoue5b5e452020-04-02 17:59:16 -070074 ASSERT_NO_FATAL_FAILURE(mDeviceId = waitForDeviceCreation());
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -080075 }
76 virtual void TearDown() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -070077#if !defined(__ANDROID__)
78 return;
79#endif
Prabir Pradhane0105c92019-12-26 12:32:13 -080080 mKeyboard.reset();
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -080081 waitForDeviceClose(mDeviceId);
Siarhei Vishniakoue5b5e452020-04-02 17:59:16 -070082 assertNoMoreEvents();
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -080083 }
84
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -080085 /**
86 * Return the device id of the created device.
87 */
88 int32_t waitForDeviceCreation();
89 void waitForDeviceClose(int32_t deviceId);
90 void consumeInitialDeviceAddedEvents();
Siarhei Vishniakoue5b5e452020-04-02 17:59:16 -070091 void assertNoMoreEvents();
92 /**
93 * Read events from the EventHub.
94 *
95 * If expectedEvents is set, wait for a significant period of time to try and ensure that
96 * the expected number of events has been read. The number of returned events
97 * may be smaller (if timeout has been reached) or larger than expectedEvents.
98 *
99 * If expectedEvents is not set, return all of the immediately available events.
100 */
101 std::vector<RawEvent> getEvents(std::optional<size_t> expectedEvents = std::nullopt);
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800102};
103
Siarhei Vishniakoue5b5e452020-04-02 17:59:16 -0700104std::vector<RawEvent> EventHubTest::getEvents(std::optional<size_t> expectedEvents) {
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800105 std::vector<RawEvent> events;
106
107 while (true) {
Siarhei Vishniakoue5b5e452020-04-02 17:59:16 -0700108 std::chrono::milliseconds timeout = 0s;
109 if (expectedEvents) {
110 timeout = 2s;
111 }
Siarhei Vishniakou7b3ea0b2022-09-16 14:23:20 -0700112
113 std::vector<RawEvent> newEvents = mEventHub->getEvents(timeout.count());
114 if (newEvents.empty()) {
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800115 break;
116 }
Siarhei Vishniakou7b3ea0b2022-09-16 14:23:20 -0700117 events.insert(events.end(), newEvents.begin(), newEvents.end());
Siarhei Vishniakoue5b5e452020-04-02 17:59:16 -0700118 if (expectedEvents && events.size() >= *expectedEvents) {
119 break;
120 }
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800121 }
122 if (DEBUG) {
123 dumpEvents(events);
124 }
125 return events;
126}
127
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800128/**
129 * Since the test runs on a real platform, there will be existing devices
130 * in addition to the test devices being added. Therefore, when EventHub is first created,
131 * it will return a lot of "device added" type of events.
132 */
133void EventHubTest::consumeInitialDeviceAddedEvents() {
Siarhei Vishniakoue5b5e452020-04-02 17:59:16 -0700134 std::vector<RawEvent> events = getEvents();
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800135 std::set<int32_t /*deviceId*/> existingDevices;
136 // All of the events should be DEVICE_ADDED type, except the last one.
137 for (size_t i = 0; i < events.size() - 1; i++) {
138 const RawEvent& event = events[i];
139 EXPECT_EQ(EventHubInterface::DEVICE_ADDED, event.type);
140 existingDevices.insert(event.deviceId);
141 }
142 // None of the existing system devices should be changing while this test is run.
143 // Check that the returned device ids are unique for all of the existing devices.
144 EXPECT_EQ(existingDevices.size(), events.size() - 1);
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800145}
146
147int32_t EventHubTest::waitForDeviceCreation() {
148 // Wait a little longer than usual, to ensure input device has time to be created
Siarhei Vishniakoue5b5e452020-04-02 17:59:16 -0700149 std::vector<RawEvent> events = getEvents(2);
Liana Kazanova5b8217b2024-07-18 17:44:51 +0000150 if (events.size() != 1) {
151 ADD_FAILURE() << "Instead of 1 event, received " << events.size();
Siarhei Vishniakoue5b5e452020-04-02 17:59:16 -0700152 return 0; // this value is unused
153 }
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800154 const RawEvent& deviceAddedEvent = events[0];
155 EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_ADDED), deviceAddedEvent.type);
156 InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceAddedEvent.deviceId);
157 const int32_t deviceId = deviceAddedEvent.deviceId;
Prabir Pradhane0105c92019-12-26 12:32:13 -0800158 EXPECT_EQ(identifier.name, mKeyboard->getName());
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800159 return deviceId;
160}
161
162void EventHubTest::waitForDeviceClose(int32_t deviceId) {
Siarhei Vishniakoue5b5e452020-04-02 17:59:16 -0700163 std::vector<RawEvent> events = getEvents(2);
Liana Kazanova5b8217b2024-07-18 17:44:51 +0000164 ASSERT_EQ(1U, events.size());
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800165 const RawEvent& deviceRemovedEvent = events[0];
166 EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_REMOVED), deviceRemovedEvent.type);
167 EXPECT_EQ(deviceId, deviceRemovedEvent.deviceId);
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800168}
169
Siarhei Vishniakoue5b5e452020-04-02 17:59:16 -0700170void EventHubTest::assertNoMoreEvents() {
171 std::vector<RawEvent> events = getEvents();
172 ASSERT_TRUE(events.empty());
173}
174
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800175/**
Josh Bartel938632f2022-07-19 15:34:22 -0500176 * Ensure that two identical devices get assigned unique descriptors from EventHub.
177 */
178TEST_F(EventHubTest, DevicesWithMatchingUniqueIdsAreUnique) {
179 std::unique_ptr<UinputHomeKey> keyboard2 = createUinputDevice<UinputHomeKey>();
180 int32_t deviceId2;
181 ASSERT_NO_FATAL_FAILURE(deviceId2 = waitForDeviceCreation());
182
183 ASSERT_NE(mEventHub->getDeviceIdentifier(mDeviceId).descriptor,
184 mEventHub->getDeviceIdentifier(deviceId2).descriptor);
185 keyboard2.reset();
186 waitForDeviceClose(deviceId2);
187}
188
189/**
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800190 * Ensure that input_events are generated with monotonic clock.
191 * That means input_event should receive a timestamp that is in the future of the time
192 * before the event was sent.
193 * Input system uses CLOCK_MONOTONIC everywhere in the code base.
194 */
195TEST_F(EventHubTest, InputEvent_TimestampIsMonotonic) {
196 nsecs_t lastEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
Prabir Pradhane0105c92019-12-26 12:32:13 -0800197 ASSERT_NO_FATAL_FAILURE(mKeyboard->pressAndReleaseHomeKey());
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800198
Siarhei Vishniakoue5b5e452020-04-02 17:59:16 -0700199 std::vector<RawEvent> events = getEvents(4);
Siarhei Vishniakou8588cc92018-12-12 18:17:58 -0800200 ASSERT_EQ(4U, events.size()) << "Expected to receive 2 keys and 2 syncs, total of 4 events";
201 for (const RawEvent& event : events) {
202 // Cannot use strict comparison because the events may happen too quickly
203 ASSERT_LE(lastEventTime, event.when) << "Event must have occurred after the key was sent";
204 ASSERT_LT(std::chrono::nanoseconds(event.when - lastEventTime), 100ms)
205 << "Event times are too far apart";
206 lastEventTime = event.when; // Ensure all returned events are monotonic
207 }
208}
Chris Ye66fbac32020-07-06 20:36:43 -0700209
210// --- BitArrayTest ---
211class BitArrayTest : public testing::Test {
212protected:
213 static constexpr size_t SINGLE_ELE_BITS = 32UL;
214 static constexpr size_t MULTI_ELE_BITS = 256UL;
215
216 virtual void SetUp() override {
217 mBitmaskSingle.loadFromBuffer(mBufferSingle);
218 mBitmaskMulti.loadFromBuffer(mBufferMulti);
219 }
220
221 android::BitArray<SINGLE_ELE_BITS> mBitmaskSingle;
222 android::BitArray<MULTI_ELE_BITS> mBitmaskMulti;
223
224private:
225 const typename android::BitArray<SINGLE_ELE_BITS>::Buffer mBufferSingle = {
226 0x800F0F0FUL // bit 0 - 31
227 };
228 const typename android::BitArray<MULTI_ELE_BITS>::Buffer mBufferMulti = {
229 0xFFFFFFFFUL, // bit 0 - 31
230 0x01000001UL, // bit 32 - 63
231 0x00000000UL, // bit 64 - 95
232 0x80000000UL, // bit 96 - 127
233 0x00000000UL, // bit 128 - 159
234 0x00000000UL, // bit 160 - 191
235 0x80000008UL, // bit 192 - 223
236 0x00000000UL, // bit 224 - 255
237 };
238};
239
240TEST_F(BitArrayTest, SetBit) {
241 ASSERT_TRUE(mBitmaskSingle.test(0));
242 ASSERT_TRUE(mBitmaskSingle.test(31));
243 ASSERT_FALSE(mBitmaskSingle.test(7));
244
245 ASSERT_TRUE(mBitmaskMulti.test(32));
246 ASSERT_TRUE(mBitmaskMulti.test(56));
247 ASSERT_FALSE(mBitmaskMulti.test(192));
248 ASSERT_TRUE(mBitmaskMulti.test(223));
249 ASSERT_FALSE(mBitmaskMulti.test(255));
250}
251
252TEST_F(BitArrayTest, AnyBit) {
253 ASSERT_TRUE(mBitmaskSingle.any(31, 32));
254 ASSERT_FALSE(mBitmaskSingle.any(12, 16));
255
256 ASSERT_TRUE(mBitmaskMulti.any(31, 32));
257 ASSERT_FALSE(mBitmaskMulti.any(33, 33));
258 ASSERT_TRUE(mBitmaskMulti.any(32, 55));
259 ASSERT_TRUE(mBitmaskMulti.any(33, 57));
260 ASSERT_FALSE(mBitmaskMulti.any(33, 55));
261 ASSERT_FALSE(mBitmaskMulti.any(130, 190));
262
263 ASSERT_FALSE(mBitmaskMulti.any(128, 195));
264 ASSERT_TRUE(mBitmaskMulti.any(128, 196));
265 ASSERT_TRUE(mBitmaskMulti.any(128, 224));
266 ASSERT_FALSE(mBitmaskMulti.any(255, 256));
267}
268
269TEST_F(BitArrayTest, SetBit_InvalidBitIndex) {
270 ASSERT_FALSE(mBitmaskSingle.test(32));
271 ASSERT_FALSE(mBitmaskMulti.test(256));
272}
273
274TEST_F(BitArrayTest, AnyBit_InvalidBitIndex) {
275 ASSERT_FALSE(mBitmaskSingle.any(32, 32));
276 ASSERT_FALSE(mBitmaskSingle.any(33, 34));
277
278 ASSERT_FALSE(mBitmaskMulti.any(256, 256));
279 ASSERT_FALSE(mBitmaskMulti.any(257, 258));
280 ASSERT_FALSE(mBitmaskMulti.any(0, 0));
281}