• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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