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