1 /*
2 * Copyright 2022 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 #include <gestures/HardwareStateConverter.h>
17
18 #include <memory>
19
20 #include <EventHub.h>
21 #include <com_android_input_flags.h>
22 #include <flag_macros.h>
23 #include <gtest/gtest.h>
24 #include <linux/input-event-codes.h>
25 #include <utils/StrongPointer.h>
26
27 #include "FakeEventHub.h"
28 #include "FakeInputReaderPolicy.h"
29 #include "InstrumentedInputReader.h"
30 #include "MultiTouchMotionAccumulator.h"
31 #include "TestConstants.h"
32 #include "TestInputListener.h"
33
34 namespace android {
35
36 namespace {
37
38 const auto REPORT_PALMS =
39 ACONFIG_FLAG(com::android::input::flags, report_palms_to_gestures_library);
40
41 } // namespace
42
43 class HardwareStateConverterTest : public testing::Test {
44 public:
HardwareStateConverterTest()45 HardwareStateConverterTest()
46 : mFakeEventHub(std::make_shared<FakeEventHub>()),
47 mFakePolicy(sp<FakeInputReaderPolicy>::make()),
48 mReader(mFakeEventHub, mFakePolicy, mFakeListener),
49 mDevice(newDevice()),
50 mDeviceContext(*mDevice, EVENTHUB_ID) {
51 const size_t slotCount = 8;
52 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_SLOT, 0, slotCount - 1, 0, 0, 0);
53 mAccumulator.configure(mDeviceContext, slotCount, /*usingSlotsProtocol=*/true);
54 mConverter = std::make_unique<HardwareStateConverter>(mDeviceContext, mAccumulator);
55 }
56
57 protected:
58 static constexpr int32_t DEVICE_ID = END_RESERVED_ID + 1000;
59 static constexpr int32_t EVENTHUB_ID = 1;
60
newDevice()61 std::shared_ptr<InputDevice> newDevice() {
62 InputDeviceIdentifier identifier;
63 identifier.name = "device";
64 identifier.location = "USB1";
65 identifier.bus = 0;
66 std::shared_ptr<InputDevice> device =
67 std::make_shared<InputDevice>(mReader.getContext(), DEVICE_ID, /*generation=*/2,
68 identifier);
69 mReader.pushNextDevice(device);
70 mFakeEventHub->addDevice(EVENTHUB_ID, identifier.name, InputDeviceClass::TOUCHPAD,
71 identifier.bus);
72 mReader.loopOnce();
73 return device;
74 }
75
processAxis(nsecs_t when,int32_t type,int32_t code,int32_t value)76 void processAxis(nsecs_t when, int32_t type, int32_t code, int32_t value) {
77 RawEvent event;
78 event.when = when;
79 event.readTime = READ_TIME;
80 event.deviceId = EVENTHUB_ID;
81 event.type = type;
82 event.code = code;
83 event.value = value;
84 std::optional<SelfContainedHardwareState> schs = mConverter->processRawEvent(event);
85 EXPECT_FALSE(schs.has_value());
86 }
87
processSync(nsecs_t when)88 std::optional<SelfContainedHardwareState> processSync(nsecs_t when) {
89 RawEvent event;
90 event.when = when;
91 event.readTime = READ_TIME;
92 event.deviceId = EVENTHUB_ID;
93 event.type = EV_SYN;
94 event.code = SYN_REPORT;
95 event.value = 0;
96 return mConverter->processRawEvent(event);
97 }
98
99 std::shared_ptr<FakeEventHub> mFakeEventHub;
100 sp<FakeInputReaderPolicy> mFakePolicy;
101 TestInputListener mFakeListener;
102 InstrumentedInputReader mReader;
103 std::shared_ptr<InputDevice> mDevice;
104 InputDeviceContext mDeviceContext;
105 MultiTouchMotionAccumulator mAccumulator;
106 std::unique_ptr<HardwareStateConverter> mConverter;
107 };
108
TEST_F(HardwareStateConverterTest,OneFinger)109 TEST_F(HardwareStateConverterTest, OneFinger) {
110 const nsecs_t time = 1500000000;
111
112 processAxis(time, EV_ABS, ABS_MT_SLOT, 0);
113 processAxis(time, EV_ABS, ABS_MT_TRACKING_ID, 123);
114 processAxis(time, EV_ABS, ABS_MT_POSITION_X, 50);
115 processAxis(time, EV_ABS, ABS_MT_POSITION_Y, 100);
116 processAxis(time, EV_ABS, ABS_MT_TOUCH_MAJOR, 5);
117 processAxis(time, EV_ABS, ABS_MT_TOUCH_MINOR, 4);
118 processAxis(time, EV_ABS, ABS_MT_PRESSURE, 42);
119 processAxis(time, EV_ABS, ABS_MT_ORIENTATION, 2);
120
121 processAxis(time, EV_ABS, ABS_X, 50);
122 processAxis(time, EV_ABS, ABS_Y, 100);
123 processAxis(time, EV_ABS, ABS_PRESSURE, 42);
124
125 processAxis(time, EV_KEY, BTN_TOUCH, 1);
126 processAxis(time, EV_KEY, BTN_TOOL_FINGER, 1);
127 std::optional<SelfContainedHardwareState> schs = processSync(time);
128
129 ASSERT_TRUE(schs.has_value());
130 const HardwareState& state = schs->state;
131 EXPECT_NEAR(1.5, state.timestamp, EPSILON);
132 EXPECT_EQ(0, state.buttons_down);
133 EXPECT_EQ(1, state.touch_cnt);
134
135 ASSERT_EQ(1, state.finger_cnt);
136 const FingerState& finger = state.fingers[0];
137 EXPECT_EQ(123, finger.tracking_id);
138 EXPECT_NEAR(50, finger.position_x, EPSILON);
139 EXPECT_NEAR(100, finger.position_y, EPSILON);
140 EXPECT_NEAR(5, finger.touch_major, EPSILON);
141 EXPECT_NEAR(4, finger.touch_minor, EPSILON);
142 EXPECT_NEAR(42, finger.pressure, EPSILON);
143 EXPECT_NEAR(2, finger.orientation, EPSILON);
144 EXPECT_EQ(0u, finger.flags);
145
146 EXPECT_EQ(0, state.rel_x);
147 EXPECT_EQ(0, state.rel_y);
148 EXPECT_EQ(0, state.rel_wheel);
149 EXPECT_EQ(0, state.rel_wheel_hi_res);
150 EXPECT_EQ(0, state.rel_hwheel);
151 EXPECT_NEAR(0.0, state.msc_timestamp, EPSILON);
152 }
153
TEST_F(HardwareStateConverterTest,TwoFingers)154 TEST_F(HardwareStateConverterTest, TwoFingers) {
155 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0);
156 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123);
157 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50);
158 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100);
159 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, 5);
160 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, 4);
161 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_PRESSURE, 42);
162 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_ORIENTATION, 2);
163
164 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 1);
165 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 456);
166 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, -20);
167 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 40);
168 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, 8);
169 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, 7);
170 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_PRESSURE, 21);
171 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_ORIENTATION, 1);
172
173 processAxis(ARBITRARY_TIME, EV_ABS, ABS_X, 50);
174 processAxis(ARBITRARY_TIME, EV_ABS, ABS_Y, 100);
175 processAxis(ARBITRARY_TIME, EV_ABS, ABS_PRESSURE, 42);
176
177 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1);
178 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
179 std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
180
181 ASSERT_TRUE(schs.has_value());
182 ASSERT_EQ(2, schs->state.finger_cnt);
183 const FingerState& finger1 = schs->state.fingers[0];
184 EXPECT_EQ(123, finger1.tracking_id);
185 EXPECT_NEAR(50, finger1.position_x, EPSILON);
186 EXPECT_NEAR(100, finger1.position_y, EPSILON);
187 EXPECT_NEAR(5, finger1.touch_major, EPSILON);
188 EXPECT_NEAR(4, finger1.touch_minor, EPSILON);
189 EXPECT_NEAR(42, finger1.pressure, EPSILON);
190 EXPECT_NEAR(2, finger1.orientation, EPSILON);
191 EXPECT_EQ(0u, finger1.flags);
192
193 const FingerState& finger2 = schs->state.fingers[1];
194 EXPECT_EQ(456, finger2.tracking_id);
195 EXPECT_NEAR(-20, finger2.position_x, EPSILON);
196 EXPECT_NEAR(40, finger2.position_y, EPSILON);
197 EXPECT_NEAR(8, finger2.touch_major, EPSILON);
198 EXPECT_NEAR(7, finger2.touch_minor, EPSILON);
199 EXPECT_NEAR(21, finger2.pressure, EPSILON);
200 EXPECT_NEAR(1, finger2.orientation, EPSILON);
201 EXPECT_EQ(0u, finger2.flags);
202 }
203
TEST_F_WITH_FLAGS(HardwareStateConverterTest,OnePalmDisableReportPalms,REQUIRES_FLAGS_DISABLED (REPORT_PALMS))204 TEST_F_WITH_FLAGS(HardwareStateConverterTest, OnePalmDisableReportPalms,
205 REQUIRES_FLAGS_DISABLED(REPORT_PALMS)) {
206 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0);
207 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
208 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123);
209 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50);
210 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100);
211
212 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1);
213 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_FINGER, 1);
214 std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
215 ASSERT_TRUE(schs.has_value());
216 EXPECT_EQ(0, schs->state.touch_cnt);
217 EXPECT_EQ(0, schs->state.finger_cnt);
218 }
219
TEST_F_WITH_FLAGS(HardwareStateConverterTest,OnePalmEnableReportPalms,REQUIRES_FLAGS_ENABLED (REPORT_PALMS))220 TEST_F_WITH_FLAGS(HardwareStateConverterTest, OnePalmEnableReportPalms,
221 REQUIRES_FLAGS_ENABLED(REPORT_PALMS)) {
222 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0);
223 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
224 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123);
225 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50);
226 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100);
227
228 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1);
229 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_FINGER, 1);
230 std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
231 ASSERT_TRUE(schs.has_value());
232 EXPECT_EQ(1, schs->state.touch_cnt);
233 EXPECT_EQ(1, schs->state.finger_cnt);
234 EXPECT_EQ(FingerState::ToolType::kPalm, schs->state.fingers[0].tool_type);
235 }
236
TEST_F_WITH_FLAGS(HardwareStateConverterTest,OneFingerTurningIntoAPalmDisableReportPalms,REQUIRES_FLAGS_DISABLED (REPORT_PALMS))237 TEST_F_WITH_FLAGS(HardwareStateConverterTest, OneFingerTurningIntoAPalmDisableReportPalms,
238 REQUIRES_FLAGS_DISABLED(REPORT_PALMS)) {
239 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0);
240 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
241 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123);
242 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50);
243 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100);
244
245 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1);
246 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_FINGER, 1);
247
248 std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
249 ASSERT_TRUE(schs.has_value());
250 EXPECT_EQ(1, schs->state.touch_cnt);
251 EXPECT_EQ(1, schs->state.finger_cnt);
252
253 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
254 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 51);
255 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 99);
256
257 schs = processSync(ARBITRARY_TIME);
258 ASSERT_TRUE(schs.has_value());
259 EXPECT_EQ(0, schs->state.touch_cnt);
260 ASSERT_EQ(0, schs->state.finger_cnt);
261
262 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 53);
263 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 97);
264
265 schs = processSync(ARBITRARY_TIME);
266 ASSERT_TRUE(schs.has_value());
267 EXPECT_EQ(0, schs->state.touch_cnt);
268 EXPECT_EQ(0, schs->state.finger_cnt);
269
270 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
271 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 55);
272 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 95);
273 schs = processSync(ARBITRARY_TIME);
274 ASSERT_TRUE(schs.has_value());
275 EXPECT_EQ(1, schs->state.touch_cnt);
276 ASSERT_EQ(1, schs->state.finger_cnt);
277 const FingerState& newFinger = schs->state.fingers[0];
278 EXPECT_EQ(123, newFinger.tracking_id);
279 EXPECT_NEAR(55, newFinger.position_x, EPSILON);
280 EXPECT_NEAR(95, newFinger.position_y, EPSILON);
281 }
282
TEST_F_WITH_FLAGS(HardwareStateConverterTest,OneFingerTurningIntoAPalmEnableReportPalms,REQUIRES_FLAGS_ENABLED (REPORT_PALMS))283 TEST_F_WITH_FLAGS(HardwareStateConverterTest, OneFingerTurningIntoAPalmEnableReportPalms,
284 REQUIRES_FLAGS_ENABLED(REPORT_PALMS)) {
285 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0);
286 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
287 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123);
288 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50);
289 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100);
290
291 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1);
292 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_FINGER, 1);
293
294 std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
295 ASSERT_TRUE(schs.has_value());
296 EXPECT_EQ(1, schs->state.touch_cnt);
297 EXPECT_EQ(1, schs->state.finger_cnt);
298 EXPECT_EQ(FingerState::ToolType::kFinger, schs->state.fingers[0].tool_type);
299
300 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
301 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 51);
302 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 99);
303
304 schs = processSync(ARBITRARY_TIME);
305 ASSERT_TRUE(schs.has_value());
306 EXPECT_EQ(1, schs->state.touch_cnt);
307 ASSERT_EQ(1, schs->state.finger_cnt);
308 EXPECT_EQ(FingerState::ToolType::kPalm, schs->state.fingers[0].tool_type);
309
310 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 53);
311 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 97);
312
313 schs = processSync(ARBITRARY_TIME);
314 ASSERT_TRUE(schs.has_value());
315 EXPECT_EQ(1, schs->state.touch_cnt);
316 EXPECT_EQ(1, schs->state.finger_cnt);
317 EXPECT_EQ(FingerState::ToolType::kPalm, schs->state.fingers[0].tool_type);
318
319 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
320 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 55);
321 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 95);
322 schs = processSync(ARBITRARY_TIME);
323 ASSERT_TRUE(schs.has_value());
324 EXPECT_EQ(1, schs->state.touch_cnt);
325 ASSERT_EQ(1, schs->state.finger_cnt);
326 const FingerState& newFinger = schs->state.fingers[0];
327 EXPECT_EQ(FingerState::ToolType::kFinger, newFinger.tool_type);
328 EXPECT_EQ(123, newFinger.tracking_id);
329 EXPECT_NEAR(55, newFinger.position_x, EPSILON);
330 EXPECT_NEAR(95, newFinger.position_y, EPSILON);
331 }
332
TEST_F(HardwareStateConverterTest,ButtonPressed)333 TEST_F(HardwareStateConverterTest, ButtonPressed) {
334 processAxis(ARBITRARY_TIME, EV_KEY, BTN_LEFT, 1);
335 std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
336
337 ASSERT_TRUE(schs.has_value());
338 EXPECT_EQ(GESTURES_BUTTON_LEFT, schs->state.buttons_down);
339 }
340
TEST_F(HardwareStateConverterTest,MscTimestamp)341 TEST_F(HardwareStateConverterTest, MscTimestamp) {
342 processAxis(ARBITRARY_TIME, EV_MSC, MSC_TIMESTAMP, 1200000);
343 std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
344
345 ASSERT_TRUE(schs.has_value());
346 EXPECT_NEAR(1.2, schs->state.msc_timestamp, EPSILON);
347 }
348
349 } // namespace android
350