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