1 /*
2 * Copyright 2023 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 <CapturedTouchpadEventConverter.h>
18
19 #include <list>
20 #include <memory>
21
22 #include <EventHub.h>
23 #include <com_android_input_flags.h>
24 #include <gtest/gtest.h>
25 #include <linux/input-event-codes.h>
26 #include <linux/input.h>
27 #include <utils/StrongPointer.h>
28
29 #include "FakeEventHub.h"
30 #include "FakeInputReaderPolicy.h"
31 #include "InstrumentedInputReader.h"
32 #include "TestConstants.h"
33 #include "TestEventMatchers.h"
34 #include "TestInputListener.h"
35
36 namespace input_flags = com::android::input::flags;
37
38 namespace android {
39
40 using testing::AllOf;
41 using testing::Each;
42 using testing::ElementsAre;
43 using testing::VariantWith;
44
45 class CapturedTouchpadEventConverterTest : public testing::Test {
46 public:
CapturedTouchpadEventConverterTest()47 CapturedTouchpadEventConverterTest()
48 : mFakeEventHub(std::make_unique<FakeEventHub>()),
49 mFakePolicy(sp<FakeInputReaderPolicy>::make()),
50 mReader(mFakeEventHub, mFakePolicy, mFakeListener),
51 mDevice(newDevice()),
52 mDeviceContext(*mDevice, EVENTHUB_ID) {
53 input_flags::include_relative_axis_values_for_captured_touchpads(true);
54
55 const size_t slotCount = 8;
56 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_SLOT, 0, slotCount - 1, 0, 0, 0);
57 mAccumulator.configure(mDeviceContext, slotCount, /*usingSlotsProtocol=*/true);
58 }
59
60 protected:
61 static constexpr int32_t DEVICE_ID = END_RESERVED_ID + 1000;
62 static constexpr int32_t EVENTHUB_ID = 1;
63
newDevice()64 std::shared_ptr<InputDevice> newDevice() {
65 InputDeviceIdentifier identifier;
66 identifier.name = "device";
67 identifier.location = "USB1";
68 identifier.bus = 0;
69 std::shared_ptr<InputDevice> device =
70 std::make_shared<InputDevice>(mReader.getContext(), DEVICE_ID, /*generation=*/2,
71 identifier);
72 mReader.pushNextDevice(device);
73 mFakeEventHub->addDevice(EVENTHUB_ID, identifier.name, InputDeviceClass::TOUCHPAD,
74 identifier.bus);
75 mReader.loopOnce();
76 return device;
77 }
78
addBasicAxesToEventHub()79 void addBasicAxesToEventHub() {
80 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, 0, 4000, 0, 0, 45);
81 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, 0, 2500, 0, 0, 40);
82 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_PRESSURE, 0, 256, 0, 0, 0);
83 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, 0, 1000, 0, 0, 0);
84 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, 0, 1000, 0, 0, 0);
85 }
86
createConverter()87 CapturedTouchpadEventConverter createConverter() {
88 addBasicAxesToEventHub();
89 return CapturedTouchpadEventConverter(*mReader.getContext(), mDeviceContext, mAccumulator,
90 DEVICE_ID);
91 }
92
processAxis(CapturedTouchpadEventConverter & conv,int32_t type,int32_t code,int32_t value)93 void processAxis(CapturedTouchpadEventConverter& conv, int32_t type, int32_t code,
94 int32_t value) {
95 RawEvent event;
96 event.when = ARBITRARY_TIME;
97 event.readTime = READ_TIME;
98 event.deviceId = EVENTHUB_ID;
99 event.type = type;
100 event.code = code;
101 event.value = value;
102 std::list<NotifyArgs> out = conv.process(event);
103 EXPECT_TRUE(out.empty());
104 }
105
processSync(CapturedTouchpadEventConverter & conv)106 std::list<NotifyArgs> processSync(CapturedTouchpadEventConverter& conv) {
107 RawEvent event;
108 event.when = ARBITRARY_TIME;
109 event.readTime = READ_TIME;
110 event.deviceId = EVENTHUB_ID;
111 event.type = EV_SYN;
112 event.code = SYN_REPORT;
113 event.value = 0;
114 return conv.process(event);
115 }
116
processSyncAndExpectSingleMotionArg(CapturedTouchpadEventConverter & conv)117 NotifyMotionArgs processSyncAndExpectSingleMotionArg(CapturedTouchpadEventConverter& conv) {
118 std::list<NotifyArgs> args = processSync(conv);
119 EXPECT_EQ(1u, args.size());
120 return std::get<NotifyMotionArgs>(args.front());
121 }
122
123 std::shared_ptr<FakeEventHub> mFakeEventHub;
124 sp<FakeInputReaderPolicy> mFakePolicy;
125 TestInputListener mFakeListener;
126 InstrumentedInputReader mReader;
127 std::shared_ptr<InputDevice> mDevice;
128 InputDeviceContext mDeviceContext;
129 MultiTouchMotionAccumulator mAccumulator;
130 };
131
TEST_F(CapturedTouchpadEventConverterTest,MotionRanges_allAxesPresent_populatedCorrectly)132 TEST_F(CapturedTouchpadEventConverterTest, MotionRanges_allAxesPresent_populatedCorrectly) {
133 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, 0, 4000, 0, 0, 45);
134 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, -500, 2000, 0, 0, 40);
135 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, 0, 1100, 0, 0, 35);
136 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, 0, 1000, 0, 0, 30);
137 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, 0, 900, 0, 0, 25);
138 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, 0, 800, 0, 0, 20);
139 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_ORIENTATION, -3, 4, 0, 0, 0);
140 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_PRESSURE, 0, 256, 0, 0, 0);
141 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
142 DEVICE_ID);
143
144 InputDeviceInfo info;
145 conv.populateMotionRanges(info);
146
147 // Most axes should have min, max, and resolution matching the evdev axes.
148 const InputDeviceInfo::MotionRange* posX =
149 info.getMotionRange(AMOTION_EVENT_AXIS_X, AINPUT_SOURCE_TOUCHPAD);
150 ASSERT_NE(nullptr, posX);
151 EXPECT_NEAR(0, posX->min, EPSILON);
152 EXPECT_NEAR(4000, posX->max, EPSILON);
153 EXPECT_NEAR(45, posX->resolution, EPSILON);
154
155 const InputDeviceInfo::MotionRange* posY =
156 info.getMotionRange(AMOTION_EVENT_AXIS_Y, AINPUT_SOURCE_TOUCHPAD);
157 ASSERT_NE(nullptr, posY);
158 EXPECT_NEAR(-500, posY->min, EPSILON);
159 EXPECT_NEAR(2000, posY->max, EPSILON);
160 EXPECT_NEAR(40, posY->resolution, EPSILON);
161
162 const InputDeviceInfo::MotionRange* touchMajor =
163 info.getMotionRange(AMOTION_EVENT_AXIS_TOUCH_MAJOR, AINPUT_SOURCE_TOUCHPAD);
164 ASSERT_NE(nullptr, touchMajor);
165 EXPECT_NEAR(0, touchMajor->min, EPSILON);
166 EXPECT_NEAR(1100, touchMajor->max, EPSILON);
167 EXPECT_NEAR(35, touchMajor->resolution, EPSILON);
168
169 const InputDeviceInfo::MotionRange* touchMinor =
170 info.getMotionRange(AMOTION_EVENT_AXIS_TOUCH_MINOR, AINPUT_SOURCE_TOUCHPAD);
171 ASSERT_NE(nullptr, touchMinor);
172 EXPECT_NEAR(0, touchMinor->min, EPSILON);
173 EXPECT_NEAR(1000, touchMinor->max, EPSILON);
174 EXPECT_NEAR(30, touchMinor->resolution, EPSILON);
175
176 const InputDeviceInfo::MotionRange* toolMajor =
177 info.getMotionRange(AMOTION_EVENT_AXIS_TOOL_MAJOR, AINPUT_SOURCE_TOUCHPAD);
178 ASSERT_NE(nullptr, toolMajor);
179 EXPECT_NEAR(0, toolMajor->min, EPSILON);
180 EXPECT_NEAR(900, toolMajor->max, EPSILON);
181 EXPECT_NEAR(25, toolMajor->resolution, EPSILON);
182
183 const InputDeviceInfo::MotionRange* toolMinor =
184 info.getMotionRange(AMOTION_EVENT_AXIS_TOOL_MINOR, AINPUT_SOURCE_TOUCHPAD);
185 ASSERT_NE(nullptr, toolMinor);
186 EXPECT_NEAR(0, toolMinor->min, EPSILON);
187 EXPECT_NEAR(800, toolMinor->max, EPSILON);
188 EXPECT_NEAR(20, toolMinor->resolution, EPSILON);
189
190 // ...except for the relative motion axes, derived from the corresponding absolute ones:
191 const InputDeviceInfo::MotionRange* relX =
192 info.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, AINPUT_SOURCE_TOUCHPAD);
193 ASSERT_NE(nullptr, relX);
194 EXPECT_NEAR(-4000, relX->min, EPSILON);
195 EXPECT_NEAR(4000, relX->max, EPSILON);
196 EXPECT_NEAR(45, relX->resolution, EPSILON);
197
198 const InputDeviceInfo::MotionRange* relY =
199 info.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, AINPUT_SOURCE_TOUCHPAD);
200 ASSERT_NE(nullptr, relY);
201 EXPECT_NEAR(-2500, relY->min, EPSILON);
202 EXPECT_NEAR(2500, relY->max, EPSILON);
203 EXPECT_NEAR(40, relY->resolution, EPSILON);
204
205 // ...orientation and pressure, which get scaled:
206 const InputDeviceInfo::MotionRange* orientation =
207 info.getMotionRange(AMOTION_EVENT_AXIS_ORIENTATION, AINPUT_SOURCE_TOUCHPAD);
208 ASSERT_NE(nullptr, orientation);
209 EXPECT_NEAR(-M_PI_2, orientation->min, EPSILON);
210 EXPECT_NEAR(M_PI_2, orientation->max, EPSILON);
211 EXPECT_NEAR(0, orientation->resolution, EPSILON);
212
213 const InputDeviceInfo::MotionRange* pressure =
214 info.getMotionRange(AMOTION_EVENT_AXIS_PRESSURE, AINPUT_SOURCE_TOUCHPAD);
215 ASSERT_NE(nullptr, pressure);
216 EXPECT_NEAR(0, pressure->min, EPSILON);
217 EXPECT_NEAR(1, pressure->max, EPSILON);
218 EXPECT_NEAR(0, pressure->resolution, EPSILON);
219
220 // ... and size, which is generated from other values.
221 const InputDeviceInfo::MotionRange* size =
222 info.getMotionRange(AMOTION_EVENT_AXIS_SIZE, AINPUT_SOURCE_TOUCHPAD);
223 ASSERT_NE(nullptr, size);
224 EXPECT_NEAR(0, size->min, EPSILON);
225 EXPECT_NEAR(1, size->max, EPSILON);
226 EXPECT_NEAR(0, size->resolution, EPSILON);
227 }
228
TEST_F(CapturedTouchpadEventConverterTest,MotionRanges_bareMinimumAxesPresent_populatedCorrectly)229 TEST_F(CapturedTouchpadEventConverterTest, MotionRanges_bareMinimumAxesPresent_populatedCorrectly) {
230 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, 0, 4000, 0, 0, 45);
231 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, 0, 2500, 0, 0, 40);
232 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
233 DEVICE_ID);
234
235 InputDeviceInfo info;
236 conv.populateMotionRanges(info);
237
238 // Only the bare minimum motion ranges should be reported, and no others (e.g. size shouldn't be
239 // present, since it's generated from axes that aren't provided by this device).
240 EXPECT_NE(nullptr, info.getMotionRange(AMOTION_EVENT_AXIS_X, AINPUT_SOURCE_TOUCHPAD));
241 EXPECT_NE(nullptr, info.getMotionRange(AMOTION_EVENT_AXIS_Y, AINPUT_SOURCE_TOUCHPAD));
242 EXPECT_NE(nullptr, info.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, AINPUT_SOURCE_TOUCHPAD));
243 EXPECT_NE(nullptr, info.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, AINPUT_SOURCE_TOUCHPAD));
244 EXPECT_EQ(4u, info.getMotionRanges().size());
245 }
246
TEST_F(CapturedTouchpadEventConverterTest,OneFinger_motionReportedCorrectly)247 TEST_F(CapturedTouchpadEventConverterTest, OneFinger_motionReportedCorrectly) {
248 CapturedTouchpadEventConverter conv = createConverter();
249
250 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
251 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
252 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 50);
253 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 100);
254
255 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
256 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
257
258 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
259 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPointerCount(1u),
260 WithCoords(50, 100), WithRelativeMotion(0, 0),
261 WithToolType(ToolType::FINGER)));
262
263 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 52);
264 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 99);
265
266 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
267 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithPointerCount(1u),
268 WithCoords(52, 99), WithRelativeMotion(2, -1),
269 WithToolType(ToolType::FINGER)));
270
271 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, -1);
272 processAxis(conv, EV_KEY, BTN_TOUCH, 0);
273 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 0);
274
275 std::list<NotifyArgs> args = processSync(conv);
276 EXPECT_THAT(args,
277 ElementsAre(VariantWith<NotifyMotionArgs>(
278 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)),
279 VariantWith<NotifyMotionArgs>(
280 WithMotionAction(AMOTION_EVENT_ACTION_UP))));
281 EXPECT_THAT(args,
282 Each(VariantWith<NotifyMotionArgs>(
283 AllOf(WithCoords(52, 99), WithRelativeMotion(0, 0), WithPointerCount(1u),
284 WithToolType(ToolType::FINGER)))));
285 }
286
TEST_F(CapturedTouchpadEventConverterTest,OneFinger_touchDimensionsPassedThrough)287 TEST_F(CapturedTouchpadEventConverterTest, OneFinger_touchDimensionsPassedThrough) {
288 addBasicAxesToEventHub();
289 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, 0, 1000, 0, 0, 0);
290 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, 0, 1000, 0, 0, 0);
291 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
292 DEVICE_ID);
293
294 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
295 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
296 processAxis(conv, EV_ABS, ABS_MT_TOUCH_MAJOR, 250);
297 processAxis(conv, EV_ABS, ABS_MT_TOUCH_MINOR, 120);
298 processAxis(conv, EV_ABS, ABS_MT_WIDTH_MAJOR, 400);
299 processAxis(conv, EV_ABS, ABS_MT_WIDTH_MINOR, 200);
300
301 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
302 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
303
304 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
305 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPointerCount(1u),
306 WithTouchDimensions(250, 120), WithToolDimensions(400, 200)));
307 }
308
TEST_F(CapturedTouchpadEventConverterTest,OneFinger_orientationCalculatedCorrectly)309 TEST_F(CapturedTouchpadEventConverterTest, OneFinger_orientationCalculatedCorrectly) {
310 addBasicAxesToEventHub();
311 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_ORIENTATION, -3, 4, 0, 0, 0);
312 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
313 DEVICE_ID);
314
315 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
316 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
317 processAxis(conv, EV_ABS, ABS_MT_ORIENTATION, -3);
318 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
319 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
320
321 EXPECT_NEAR(-3 * M_PI / 8,
322 processSyncAndExpectSingleMotionArg(conv).pointerCoords[0].getAxisValue(
323 AMOTION_EVENT_AXIS_ORIENTATION),
324 EPSILON);
325
326 processAxis(conv, EV_ABS, ABS_MT_ORIENTATION, 0);
327
328 EXPECT_NEAR(0,
329 processSyncAndExpectSingleMotionArg(conv).pointerCoords[0].getAxisValue(
330 AMOTION_EVENT_AXIS_ORIENTATION),
331 EPSILON);
332
333 processAxis(conv, EV_ABS, ABS_MT_ORIENTATION, 4);
334
335 EXPECT_NEAR(M_PI / 2,
336 processSyncAndExpectSingleMotionArg(conv).pointerCoords[0].getAxisValue(
337 AMOTION_EVENT_AXIS_ORIENTATION),
338 EPSILON);
339 }
340
TEST_F(CapturedTouchpadEventConverterTest,OneFinger_pressureScaledCorrectly)341 TEST_F(CapturedTouchpadEventConverterTest, OneFinger_pressureScaledCorrectly) {
342 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, 0, 4000, 0, 0, 45);
343 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, 0, 2500, 0, 0, 40);
344 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_PRESSURE, 0, 256, 0, 0, 0);
345 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
346 DEVICE_ID);
347
348 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
349 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
350 processAxis(conv, EV_ABS, ABS_MT_PRESSURE, 128);
351 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
352 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
353
354 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv), WithPressure(0.5));
355 }
356
TEST_F(CapturedTouchpadEventConverterTest,OneFinger_withAllSizeAxes_sizeCalculatedFromTouchMajorMinorAverage)357 TEST_F(CapturedTouchpadEventConverterTest,
358 OneFinger_withAllSizeAxes_sizeCalculatedFromTouchMajorMinorAverage) {
359 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, 0, 4000, 0, 0, 45);
360 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, 0, 2500, 0, 0, 40);
361 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, 0, 256, 0, 0, 0);
362 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, 0, 256, 0, 0, 0);
363 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, 0, 256, 0, 0, 0);
364 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, 0, 256, 0, 0, 0);
365 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
366 DEVICE_ID);
367
368 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
369 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
370 processAxis(conv, EV_ABS, ABS_MT_TOUCH_MAJOR, 138);
371 processAxis(conv, EV_ABS, ABS_MT_TOUCH_MINOR, 118);
372 processAxis(conv, EV_ABS, ABS_MT_WIDTH_MAJOR, 200);
373 processAxis(conv, EV_ABS, ABS_MT_WIDTH_MINOR, 210);
374 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
375 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
376
377 EXPECT_NEAR(0.5,
378 processSyncAndExpectSingleMotionArg(conv).pointerCoords[0].getAxisValue(
379 AMOTION_EVENT_AXIS_SIZE),
380 EPSILON);
381 }
382
TEST_F(CapturedTouchpadEventConverterTest,OneFinger_withMajorDimensionsOnly_sizeCalculatedFromTouchMajor)383 TEST_F(CapturedTouchpadEventConverterTest,
384 OneFinger_withMajorDimensionsOnly_sizeCalculatedFromTouchMajor) {
385 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, 0, 4000, 0, 0, 45);
386 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, 0, 2500, 0, 0, 40);
387 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, 0, 256, 0, 0, 0);
388 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, 0, 256, 0, 0, 0);
389 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
390 DEVICE_ID);
391
392 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
393 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
394 processAxis(conv, EV_ABS, ABS_MT_TOUCH_MAJOR, 128);
395 processAxis(conv, EV_ABS, ABS_MT_WIDTH_MAJOR, 200);
396 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
397 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
398
399 EXPECT_NEAR(0.5,
400 processSyncAndExpectSingleMotionArg(conv).pointerCoords[0].getAxisValue(
401 AMOTION_EVENT_AXIS_SIZE),
402 EPSILON);
403 }
404
TEST_F(CapturedTouchpadEventConverterTest,OneFinger_withToolDimensionsOnly_sizeCalculatedFromToolMajorMinorAverage)405 TEST_F(CapturedTouchpadEventConverterTest,
406 OneFinger_withToolDimensionsOnly_sizeCalculatedFromToolMajorMinorAverage) {
407 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, 0, 4000, 0, 0, 45);
408 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, 0, 2500, 0, 0, 40);
409 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, 0, 256, 0, 0, 0);
410 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, 0, 256, 0, 0, 0);
411 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
412 DEVICE_ID);
413
414 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
415 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
416 processAxis(conv, EV_ABS, ABS_MT_WIDTH_MAJOR, 138);
417 processAxis(conv, EV_ABS, ABS_MT_WIDTH_MINOR, 118);
418 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
419 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
420
421 EXPECT_NEAR(0.5,
422 processSyncAndExpectSingleMotionArg(conv).pointerCoords[0].getAxisValue(
423 AMOTION_EVENT_AXIS_SIZE),
424 EPSILON);
425 }
426
TEST_F(CapturedTouchpadEventConverterTest,OneFinger_withToolMajorOnly_sizeCalculatedFromTouchMajor)427 TEST_F(CapturedTouchpadEventConverterTest,
428 OneFinger_withToolMajorOnly_sizeCalculatedFromTouchMajor) {
429 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, 0, 4000, 0, 0, 45);
430 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, 0, 2500, 0, 0, 40);
431 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, 0, 256, 0, 0, 0);
432 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
433 DEVICE_ID);
434
435 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
436 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
437 processAxis(conv, EV_ABS, ABS_MT_WIDTH_MAJOR, 128);
438 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
439 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
440
441 EXPECT_NEAR(0.5,
442 processSyncAndExpectSingleMotionArg(conv).pointerCoords[0].getAxisValue(
443 AMOTION_EVENT_AXIS_SIZE),
444 EPSILON);
445 }
446
TEST_F(CapturedTouchpadEventConverterTest,OnePalm_neverReported)447 TEST_F(CapturedTouchpadEventConverterTest, OnePalm_neverReported) {
448 addBasicAxesToEventHub();
449 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOOL_TYPE, 0, MT_TOOL_PALM, 0, 0, 0);
450 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
451 DEVICE_ID);
452
453 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
454 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
455 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 50);
456 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 100);
457 processAxis(conv, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
458 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
459 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
460
461 EXPECT_EQ(0u, processSync(conv).size());
462
463 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 51);
464
465 EXPECT_EQ(0u, processSync(conv).size());
466
467 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, -1);
468 processAxis(conv, EV_KEY, BTN_TOUCH, 0);
469 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 0);
470
471 EXPECT_EQ(0u, processSync(conv).size());
472 }
473
TEST_F(CapturedTouchpadEventConverterTest,FingerTurningIntoPalm_cancelled)474 TEST_F(CapturedTouchpadEventConverterTest, FingerTurningIntoPalm_cancelled) {
475 addBasicAxesToEventHub();
476 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOOL_TYPE, 0, MT_TOOL_PALM, 0, 0, 0);
477 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
478 DEVICE_ID);
479
480 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
481 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
482 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 50);
483 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 100);
484 processAxis(conv, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
485 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
486 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
487
488 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
489 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithToolType(ToolType::FINGER),
490 WithPointerCount(1u)));
491
492 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 51);
493 processAxis(conv, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
494
495 std::list<NotifyArgs> args = processSync(conv);
496 ASSERT_EQ(2u, args.size());
497 EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
498 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithPointerCount(1u)));
499 args.pop_front();
500 EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
501 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL), WithPointerCount(1u)));
502
503 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 52);
504
505 EXPECT_EQ(0u, processSync(conv).size());
506
507 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, -1);
508 processAxis(conv, EV_KEY, BTN_TOUCH, 0);
509 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 0);
510
511 EXPECT_EQ(0u, processSync(conv).size());
512 }
513
TEST_F(CapturedTouchpadEventConverterTest,PalmTurningIntoFinger_reported)514 TEST_F(CapturedTouchpadEventConverterTest, PalmTurningIntoFinger_reported) {
515 addBasicAxesToEventHub();
516 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOOL_TYPE, 0, MT_TOOL_PALM, 0, 0, 0);
517 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
518 DEVICE_ID);
519
520 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
521 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
522 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 50);
523 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 100);
524 processAxis(conv, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
525 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
526 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
527
528 EXPECT_EQ(0u, processSync(conv).size());
529
530 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 51);
531 processAxis(conv, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
532
533 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
534 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPointerCount(1u),
535 WithCoords(51, 100), WithRelativeMotion(0, 0)));
536
537 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 52);
538
539 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
540 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithPointerCount(1u),
541 WithCoords(52, 100), WithRelativeMotion(1, 0)));
542 }
543
TEST_F(CapturedTouchpadEventConverterTest,FingerArrivingAfterPalm_onlyFingerReported)544 TEST_F(CapturedTouchpadEventConverterTest, FingerArrivingAfterPalm_onlyFingerReported) {
545 addBasicAxesToEventHub();
546 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOOL_TYPE, 0, MT_TOOL_PALM, 0, 0, 0);
547 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
548 DEVICE_ID);
549
550 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
551 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
552 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 50);
553 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 100);
554 processAxis(conv, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
555 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
556 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
557
558 EXPECT_EQ(0u, processSync(conv).size());
559
560 processAxis(conv, EV_ABS, ABS_MT_SLOT, 1);
561 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 2);
562 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 100);
563 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 150);
564 processAxis(conv, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
565 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 0);
566 processAxis(conv, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
567
568 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
569 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPointerCount(1u),
570 WithCoords(100, 150)));
571
572 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
573 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 52);
574 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 102);
575 processAxis(conv, EV_ABS, ABS_MT_SLOT, 1);
576 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 98);
577 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 148);
578
579 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
580 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithPointerCount(1u),
581 WithCoords(98, 148), WithRelativeMotion(-2, -2)));
582 }
583
TEST_F(CapturedTouchpadEventConverterTest,FingerAndFingerTurningIntoPalm_partiallyCancelled)584 TEST_F(CapturedTouchpadEventConverterTest, FingerAndFingerTurningIntoPalm_partiallyCancelled) {
585 addBasicAxesToEventHub();
586 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOOL_TYPE, 0, MT_TOOL_PALM, 0, 0, 0);
587 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
588 DEVICE_ID);
589
590 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
591 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
592 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 50);
593 processAxis(conv, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
594
595 processAxis(conv, EV_ABS, ABS_MT_SLOT, 1);
596 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 2);
597 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 250);
598 processAxis(conv, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
599
600 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
601 processAxis(conv, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
602
603 EXPECT_THAT(processSync(conv),
604 ElementsAre(VariantWith<NotifyMotionArgs>(
605 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
606 WithPointerCount(1u), WithToolType(ToolType::FINGER))),
607 VariantWith<NotifyMotionArgs>(
608 AllOf(WithMotionAction(
609 AMOTION_EVENT_ACTION_POINTER_DOWN |
610 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
611 WithPointerCount(2u),
612 WithPointerToolType(0, ToolType::FINGER),
613 WithPointerToolType(1, ToolType::FINGER)))));
614
615 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
616 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 51);
617
618 processAxis(conv, EV_ABS, ABS_MT_SLOT, 1);
619 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 251);
620 processAxis(conv, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
621
622 std::list<NotifyArgs> args = processSync(conv);
623 EXPECT_THAT(args,
624 ElementsAre(VariantWith<NotifyMotionArgs>(
625 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)),
626 VariantWith<NotifyMotionArgs>(
627 AllOf(WithMotionAction(
628 AMOTION_EVENT_ACTION_POINTER_UP |
629 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
630 WithFlags(AMOTION_EVENT_FLAG_CANCELED)))));
631 EXPECT_THAT(args, Each(VariantWith<NotifyMotionArgs>(WithPointerCount(2u))));
632 }
633
TEST_F(CapturedTouchpadEventConverterTest,FingerAndPalmTurningIntoFinger_reported)634 TEST_F(CapturedTouchpadEventConverterTest, FingerAndPalmTurningIntoFinger_reported) {
635 addBasicAxesToEventHub();
636 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOOL_TYPE, 0, MT_TOOL_PALM, 0, 0, 0);
637 CapturedTouchpadEventConverter conv(*mReader.getContext(), mDeviceContext, mAccumulator,
638 DEVICE_ID);
639
640 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
641 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
642 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 50);
643 processAxis(conv, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
644
645 processAxis(conv, EV_ABS, ABS_MT_SLOT, 1);
646 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 2);
647 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 250);
648 processAxis(conv, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
649
650 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
651 processAxis(conv, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
652
653 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
654 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPointerCount(1u),
655 WithToolType(ToolType::FINGER)));
656
657 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
658 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 51);
659
660 processAxis(conv, EV_ABS, ABS_MT_SLOT, 1);
661 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 251);
662 processAxis(conv, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
663
664 EXPECT_THAT(processSync(conv),
665 ElementsAre(VariantWith<NotifyMotionArgs>(
666 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
667 WithPointerCount(1u))),
668 VariantWith<NotifyMotionArgs>(
669 AllOf(WithMotionAction(
670 AMOTION_EVENT_ACTION_POINTER_DOWN |
671 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
672 WithPointerCount(2u)))));
673 }
674
TEST_F(CapturedTouchpadEventConverterTest,TwoFingers_motionReportedCorrectly)675 TEST_F(CapturedTouchpadEventConverterTest, TwoFingers_motionReportedCorrectly) {
676 CapturedTouchpadEventConverter conv = createConverter();
677
678 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
679 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
680 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 50);
681 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 100);
682
683 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
684 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
685
686 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
687 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPointerCount(1u),
688 WithCoords(50, 100), WithRelativeMotion(0, 0),
689 WithToolType(ToolType::FINGER)));
690
691 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
692 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 52);
693 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 99);
694
695 processAxis(conv, EV_ABS, ABS_MT_SLOT, 1);
696 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 2);
697 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 250);
698 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 200);
699
700 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 0);
701 processAxis(conv, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
702
703 EXPECT_THAT(processSync(conv),
704 ElementsAre(VariantWith<NotifyMotionArgs>(
705 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
706 WithPointerCount(1u), WithCoords(52, 99),
707 WithRelativeMotion(2, -1),
708 WithToolType(ToolType::FINGER))),
709 VariantWith<NotifyMotionArgs>(
710 AllOf(WithMotionAction(
711 AMOTION_EVENT_ACTION_POINTER_DOWN |
712 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
713 WithPointerCount(2u), WithPointerCoords(0, 52, 99),
714 WithPointerRelativeMotion(0, 0, 0),
715 WithPointerCoords(1, 250, 200),
716 WithPointerRelativeMotion(1, 0, 0),
717 WithPointerToolType(0, ToolType::FINGER),
718 WithPointerToolType(1, ToolType::FINGER)))));
719
720 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
721 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, -1);
722 processAxis(conv, EV_ABS, ABS_MT_SLOT, 1);
723 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 255);
724 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 202);
725
726 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
727 processAxis(conv, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
728
729 std::list<NotifyArgs> args = processSync(conv);
730 EXPECT_THAT(args,
731 ElementsAre(VariantWith<NotifyMotionArgs>(
732 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
733 WithPointerRelativeMotion(1, 5, 2))),
734 VariantWith<NotifyMotionArgs>(
735 AllOf(WithMotionAction(
736 AMOTION_EVENT_ACTION_POINTER_UP |
737 0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
738 WithPointerRelativeMotion(1, 0, 0)))));
739 EXPECT_THAT(args,
740 Each(VariantWith<NotifyMotionArgs>(
741 AllOf(WithPointerCount(2u), WithPointerCoords(0, 52, 99),
742 WithPointerRelativeMotion(0, 0, 0), WithPointerCoords(1, 255, 202),
743 WithPointerToolType(1, ToolType::FINGER),
744 WithPointerToolType(0, ToolType::FINGER)))));
745
746 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, -1);
747 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 0);
748 processAxis(conv, EV_KEY, BTN_TOUCH, 0);
749
750 args = processSync(conv);
751 EXPECT_THAT(args,
752 ElementsAre(VariantWith<NotifyMotionArgs>(
753 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)),
754 VariantWith<NotifyMotionArgs>(
755 WithMotionAction(AMOTION_EVENT_ACTION_UP))));
756 EXPECT_THAT(args,
757 Each(VariantWith<NotifyMotionArgs>(AllOf(WithPointerCount(1u), WithCoords(255, 202),
758 WithRelativeMotion(0, 0),
759 WithToolType(ToolType::FINGER)))));
760 }
761
TEST_F(CapturedTouchpadEventConverterTest,RelativeMotionAxesClearedForNewFingerInSlot)762 TEST_F(CapturedTouchpadEventConverterTest, RelativeMotionAxesClearedForNewFingerInSlot) {
763 CapturedTouchpadEventConverter conv = createConverter();
764 // Put down one finger.
765 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
766 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
767 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 50);
768 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 100);
769
770 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
771 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
772
773 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
774 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPointerCount(1u),
775 WithCoords(50, 100), WithRelativeMotion(0, 0)));
776
777 // Move it in negative X and Y directions.
778 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 47);
779 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 97);
780
781 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
782 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithCoords(47, 97),
783 WithRelativeMotion(-3, -3)));
784
785 // Lift it.
786 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, -1);
787 processAxis(conv, EV_KEY, BTN_TOUCH, 0);
788 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 0);
789
790 std::list<NotifyArgs> args = processSync(conv);
791 EXPECT_THAT(args,
792 ElementsAre(VariantWith<NotifyMotionArgs>(
793 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)),
794 VariantWith<NotifyMotionArgs>(
795 WithMotionAction(AMOTION_EVENT_ACTION_UP))));
796 EXPECT_THAT(args,
797 Each(VariantWith<NotifyMotionArgs>(AllOf(WithCoords(47, 97),
798 WithRelativeMotion(0, 0),
799 WithPointerCount(1u)))));
800
801 // Put down another finger using the same slot. Relative axis values should be cleared.
802 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 2);
803 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 60);
804 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 60);
805
806 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
807 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
808
809 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
810 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPointerCount(1u),
811 WithCoords(60, 60), WithRelativeMotion(0, 0)));
812
813 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 64);
814 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 58);
815
816 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
817 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithPointerCount(1u),
818 WithCoords(64, 58), WithRelativeMotion(4, -2)));
819 }
820
821 // Pointer IDs max out at 31, and so must be reused once a touch is lifted to avoid running out.
TEST_F(CapturedTouchpadEventConverterTest,PointerIdsReusedAfterLift)822 TEST_F(CapturedTouchpadEventConverterTest, PointerIdsReusedAfterLift) {
823 CapturedTouchpadEventConverter conv = createConverter();
824
825 // Put down two fingers, which should get IDs 0 and 1.
826 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
827 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
828 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 10);
829 processAxis(conv, EV_ABS, ABS_MT_SLOT, 1);
830 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 2);
831 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 20);
832
833 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
834 processAxis(conv, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
835
836 EXPECT_THAT(processSync(conv),
837 ElementsAre(VariantWith<NotifyMotionArgs>(
838 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
839 WithPointerCount(1u),
840 WithPointerId(/*index=*/0, /*id=*/0))),
841 VariantWith<NotifyMotionArgs>(
842 AllOf(WithMotionAction(
843 AMOTION_EVENT_ACTION_POINTER_DOWN |
844 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
845 WithPointerCount(2u),
846 WithPointerId(/*index=*/0, /*id=*/0),
847 WithPointerId(/*index=*/1, /*id=*/1)))));
848
849 // Lift the finger in slot 0, freeing up pointer ID 0...
850 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
851 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, -1);
852
853 // ...and simultaneously add a finger in slot 2.
854 processAxis(conv, EV_ABS, ABS_MT_SLOT, 2);
855 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 3);
856 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 30);
857
858 std::list<NotifyArgs> args = processSync(conv);
859 // Slot 1 being present will result in a MOVE event, even though it hasn't actually moved (see
860 // comments in CapturedTouchpadEventConverter::sync).
861 EXPECT_THAT(args,
862 ElementsAre(VariantWith<NotifyMotionArgs>(
863 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
864 WithPointerId(/*index=*/0, /*id=*/0),
865 WithPointerId(/*index=*/1, /*id=*/1))),
866 VariantWith<NotifyMotionArgs>(
867 AllOf(WithMotionAction(
868 AMOTION_EVENT_ACTION_POINTER_UP |
869 0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
870 WithPointerId(/*index=*/0, /*id=*/0),
871 WithPointerId(/*index=*/1, /*id=*/1))),
872 // Slot 0 being lifted causes the finger from slot 1 to move up to index
873 // 0, but keep its previous ID. The new finger in slot 2 should take ID
874 // 0, which was just freed up.
875 VariantWith<NotifyMotionArgs>(
876 AllOf(WithMotionAction(
877 AMOTION_EVENT_ACTION_POINTER_DOWN |
878 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
879 WithPointerId(/*index=*/0, /*id=*/1),
880 WithPointerId(/*index=*/1, /*id=*/0)))));
881 EXPECT_THAT(args, Each(VariantWith<NotifyMotionArgs>(WithPointerCount(2u))));
882 }
883
884 // Motion events without any pointers are invalid, so when a button press is reported in the same
885 // frame as a touch down, the button press must be reported second. Similarly with a button release
886 // and a touch lift.
TEST_F(CapturedTouchpadEventConverterTest,ButtonPressedAndReleasedInSameFrameAsTouch_ReportedWithPointers)887 TEST_F(CapturedTouchpadEventConverterTest,
888 ButtonPressedAndReleasedInSameFrameAsTouch_ReportedWithPointers) {
889 CapturedTouchpadEventConverter conv = createConverter();
890
891 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
892 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
893 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 50);
894 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 100);
895 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
896 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
897
898 processAxis(conv, EV_KEY, BTN_LEFT, 1);
899
900 EXPECT_THAT(processSync(conv),
901 ElementsAre(VariantWith<NotifyMotionArgs>(
902 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)),
903 VariantWith<NotifyMotionArgs>(
904 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
905 WithPointerCount(1u), WithCoords(50, 100),
906 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
907 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY)))));
908
909 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, -1);
910 processAxis(conv, EV_KEY, BTN_TOUCH, 0);
911 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 0);
912
913 processAxis(conv, EV_KEY, BTN_LEFT, 0);
914 EXPECT_THAT(processSync(conv),
915 ElementsAre(VariantWith<NotifyMotionArgs>(
916 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)),
917 VariantWith<NotifyMotionArgs>(
918 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
919 WithPointerCount(1u), WithCoords(50, 100),
920 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
921 WithButtonState(0))),
922 VariantWith<NotifyMotionArgs>(
923 WithMotionAction(AMOTION_EVENT_ACTION_UP))));
924 }
925
926 // Some touchpads sometimes report a button press before they report the finger touching the pad. In
927 // that case we need to wait until the touch comes to report the button press.
TEST_F(CapturedTouchpadEventConverterTest,ButtonPressedBeforeTouch_ReportedOnceTouchOccurs)928 TEST_F(CapturedTouchpadEventConverterTest, ButtonPressedBeforeTouch_ReportedOnceTouchOccurs) {
929 CapturedTouchpadEventConverter conv = createConverter();
930
931 processAxis(conv, EV_KEY, BTN_LEFT, 1);
932 ASSERT_EQ(0u, processSync(conv).size());
933
934 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
935 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
936 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 50);
937 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 100);
938 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
939 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
940
941 EXPECT_THAT(processSync(conv),
942 ElementsAre(VariantWith<NotifyMotionArgs>(
943 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)),
944 VariantWith<NotifyMotionArgs>(
945 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
946 WithPointerCount(1u), WithCoords(50, 100),
947 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
948 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY)))));
949 }
950
951 // When all fingers are lifted from a touchpad, we should release any buttons that are down, since
952 // we won't be able to report them being lifted later if no pointers are present.
TEST_F(CapturedTouchpadEventConverterTest,ButtonReleasedAfterTouchLifts_ReportedWithLift)953 TEST_F(CapturedTouchpadEventConverterTest, ButtonReleasedAfterTouchLifts_ReportedWithLift) {
954 CapturedTouchpadEventConverter conv = createConverter();
955
956 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
957 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
958 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 50);
959 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 100);
960 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
961 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
962
963 processAxis(conv, EV_KEY, BTN_LEFT, 1);
964
965 EXPECT_THAT(processSync(conv),
966 ElementsAre(VariantWith<NotifyMotionArgs>(
967 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)),
968 VariantWith<NotifyMotionArgs>(
969 WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS))));
970
971 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, -1);
972 processAxis(conv, EV_KEY, BTN_TOUCH, 0);
973 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 0);
974 EXPECT_THAT(processSync(conv),
975 ElementsAre(VariantWith<NotifyMotionArgs>(
976 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)),
977 VariantWith<NotifyMotionArgs>(
978 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
979 WithPointerCount(1u), WithCoords(50, 100),
980 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
981 WithButtonState(0))),
982 VariantWith<NotifyMotionArgs>(
983 WithMotionAction(AMOTION_EVENT_ACTION_UP))));
984
985 processAxis(conv, EV_KEY, BTN_LEFT, 0);
986 ASSERT_EQ(0u, processSync(conv).size());
987 }
988
TEST_F(CapturedTouchpadEventConverterTest,MultipleButtonsPressedDuringTouch_ReportedCorrectly)989 TEST_F(CapturedTouchpadEventConverterTest, MultipleButtonsPressedDuringTouch_ReportedCorrectly) {
990 CapturedTouchpadEventConverter conv = createConverter();
991
992 processAxis(conv, EV_ABS, ABS_MT_SLOT, 0);
993 processAxis(conv, EV_ABS, ABS_MT_TRACKING_ID, 1);
994 processAxis(conv, EV_ABS, ABS_MT_POSITION_X, 50);
995 processAxis(conv, EV_ABS, ABS_MT_POSITION_Y, 100);
996 processAxis(conv, EV_KEY, BTN_TOUCH, 1);
997 processAxis(conv, EV_KEY, BTN_TOOL_FINGER, 1);
998
999 EXPECT_THAT(processSyncAndExpectSingleMotionArg(conv),
1000 WithMotionAction(AMOTION_EVENT_ACTION_DOWN));
1001
1002 processAxis(conv, EV_KEY, BTN_LEFT, 1);
1003 EXPECT_THAT(processSync(conv),
1004 ElementsAre(VariantWith<NotifyMotionArgs>(
1005 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)),
1006 VariantWith<NotifyMotionArgs>(
1007 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
1008 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
1009 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY)))));
1010
1011 processAxis(conv, EV_KEY, BTN_RIGHT, 1);
1012 EXPECT_THAT(processSync(conv),
1013 ElementsAre(VariantWith<NotifyMotionArgs>(
1014 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)),
1015 VariantWith<NotifyMotionArgs>(
1016 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
1017 WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY),
1018 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
1019 AMOTION_EVENT_BUTTON_SECONDARY)))));
1020
1021 processAxis(conv, EV_KEY, BTN_LEFT, 0);
1022 EXPECT_THAT(processSync(conv),
1023 ElementsAre(VariantWith<NotifyMotionArgs>(
1024 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)),
1025 VariantWith<NotifyMotionArgs>(
1026 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
1027 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
1028 WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY)))));
1029
1030 processAxis(conv, EV_KEY, BTN_RIGHT, 0);
1031 EXPECT_THAT(processSync(conv),
1032 ElementsAre(VariantWith<NotifyMotionArgs>(
1033 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)),
1034 VariantWith<NotifyMotionArgs>(
1035 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
1036 WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY),
1037 WithButtonState(0)))));
1038 }
1039
1040 } // namespace android
1041