1 /*
2 * Copyright 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <memory>
18
19 #include <com_android_input_flags.h>
20 #include <flag_macros.h>
21 #include <gestures/GestureConverter.h>
22 #include <gtest/gtest.h>
23
24 #include "FakeEventHub.h"
25 #include "FakeInputReaderPolicy.h"
26 #include "FakePointerController.h"
27 #include "InstrumentedInputReader.h"
28 #include "NotifyArgs.h"
29 #include "TestConstants.h"
30 #include "TestEventMatchers.h"
31 #include "TestInputListener.h"
32 #include "include/gestures.h"
33 #include "ui/Rotation.h"
34
35 namespace android {
36
37 namespace input_flags = com::android::input::flags;
38
39 namespace {
40
41 const auto TOUCHPAD_PALM_REJECTION =
42 ACONFIG_FLAG(input_flags, enable_touchpad_typing_palm_rejection);
43 const auto TOUCHPAD_PALM_REJECTION_V2 =
44 ACONFIG_FLAG(input_flags, enable_v2_touchpad_typing_palm_rejection);
45
46 } // namespace
47
48 using testing::AllOf;
49 using testing::Each;
50 using testing::ElementsAre;
51 using testing::IsEmpty;
52 using testing::VariantWith;
53
54 class GestureConverterTest : public testing::Test {
55 protected:
56 static constexpr int32_t DEVICE_ID = END_RESERVED_ID + 1000;
57 static constexpr int32_t EVENTHUB_ID = 1;
58 static constexpr stime_t ARBITRARY_GESTURE_TIME = 1.2;
59
SetUp()60 void SetUp() {
61 mFakeEventHub = std::make_unique<FakeEventHub>();
62 mFakePolicy = sp<FakeInputReaderPolicy>::make();
63 mFakeListener = std::make_unique<TestInputListener>();
64 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
65 *mFakeListener);
66 mDevice = newDevice();
67 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, -500, 500, 0, 0, 20);
68 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, -500, 500, 0, 0, 20);
69 }
70
newDevice()71 std::shared_ptr<InputDevice> newDevice() {
72 InputDeviceIdentifier identifier;
73 identifier.name = "device";
74 identifier.location = "USB1";
75 identifier.bus = 0;
76 std::shared_ptr<InputDevice> device =
77 std::make_shared<InputDevice>(mReader->getContext(), DEVICE_ID, /* generation= */ 2,
78 identifier);
79 mReader->pushNextDevice(device);
80 mFakeEventHub->addDevice(EVENTHUB_ID, identifier.name, InputDeviceClass::TOUCHPAD,
81 identifier.bus);
82 mReader->loopOnce();
83 return device;
84 }
85
86 std::shared_ptr<FakeEventHub> mFakeEventHub;
87 sp<FakeInputReaderPolicy> mFakePolicy;
88 std::unique_ptr<TestInputListener> mFakeListener;
89 std::unique_ptr<InstrumentedInputReader> mReader;
90 std::shared_ptr<InputDevice> mDevice;
91 };
92
TEST_F(GestureConverterTest,Move)93 TEST_F(GestureConverterTest, Move) {
94 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
95 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
96 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
97
98 Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
99 std::list<NotifyArgs> args =
100 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
101 ASSERT_THAT(args,
102 ElementsAre(VariantWith<NotifyMotionArgs>(
103 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
104 WithRelativeMotion(0, 0))),
105 VariantWith<NotifyMotionArgs>(
106 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
107 WithRelativeMotion(-5, 10), WithButtonState(0),
108 WithPressure(0.0f)))));
109 ASSERT_THAT(args,
110 Each(VariantWith<NotifyMotionArgs>(
111 AllOf(WithCoords(0, 0), WithToolType(ToolType::FINGER),
112 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
113
114 // The same gesture again should only repeat the HOVER_MOVE, not the HOVER_ENTER.
115 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
116 ASSERT_THAT(args,
117 ElementsAre(VariantWith<NotifyMotionArgs>(
118 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
119 WithRelativeMotion(-5, 10), WithToolType(ToolType::FINGER),
120 WithButtonState(0), WithPressure(0.0f),
121 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
122 }
123
TEST_F(GestureConverterTest,Move_Rotated)124 TEST_F(GestureConverterTest, Move_Rotated) {
125 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
126 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
127 converter.setOrientation(ui::ROTATION_90);
128 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
129
130 Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
131 std::list<NotifyArgs> args =
132 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
133 ASSERT_THAT(args,
134 ElementsAre(VariantWith<NotifyMotionArgs>(
135 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
136 WithRelativeMotion(0, 0))),
137 VariantWith<NotifyMotionArgs>(
138 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
139 WithRelativeMotion(10, 5), WithButtonState(0),
140 WithPressure(0.0f)))));
141 ASSERT_THAT(args,
142 Each(VariantWith<NotifyMotionArgs>(
143 AllOf(WithCoords(0, 0), WithToolType(ToolType::FINGER),
144 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
145 }
146
TEST_F(GestureConverterTest,ButtonsChange)147 TEST_F(GestureConverterTest, ButtonsChange) {
148 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
149 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
150 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
151
152 // Press left and right buttons at once
153 Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
154 /* down= */ GESTURES_BUTTON_LEFT | GESTURES_BUTTON_RIGHT,
155 /* up= */ GESTURES_BUTTON_NONE, /* is_tap= */ false);
156 std::list<NotifyArgs> args =
157 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, downGesture);
158 ASSERT_THAT(args,
159 ElementsAre(VariantWith<NotifyMotionArgs>(
160 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
161 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
162 AMOTION_EVENT_BUTTON_SECONDARY))),
163 VariantWith<NotifyMotionArgs>(
164 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
165 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
166 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY))),
167 VariantWith<NotifyMotionArgs>(
168 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
169 WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY),
170 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
171 AMOTION_EVENT_BUTTON_SECONDARY)))));
172 ASSERT_THAT(args,
173 Each(VariantWith<NotifyMotionArgs>(
174 AllOf(WithCoords(0, 0), WithToolType(ToolType::FINGER),
175 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
176
177 // Then release the left button
178 Gesture leftUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
179 /* down= */ GESTURES_BUTTON_NONE, /* up= */ GESTURES_BUTTON_LEFT,
180 /* is_tap= */ false);
181 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, leftUpGesture);
182 ASSERT_THAT(args,
183 ElementsAre(VariantWith<NotifyMotionArgs>(
184 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
185 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
186 WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY), WithCoords(0, 0),
187 WithToolType(ToolType::FINGER),
188 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
189
190 // Finally release the right button
191 Gesture rightUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
192 /* down= */ GESTURES_BUTTON_NONE, /* up= */ GESTURES_BUTTON_RIGHT,
193 /* is_tap= */ false);
194 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, rightUpGesture);
195 ASSERT_THAT(args,
196 ElementsAre(VariantWith<NotifyMotionArgs>(
197 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
198 WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY))),
199 VariantWith<NotifyMotionArgs>(
200 WithMotionAction(AMOTION_EVENT_ACTION_UP)),
201 VariantWith<NotifyMotionArgs>(
202 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER))));
203 ASSERT_THAT(args,
204 Each(VariantWith<NotifyMotionArgs>(
205 AllOf(WithButtonState(0), WithCoords(0, 0), WithToolType(ToolType::FINGER),
206 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
207 }
208
TEST_F(GestureConverterTest,ButtonDownAfterMoveExitsHover)209 TEST_F(GestureConverterTest, ButtonDownAfterMoveExitsHover) {
210 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
211 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
212 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
213
214 Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
215 std::list<NotifyArgs> args =
216 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
217
218 Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
219 /*down=*/GESTURES_BUTTON_LEFT, /*up=*/GESTURES_BUTTON_NONE,
220 /*is_tap=*/false);
221 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, downGesture);
222 ASSERT_THAT(args.front(),
223 VariantWith<NotifyMotionArgs>(
224 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT), WithButtonState(0),
225 WithCoords(0, 0), WithToolType(ToolType::FINGER),
226 WithDisplayId(ui::LogicalDisplayId::DEFAULT))));
227 }
228
TEST_F(GestureConverterTest,DragWithButton)229 TEST_F(GestureConverterTest, DragWithButton) {
230 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
231 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
232 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
233
234 // Press the button
235 Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
236 /* down= */ GESTURES_BUTTON_LEFT, /* up= */ GESTURES_BUTTON_NONE,
237 /* is_tap= */ false);
238 std::list<NotifyArgs> args =
239 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, downGesture);
240 ASSERT_THAT(args,
241 ElementsAre(VariantWith<NotifyMotionArgs>(
242 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
243 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY))),
244 VariantWith<NotifyMotionArgs>(
245 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
246 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
247 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY)))));
248 ASSERT_THAT(args,
249 Each(VariantWith<NotifyMotionArgs>(
250 AllOf(WithCoords(0, 0), WithToolType(ToolType::FINGER),
251 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
252
253 // Move
254 Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
255 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
256 ASSERT_THAT(args,
257 ElementsAre(VariantWith<NotifyMotionArgs>(
258 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithCoords(0, 0),
259 WithRelativeMotion(-5, 10), WithToolType(ToolType::FINGER),
260 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
261 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
262
263 // Release the button
264 Gesture upGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
265 /* down= */ GESTURES_BUTTON_NONE, /* up= */ GESTURES_BUTTON_LEFT,
266 /* is_tap= */ false);
267 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, upGesture);
268 ASSERT_THAT(args,
269 ElementsAre(VariantWith<NotifyMotionArgs>(
270 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
271 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY))),
272 VariantWith<NotifyMotionArgs>(
273 WithMotionAction(AMOTION_EVENT_ACTION_UP)),
274 VariantWith<NotifyMotionArgs>(
275 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER))));
276 ASSERT_THAT(args,
277 Each(VariantWith<NotifyMotionArgs>(
278 AllOf(WithButtonState(0), WithCoords(0, 0), WithToolType(ToolType::FINGER),
279 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
280 }
281
TEST_F(GestureConverterTest,Scroll)282 TEST_F(GestureConverterTest, Scroll) {
283 input_flags::enable_touchpad_no_focus_change(true);
284
285 const nsecs_t downTime = 12345;
286 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
287 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
288 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
289
290 Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
291 std::list<NotifyArgs> args =
292 converter.handleGesture(downTime, READ_TIME, ARBITRARY_TIME, startGesture);
293 ASSERT_THAT(args,
294 ElementsAre(VariantWith<NotifyMotionArgs>(
295 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
296 WithCoords(0, 0),
297 WithGestureScrollDistance(0, 0, EPSILON),
298 WithDownTime(downTime))),
299 VariantWith<NotifyMotionArgs>(
300 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
301 WithCoords(0, -10),
302 WithGestureScrollDistance(0, 10, EPSILON)))));
303 ASSERT_THAT(args,
304 Each(VariantWith<NotifyMotionArgs>(
305 AllOf(WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
306 WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE |
307 AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE),
308 WithToolType(ToolType::FINGER),
309 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
310
311 Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
312 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
313 ASSERT_THAT(args,
314 ElementsAre(VariantWith<NotifyMotionArgs>(
315 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithCoords(0, -15),
316 WithGestureScrollDistance(0, 5, EPSILON),
317 WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
318 WithToolType(ToolType::FINGER),
319 WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE |
320 AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE),
321 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
322
323 Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
324 GESTURES_FLING_START);
325 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
326 ASSERT_THAT(args,
327 ElementsAre(VariantWith<NotifyMotionArgs>(
328 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
329 WithCoords(0, -15),
330 WithGestureScrollDistance(0, 0, EPSILON),
331 WithMotionClassification(
332 MotionClassification::TWO_FINGER_SWIPE),
333 WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE |
334 AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE))),
335 VariantWith<NotifyMotionArgs>(
336 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
337 WithCoords(0, 0),
338 WithMotionClassification(MotionClassification::NONE)))));
339 ASSERT_THAT(args,
340 Each(VariantWith<NotifyMotionArgs>(
341 AllOf(WithToolType(ToolType::FINGER),
342 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
343 }
344
TEST_F(GestureConverterTest,Scroll_Rotated)345 TEST_F(GestureConverterTest, Scroll_Rotated) {
346 const nsecs_t downTime = 12345;
347 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
348 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
349 converter.setOrientation(ui::ROTATION_90);
350 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
351
352 Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
353 std::list<NotifyArgs> args =
354 converter.handleGesture(downTime, READ_TIME, ARBITRARY_TIME, startGesture);
355 ASSERT_THAT(args,
356 ElementsAre(VariantWith<NotifyMotionArgs>(
357 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
358 WithCoords(0, 0),
359 WithGestureScrollDistance(0, 0, EPSILON),
360 WithDownTime(downTime))),
361 VariantWith<NotifyMotionArgs>(
362 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
363 WithCoords(-10, 0),
364 WithGestureScrollDistance(0, 10, EPSILON)))));
365 ASSERT_THAT(args,
366 Each(VariantWith<NotifyMotionArgs>(
367 AllOf(WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
368 WithToolType(ToolType::FINGER),
369 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
370
371 Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
372 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
373 ASSERT_THAT(args,
374 ElementsAre(VariantWith<NotifyMotionArgs>(
375 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithCoords(-15, 0),
376 WithGestureScrollDistance(0, 5, EPSILON),
377 WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
378 WithToolType(ToolType::FINGER),
379 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
380
381 Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
382 GESTURES_FLING_START);
383 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
384 ASSERT_THAT(args,
385 ElementsAre(VariantWith<NotifyMotionArgs>(
386 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
387 WithCoords(-15, 0),
388 WithGestureScrollDistance(0, 0, EPSILON),
389 WithMotionClassification(
390 MotionClassification::TWO_FINGER_SWIPE))),
391 VariantWith<NotifyMotionArgs>(
392 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
393 WithCoords(0, 0),
394 WithMotionClassification(MotionClassification::NONE)))));
395 ASSERT_THAT(args,
396 Each(VariantWith<NotifyMotionArgs>(
397 AllOf(WithToolType(ToolType::FINGER),
398 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
399 }
400
TEST_F(GestureConverterTest,Scroll_ClearsClassificationAfterGesture)401 TEST_F(GestureConverterTest, Scroll_ClearsClassificationAfterGesture) {
402 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
403 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
404 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
405
406 Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
407 std::list<NotifyArgs> args =
408 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
409
410 Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
411 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
412
413 Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
414 GESTURES_FLING_START);
415 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
416
417 Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
418 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
419 ASSERT_THAT(args,
420 ElementsAre(VariantWith<NotifyMotionArgs>(
421 AllOf(WithMotionClassification(MotionClassification::NONE),
422 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
423 }
424
TEST_F(GestureConverterTest,Scroll_ClearsScrollDistanceAfterGesture)425 TEST_F(GestureConverterTest, Scroll_ClearsScrollDistanceAfterGesture) {
426 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
427 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
428 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
429
430 Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
431 std::list<NotifyArgs> args =
432 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
433
434 Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
435 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
436
437 Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
438 GESTURES_FLING_START);
439 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
440
441 // Move gestures don't use the fake finger array, so to test that gesture axes are cleared we
442 // need to use another gesture type, like pinch.
443 Gesture pinchGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
444 GESTURES_ZOOM_START);
445 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, pinchGesture);
446 ASSERT_FALSE(args.empty());
447 EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), WithGestureScrollDistance(0, 0, EPSILON));
448 }
449
TEST_F(GestureConverterTest,Scroll_ClearsFakeFingerPositionOnSubsequentScrollGestures)450 TEST_F(GestureConverterTest, Scroll_ClearsFakeFingerPositionOnSubsequentScrollGestures) {
451 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
452 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
453 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
454
455 Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 15, -10);
456 std::list<NotifyArgs> args =
457 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
458
459 Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -2, -5);
460 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
461
462 Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
463 GESTURES_FLING_START);
464 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
465 Gesture flingGestureEnd(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, 0,
466 GESTURES_FLING_TAP_DOWN);
467 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGestureEnd);
468
469 // Start a second scoll gesture, and ensure the fake finger is reset to (0, 0), instead of
470 // continuing from the position where the last scroll gesture's fake finger ended.
471 Gesture secondScrollStart(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 2,
472 14);
473 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, secondScrollStart);
474 ASSERT_THAT(args,
475 ElementsAre(VariantWith<NotifyMotionArgs>(
476 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT)),
477 VariantWith<NotifyMotionArgs>(
478 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
479 WithCoords(0, 0),
480 WithGestureScrollDistance(0, 0, EPSILON))),
481 VariantWith<NotifyMotionArgs>(
482 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
483 WithCoords(2, 14),
484 WithGestureScrollDistance(-2, -14, EPSILON)))));
485 }
486
TEST_F(GestureConverterTest,ThreeFingerSwipe_ClearsClassificationAfterGesture)487 TEST_F(GestureConverterTest, ThreeFingerSwipe_ClearsClassificationAfterGesture) {
488 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
489 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
490 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
491
492 Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
493 /*dy=*/0);
494 std::list<NotifyArgs> args =
495 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
496
497 Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
498 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
499
500 Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/-5,
501 /*dy=*/10);
502 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
503 ASSERT_THAT(args,
504 ElementsAre(VariantWith<NotifyMotionArgs>(
505 WithMotionClassification(MotionClassification::NONE))));
506 }
507
TEST_F(GestureConverterTest,ThreeFingerSwipe_ClearsGestureAxesAfterGesture)508 TEST_F(GestureConverterTest, ThreeFingerSwipe_ClearsGestureAxesAfterGesture) {
509 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
510 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
511 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
512
513 Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/5,
514 /*dy=*/5);
515 std::list<NotifyArgs> args =
516 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
517
518 Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
519 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
520
521 // Move gestures don't use the fake finger array, so to test that gesture axes are cleared we
522 // need to use another gesture type, like pinch.
523 Gesture pinchGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
524 GESTURES_ZOOM_START);
525 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, pinchGesture);
526 ASSERT_FALSE(args.empty());
527 EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
528 AllOf(WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(0)));
529 }
530
TEST_F(GestureConverterTest,ThreeFingerSwipe_Vertical)531 TEST_F(GestureConverterTest, ThreeFingerSwipe_Vertical) {
532 // The gestures library will "lock" a swipe into the dimension it starts in. For example, if you
533 // start swiping up and then start moving left or right, it'll return gesture events with only Y
534 // deltas until you lift your fingers and start swiping again. That's why each of these tests
535 // only checks movement in one dimension.
536 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
537 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
538 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
539
540 Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dx= */ 0,
541 /* dy= */ 10);
542 std::list<NotifyArgs> args =
543 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
544 ASSERT_EQ(4u, args.size());
545 ASSERT_THAT(args,
546 Each(VariantWith<NotifyMotionArgs>(
547 AllOf(WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
548 WithGestureSwipeFingerCount(3), WithToolType(ToolType::FINGER),
549 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
550
551 // Three fake fingers should be created. We don't actually care where they are, so long as they
552 // move appropriately.
553 NotifyMotionArgs arg = std::get<NotifyMotionArgs>(args.front());
554 ASSERT_THAT(arg,
555 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithGestureOffset(0, 0, EPSILON),
556 WithPointerCount(1u)));
557 PointerCoords finger0Start = arg.pointerCoords[0];
558 args.pop_front();
559 arg = std::get<NotifyMotionArgs>(args.front());
560 ASSERT_THAT(arg,
561 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
562 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
563 WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u)));
564 PointerCoords finger1Start = arg.pointerCoords[1];
565 args.pop_front();
566 arg = std::get<NotifyMotionArgs>(args.front());
567 ASSERT_THAT(arg,
568 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
569 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
570 WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u)));
571 PointerCoords finger2Start = arg.pointerCoords[2];
572 args.pop_front();
573
574 arg = std::get<NotifyMotionArgs>(args.front());
575 ASSERT_THAT(arg,
576 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
577 WithGestureOffset(0, -0.01, EPSILON), WithPointerCount(3u)));
578 EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX());
579 EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX());
580 EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX());
581 EXPECT_EQ(arg.pointerCoords[0].getY(), finger0Start.getY() - 10);
582 EXPECT_EQ(arg.pointerCoords[1].getY(), finger1Start.getY() - 10);
583 EXPECT_EQ(arg.pointerCoords[2].getY(), finger2Start.getY() - 10);
584
585 Gesture continueGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
586 /* dx= */ 0, /* dy= */ 5);
587 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
588 ASSERT_EQ(1u, args.size());
589 arg = std::get<NotifyMotionArgs>(args.front());
590 ASSERT_THAT(arg,
591 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
592 WithGestureOffset(0, -0.005, EPSILON), WithGestureSwipeFingerCount(3),
593 WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
594 WithPointerCount(3u), WithToolType(ToolType::FINGER),
595 WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
596 EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX());
597 EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX());
598 EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX());
599 EXPECT_EQ(arg.pointerCoords[0].getY(), finger0Start.getY() - 15);
600 EXPECT_EQ(arg.pointerCoords[1].getY(), finger1Start.getY() - 15);
601 EXPECT_EQ(arg.pointerCoords[2].getY(), finger2Start.getY() - 15);
602
603 Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
604 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
605 ASSERT_THAT(args,
606 ElementsAre(VariantWith<NotifyMotionArgs>(
607 AllOf(WithMotionAction(
608 AMOTION_EVENT_ACTION_POINTER_UP |
609 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
610 WithGestureOffset(0, 0, EPSILON),
611 WithGestureSwipeFingerCount(3),
612 WithMotionClassification(
613 MotionClassification::MULTI_FINGER_SWIPE),
614 WithPointerCount(3u))),
615 VariantWith<NotifyMotionArgs>(
616 AllOf(WithMotionAction(
617 AMOTION_EVENT_ACTION_POINTER_UP |
618 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
619 WithGestureOffset(0, 0, EPSILON),
620 WithGestureSwipeFingerCount(3),
621 WithMotionClassification(
622 MotionClassification::MULTI_FINGER_SWIPE),
623 WithPointerCount(2u))),
624 VariantWith<NotifyMotionArgs>(
625 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
626 WithGestureOffset(0, 0, EPSILON),
627 WithGestureSwipeFingerCount(3),
628 WithMotionClassification(
629 MotionClassification::MULTI_FINGER_SWIPE),
630 WithPointerCount(1u))),
631 VariantWith<NotifyMotionArgs>(
632 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
633 WithCoords(0, 0),
634 WithMotionClassification(MotionClassification::NONE)))));
635 ASSERT_THAT(args,
636 Each(VariantWith<NotifyMotionArgs>(
637 AllOf(WithToolType(ToolType::FINGER),
638 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
639 }
640
TEST_F(GestureConverterTest,ThreeFingerSwipe_Rotated)641 TEST_F(GestureConverterTest, ThreeFingerSwipe_Rotated) {
642 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
643 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
644 converter.setOrientation(ui::ROTATION_90);
645 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
646
647 Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dx= */ 0,
648 /* dy= */ 10);
649 std::list<NotifyArgs> args =
650 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
651 ASSERT_EQ(4u, args.size());
652 ASSERT_THAT(args,
653 Each(VariantWith<NotifyMotionArgs>(WithDisplayId(ui::LogicalDisplayId::DEFAULT))));
654
655 // Three fake fingers should be created. We don't actually care where they are, so long as they
656 // move appropriately.
657 NotifyMotionArgs arg = std::get<NotifyMotionArgs>(args.front());
658 ASSERT_THAT(arg,
659 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithGestureOffset(0, 0, EPSILON),
660 WithPointerCount(1u)));
661 PointerCoords finger0Start = arg.pointerCoords[0];
662 args.pop_front();
663 arg = std::get<NotifyMotionArgs>(args.front());
664 ASSERT_THAT(arg,
665 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
666 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
667 WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u)));
668 PointerCoords finger1Start = arg.pointerCoords[1];
669 args.pop_front();
670 arg = std::get<NotifyMotionArgs>(args.front());
671 ASSERT_THAT(arg,
672 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
673 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
674 WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u)));
675 PointerCoords finger2Start = arg.pointerCoords[2];
676 args.pop_front();
677
678 arg = std::get<NotifyMotionArgs>(args.front());
679 ASSERT_THAT(arg,
680 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
681 WithGestureOffset(0, -0.01, EPSILON), WithPointerCount(3u)));
682 EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX() - 10);
683 EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX() - 10);
684 EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX() - 10);
685 EXPECT_EQ(arg.pointerCoords[0].getY(), finger0Start.getY());
686 EXPECT_EQ(arg.pointerCoords[1].getY(), finger1Start.getY());
687 EXPECT_EQ(arg.pointerCoords[2].getY(), finger2Start.getY());
688
689 Gesture continueGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
690 /* dx= */ 0, /* dy= */ 5);
691 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
692 ASSERT_EQ(1u, args.size());
693 arg = std::get<NotifyMotionArgs>(args.front());
694 ASSERT_THAT(arg,
695 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
696 WithGestureOffset(0, -0.005, EPSILON), WithPointerCount(3u),
697 WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
698 EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX() - 15);
699 EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX() - 15);
700 EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX() - 15);
701 EXPECT_EQ(arg.pointerCoords[0].getY(), finger0Start.getY());
702 EXPECT_EQ(arg.pointerCoords[1].getY(), finger1Start.getY());
703 EXPECT_EQ(arg.pointerCoords[2].getY(), finger2Start.getY());
704
705 Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
706 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
707 ASSERT_THAT(args,
708 ElementsAre(VariantWith<NotifyMotionArgs>(
709 AllOf(WithMotionAction(
710 AMOTION_EVENT_ACTION_POINTER_UP |
711 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
712 WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u))),
713 VariantWith<NotifyMotionArgs>(
714 AllOf(WithMotionAction(
715 AMOTION_EVENT_ACTION_POINTER_UP |
716 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
717 WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u))),
718 VariantWith<NotifyMotionArgs>(
719 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
720 WithGestureOffset(0, 0, EPSILON), WithPointerCount(1u))),
721 VariantWith<NotifyMotionArgs>(
722 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER)))));
723 ASSERT_THAT(args,
724 Each(VariantWith<NotifyMotionArgs>(WithDisplayId(ui::LogicalDisplayId::DEFAULT))));
725 }
726
TEST_F(GestureConverterTest,FourFingerSwipe_Horizontal)727 TEST_F(GestureConverterTest, FourFingerSwipe_Horizontal) {
728 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
729 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
730 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
731
732 Gesture startGesture(kGestureFourFingerSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
733 /* dx= */ 10, /* dy= */ 0);
734 std::list<NotifyArgs> args =
735 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
736 ASSERT_EQ(5u, args.size());
737 ASSERT_THAT(args,
738 Each(VariantWith<NotifyMotionArgs>(
739 AllOf(WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
740 WithGestureSwipeFingerCount(4), WithToolType(ToolType::FINGER),
741 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
742
743 // Four fake fingers should be created. We don't actually care where they are, so long as they
744 // move appropriately.
745 NotifyMotionArgs arg = std::get<NotifyMotionArgs>(args.front());
746 ASSERT_THAT(arg,
747 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithGestureOffset(0, 0, EPSILON),
748 WithPointerCount(1u)));
749 PointerCoords finger0Start = arg.pointerCoords[0];
750 args.pop_front();
751 arg = std::get<NotifyMotionArgs>(args.front());
752 ASSERT_THAT(arg,
753 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
754 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
755 WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u)));
756 PointerCoords finger1Start = arg.pointerCoords[1];
757 args.pop_front();
758 arg = std::get<NotifyMotionArgs>(args.front());
759 ASSERT_THAT(arg,
760 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
761 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
762 WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u)));
763 PointerCoords finger2Start = arg.pointerCoords[2];
764 args.pop_front();
765 arg = std::get<NotifyMotionArgs>(args.front());
766 ASSERT_THAT(arg,
767 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
768 3 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
769 WithGestureOffset(0, 0, EPSILON), WithPointerCount(4u)));
770 PointerCoords finger3Start = arg.pointerCoords[3];
771 args.pop_front();
772
773 arg = std::get<NotifyMotionArgs>(args.front());
774 ASSERT_THAT(arg,
775 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
776 WithGestureOffset(0.01, 0, EPSILON), WithPointerCount(4u)));
777 EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX() + 10);
778 EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX() + 10);
779 EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX() + 10);
780 EXPECT_EQ(arg.pointerCoords[3].getX(), finger3Start.getX() + 10);
781 EXPECT_EQ(arg.pointerCoords[0].getY(), finger0Start.getY());
782 EXPECT_EQ(arg.pointerCoords[1].getY(), finger1Start.getY());
783 EXPECT_EQ(arg.pointerCoords[2].getY(), finger2Start.getY());
784 EXPECT_EQ(arg.pointerCoords[3].getY(), finger3Start.getY());
785
786 Gesture continueGesture(kGestureFourFingerSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
787 /* dx= */ 5, /* dy= */ 0);
788 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
789 ASSERT_EQ(1u, args.size());
790 arg = std::get<NotifyMotionArgs>(args.front());
791 ASSERT_THAT(arg,
792 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
793 WithGestureOffset(0.005, 0, EPSILON), WithGestureSwipeFingerCount(4),
794 WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
795 WithPointerCount(4u), WithToolType(ToolType::FINGER),
796 WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
797 EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX() + 15);
798 EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX() + 15);
799 EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX() + 15);
800 EXPECT_EQ(arg.pointerCoords[3].getX(), finger3Start.getX() + 15);
801 EXPECT_EQ(arg.pointerCoords[0].getY(), finger0Start.getY());
802 EXPECT_EQ(arg.pointerCoords[1].getY(), finger1Start.getY());
803 EXPECT_EQ(arg.pointerCoords[2].getY(), finger2Start.getY());
804 EXPECT_EQ(arg.pointerCoords[3].getY(), finger3Start.getY());
805
806 Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
807 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
808 ASSERT_THAT(args,
809 ElementsAre(VariantWith<NotifyMotionArgs>(
810 AllOf(WithMotionAction(
811 AMOTION_EVENT_ACTION_POINTER_UP |
812 3 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
813 WithGestureOffset(0, 0, EPSILON),
814 WithGestureSwipeFingerCount(4),
815 WithMotionClassification(
816 MotionClassification::MULTI_FINGER_SWIPE),
817 WithPointerCount(4u))),
818 VariantWith<NotifyMotionArgs>(
819 AllOf(WithMotionAction(
820 AMOTION_EVENT_ACTION_POINTER_UP |
821 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
822 WithGestureOffset(0, 0, EPSILON),
823 WithGestureSwipeFingerCount(4),
824 WithMotionClassification(
825 MotionClassification::MULTI_FINGER_SWIPE),
826 WithPointerCount(3u))),
827 VariantWith<NotifyMotionArgs>(
828 AllOf(WithMotionAction(
829 AMOTION_EVENT_ACTION_POINTER_UP |
830 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
831 WithGestureOffset(0, 0, EPSILON),
832 WithGestureSwipeFingerCount(4),
833 WithMotionClassification(
834 MotionClassification::MULTI_FINGER_SWIPE),
835 WithPointerCount(2u))),
836 VariantWith<NotifyMotionArgs>(
837 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
838 WithGestureOffset(0, 0, EPSILON),
839 WithGestureSwipeFingerCount(4),
840 WithMotionClassification(
841 MotionClassification::MULTI_FINGER_SWIPE),
842 WithPointerCount(1u))),
843 VariantWith<NotifyMotionArgs>(
844 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
845 WithCoords(0, 0),
846 WithMotionClassification(MotionClassification::NONE)))));
847 ASSERT_THAT(args,
848 Each(VariantWith<NotifyMotionArgs>(
849 AllOf(WithToolType(ToolType::FINGER),
850 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
851 }
852
TEST_F(GestureConverterTest,DisablingSystemGestures_IgnoresMultiFingerSwipe)853 TEST_F(GestureConverterTest, DisablingSystemGestures_IgnoresMultiFingerSwipe) {
854 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
855 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
856 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
857
858 std::list<NotifyArgs> args = converter.setEnableSystemGestures(ARBITRARY_TIME, false);
859 ASSERT_THAT(args, IsEmpty());
860
861 Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
862 /*dy=*/10);
863 Gesture continueGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
864 /*dy=*/5);
865 Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
866
867 args += converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
868 args += converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
869 args += converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
870 ASSERT_THAT(args, IsEmpty());
871
872 args = converter.setEnableSystemGestures(ARBITRARY_TIME, true);
873 ASSERT_THAT(args, IsEmpty());
874
875 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
876 ASSERT_THAT(args,
877 ElementsAre(VariantWith<NotifyMotionArgs>(
878 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)),
879 VariantWith<NotifyMotionArgs>(WithMotionAction(
880 AMOTION_EVENT_ACTION_POINTER_DOWN |
881 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT)),
882 VariantWith<NotifyMotionArgs>(WithMotionAction(
883 AMOTION_EVENT_ACTION_POINTER_DOWN |
884 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT)),
885 VariantWith<NotifyMotionArgs>(
886 WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
887 ASSERT_THAT(args,
888 Each(VariantWith<NotifyMotionArgs>(
889 WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE))));
890 }
891
TEST_F(GestureConverterTest,DisablingSystemGestures_EndsOngoingMultiFingerSwipe)892 TEST_F(GestureConverterTest, DisablingSystemGestures_EndsOngoingMultiFingerSwipe) {
893 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
894 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
895 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
896
897 Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
898 /*dy=*/10);
899 std::list<NotifyArgs> args;
900 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
901 ASSERT_FALSE(args.empty());
902
903 // Disabling system gestures should end the swipe early.
904 args = converter.setEnableSystemGestures(ARBITRARY_TIME, false);
905 ASSERT_THAT(args,
906 ElementsAre(VariantWith<NotifyMotionArgs>(
907 AllOf(WithMotionAction(
908 AMOTION_EVENT_ACTION_POINTER_UP |
909 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
910 WithGestureOffset(0, 0, EPSILON),
911 WithMotionClassification(
912 MotionClassification::MULTI_FINGER_SWIPE),
913 WithPointerCount(3u))),
914 VariantWith<NotifyMotionArgs>(
915 AllOf(WithMotionAction(
916 AMOTION_EVENT_ACTION_POINTER_UP |
917 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
918 WithGestureOffset(0, 0, EPSILON),
919 WithMotionClassification(
920 MotionClassification::MULTI_FINGER_SWIPE),
921 WithPointerCount(2u))),
922 VariantWith<NotifyMotionArgs>(
923 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
924 WithGestureOffset(0, 0, EPSILON),
925 WithMotionClassification(
926 MotionClassification::MULTI_FINGER_SWIPE),
927 WithPointerCount(1u))),
928 VariantWith<NotifyMotionArgs>(
929 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
930 WithMotionClassification(MotionClassification::NONE)))));
931 ASSERT_THAT(args,
932 Each(VariantWith<NotifyMotionArgs>(
933 AllOf(WithToolType(ToolType::FINGER),
934 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
935
936 // Further movement in the same swipe should be ignored.
937 Gesture continueGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
938 /*dy=*/5);
939 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
940 ASSERT_THAT(args, IsEmpty());
941 Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
942 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
943 ASSERT_THAT(args, IsEmpty());
944
945 // But single-finger pointer motion should be reported.
946 Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
947 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
948 ASSERT_THAT(args,
949 ElementsAre(VariantWith<NotifyMotionArgs>(
950 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
951 WithRelativeMotion(-5, 10), WithButtonState(0)))));
952 }
953
TEST_F(GestureConverterTest,Pinch_Inwards)954 TEST_F(GestureConverterTest, Pinch_Inwards) {
955 input_flags::enable_touchpad_no_focus_change(true);
956
957 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
958 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
959 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
960
961 Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
962 GESTURES_ZOOM_START);
963 std::list<NotifyArgs> args =
964 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
965 ASSERT_THAT(args,
966 ElementsAre(VariantWith<NotifyMotionArgs>(
967 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
968 WithCoords(-100, 0), WithPointerCount(1u))),
969 VariantWith<NotifyMotionArgs>(
970 AllOf(WithMotionAction(
971 AMOTION_EVENT_ACTION_POINTER_DOWN |
972 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
973 WithPointerCoords(1, 100, 0), WithPointerCount(2u)))));
974 ASSERT_THAT(args,
975 Each(VariantWith<NotifyMotionArgs>(
976 AllOf(WithMotionClassification(MotionClassification::PINCH),
977 WithGesturePinchScaleFactor(1.0f, EPSILON),
978 WithToolType(ToolType::FINGER),
979 WithDisplayId(ui::LogicalDisplayId::DEFAULT),
980 WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE)))));
981
982 Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
983 /* dz= */ 0.8, GESTURES_ZOOM_UPDATE);
984 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, updateGesture);
985 ASSERT_THAT(args,
986 ElementsAre(VariantWith<NotifyMotionArgs>(
987 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
988 WithMotionClassification(MotionClassification::PINCH),
989 WithGesturePinchScaleFactor(0.8f, EPSILON),
990 WithPointerCoords(0, -80, 0), WithPointerCoords(1, 80, 0),
991 WithPointerCount(2u), WithToolType(ToolType::FINGER),
992 WithDisplayId(ui::LogicalDisplayId::DEFAULT),
993 WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE)))));
994
995 Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
996 GESTURES_ZOOM_END);
997 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, endGesture);
998 ASSERT_THAT(args,
999 ElementsAre(VariantWith<NotifyMotionArgs>(
1000 AllOf(WithMotionAction(
1001 AMOTION_EVENT_ACTION_POINTER_UP |
1002 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1003 WithMotionClassification(MotionClassification::PINCH),
1004 WithGesturePinchScaleFactor(1.0f, EPSILON),
1005 WithPointerCount(2u),
1006 WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE))),
1007 VariantWith<NotifyMotionArgs>(
1008 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
1009 WithMotionClassification(MotionClassification::PINCH),
1010 WithGesturePinchScaleFactor(1.0f, EPSILON),
1011 WithPointerCount(1u),
1012 WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE))),
1013 VariantWith<NotifyMotionArgs>(
1014 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1015 WithCoords(0, 0),
1016 WithMotionClassification(MotionClassification::NONE)))));
1017 ASSERT_THAT(args,
1018 Each(VariantWith<NotifyMotionArgs>(
1019 AllOf(WithToolType(ToolType::FINGER),
1020 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
1021 }
1022
TEST_F(GestureConverterTest,Pinch_Outwards)1023 TEST_F(GestureConverterTest, Pinch_Outwards) {
1024 input_flags::enable_touchpad_no_focus_change(true);
1025
1026 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1027 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1028 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1029
1030 Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
1031 GESTURES_ZOOM_START);
1032 std::list<NotifyArgs> args =
1033 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
1034 ASSERT_THAT(args,
1035 ElementsAre(VariantWith<NotifyMotionArgs>(
1036 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1037 WithCoords(-100, 0), WithPointerCount(1u))),
1038 VariantWith<NotifyMotionArgs>(
1039 AllOf(WithMotionAction(
1040 AMOTION_EVENT_ACTION_POINTER_DOWN |
1041 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1042 WithPointerCoords(1, 100, 0), WithPointerCount(2u)))));
1043 ASSERT_THAT(args,
1044 Each(VariantWith<NotifyMotionArgs>(
1045 AllOf(WithMotionClassification(MotionClassification::PINCH),
1046 WithGesturePinchScaleFactor(1.0f, EPSILON),
1047 WithToolType(ToolType::FINGER),
1048 WithDisplayId(ui::LogicalDisplayId::DEFAULT),
1049 WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE)))));
1050
1051 Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
1052 /* dz= */ 1.1, GESTURES_ZOOM_UPDATE);
1053 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, updateGesture);
1054 ASSERT_THAT(args,
1055 ElementsAre(VariantWith<NotifyMotionArgs>(
1056 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
1057 WithMotionClassification(MotionClassification::PINCH),
1058 WithGesturePinchScaleFactor(1.1f, EPSILON),
1059 WithPointerCoords(0, -110, 0), WithPointerCoords(1, 110, 0),
1060 WithPointerCount(2u), WithToolType(ToolType::FINGER),
1061 WithDisplayId(ui::LogicalDisplayId::DEFAULT),
1062 WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE)))));
1063
1064 Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
1065 GESTURES_ZOOM_END);
1066 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, endGesture);
1067 ASSERT_THAT(args,
1068 ElementsAre(VariantWith<NotifyMotionArgs>(
1069 AllOf(WithMotionAction(
1070 AMOTION_EVENT_ACTION_POINTER_UP |
1071 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1072 WithMotionClassification(MotionClassification::PINCH),
1073 WithGesturePinchScaleFactor(1.0f, EPSILON),
1074 WithPointerCount(2u),
1075 WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE))),
1076 VariantWith<NotifyMotionArgs>(
1077 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
1078 WithMotionClassification(MotionClassification::PINCH),
1079 WithGesturePinchScaleFactor(1.0f, EPSILON),
1080 WithPointerCount(1u),
1081 WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE))),
1082 VariantWith<NotifyMotionArgs>(
1083 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1084 WithCoords(0, 0),
1085 WithMotionClassification(MotionClassification::NONE)))));
1086 ASSERT_THAT(args,
1087 Each(VariantWith<NotifyMotionArgs>(
1088 AllOf(WithToolType(ToolType::FINGER),
1089 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
1090 }
1091
TEST_F(GestureConverterTest,Pinch_ClearsClassificationAfterGesture)1092 TEST_F(GestureConverterTest, Pinch_ClearsClassificationAfterGesture) {
1093 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1094 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1095 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1096
1097 Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
1098 GESTURES_ZOOM_START);
1099 std::list<NotifyArgs> args =
1100 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
1101
1102 Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
1103 /*dz=*/1.2, GESTURES_ZOOM_UPDATE);
1104 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, updateGesture);
1105
1106 Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
1107 GESTURES_ZOOM_END);
1108 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, endGesture);
1109
1110 Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
1111 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
1112 ASSERT_THAT(args,
1113 ElementsAre(VariantWith<NotifyMotionArgs>(
1114 WithMotionClassification(MotionClassification::NONE))));
1115 }
1116
TEST_F(GestureConverterTest,Pinch_ClearsScaleFactorAfterGesture)1117 TEST_F(GestureConverterTest, Pinch_ClearsScaleFactorAfterGesture) {
1118 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1119 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1120 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1121
1122 Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
1123 GESTURES_ZOOM_START);
1124 std::list<NotifyArgs> args =
1125 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
1126
1127 Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
1128 /*dz=*/1.2, GESTURES_ZOOM_UPDATE);
1129 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, updateGesture);
1130
1131 Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
1132 GESTURES_ZOOM_END);
1133 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, endGesture);
1134
1135 // Move gestures don't use the fake finger array, so to test that gesture axes are cleared we
1136 // need to use another gesture type, like scroll.
1137 Gesture scrollGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/1,
1138 /*dy=*/0);
1139 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, scrollGesture);
1140 ASSERT_FALSE(args.empty());
1141 EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), WithGesturePinchScaleFactor(0, EPSILON));
1142 }
1143
TEST_F(GestureConverterTest,ResetWithButtonPressed)1144 TEST_F(GestureConverterTest, ResetWithButtonPressed) {
1145 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1146 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1147 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1148
1149 Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
1150 /*down=*/GESTURES_BUTTON_LEFT | GESTURES_BUTTON_RIGHT,
1151 /*up=*/GESTURES_BUTTON_NONE, /*is_tap=*/false);
1152 (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, downGesture);
1153
1154 std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
1155 ASSERT_THAT(args,
1156 ElementsAre(VariantWith<NotifyMotionArgs>(
1157 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
1158 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
1159 WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY))),
1160 VariantWith<NotifyMotionArgs>(
1161 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
1162 WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY),
1163 WithButtonState(0))),
1164 VariantWith<NotifyMotionArgs>(
1165 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
1166 WithButtonState(0))),
1167 VariantWith<NotifyMotionArgs>(
1168 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1169 WithButtonState(0)))));
1170 ASSERT_THAT(args,
1171 Each(VariantWith<NotifyMotionArgs>(
1172 AllOf(WithCoords(0, 0), WithToolType(ToolType::FINGER),
1173 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
1174 }
1175
TEST_F(GestureConverterTest,ResetDuringScroll)1176 TEST_F(GestureConverterTest, ResetDuringScroll) {
1177 input_flags::enable_touchpad_no_focus_change(true);
1178
1179 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1180 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1181 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1182
1183 Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
1184 (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
1185
1186 std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
1187 ASSERT_THAT(args,
1188 ElementsAre(VariantWith<NotifyMotionArgs>(
1189 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
1190 WithCoords(0, -10),
1191 WithGestureScrollDistance(0, 0, EPSILON),
1192 WithMotionClassification(
1193 MotionClassification::TWO_FINGER_SWIPE),
1194 WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE |
1195 AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE))),
1196 VariantWith<NotifyMotionArgs>(
1197 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1198 WithCoords(0, 0),
1199 WithMotionClassification(MotionClassification::NONE)))));
1200 ASSERT_THAT(args,
1201 Each(VariantWith<NotifyMotionArgs>(
1202 AllOf(WithToolType(ToolType::FINGER),
1203 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
1204 }
1205
TEST_F(GestureConverterTest,ResetDuringThreeFingerSwipe)1206 TEST_F(GestureConverterTest, ResetDuringThreeFingerSwipe) {
1207 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1208 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1209 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1210
1211 Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
1212 /*dy=*/10);
1213 (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
1214
1215 std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
1216 ASSERT_THAT(args,
1217 ElementsAre(VariantWith<NotifyMotionArgs>(
1218 AllOf(WithMotionAction(
1219 AMOTION_EVENT_ACTION_POINTER_UP |
1220 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1221 WithGestureOffset(0, 0, EPSILON),
1222 WithMotionClassification(
1223 MotionClassification::MULTI_FINGER_SWIPE),
1224 WithPointerCount(3u))),
1225 VariantWith<NotifyMotionArgs>(
1226 AllOf(WithMotionAction(
1227 AMOTION_EVENT_ACTION_POINTER_UP |
1228 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1229 WithGestureOffset(0, 0, EPSILON),
1230 WithMotionClassification(
1231 MotionClassification::MULTI_FINGER_SWIPE),
1232 WithPointerCount(2u))),
1233 VariantWith<NotifyMotionArgs>(
1234 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
1235 WithGestureOffset(0, 0, EPSILON),
1236 WithMotionClassification(
1237 MotionClassification::MULTI_FINGER_SWIPE),
1238 WithPointerCount(1u))),
1239 VariantWith<NotifyMotionArgs>(
1240 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1241 WithMotionClassification(MotionClassification::NONE)))));
1242 ASSERT_THAT(args,
1243 Each(VariantWith<NotifyMotionArgs>(
1244 AllOf(WithToolType(ToolType::FINGER),
1245 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
1246 }
1247
TEST_F(GestureConverterTest,ResetDuringPinch)1248 TEST_F(GestureConverterTest, ResetDuringPinch) {
1249 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1250 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1251 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1252
1253 Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
1254 GESTURES_ZOOM_START);
1255 (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
1256
1257 std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
1258 ASSERT_THAT(args,
1259 ElementsAre(VariantWith<NotifyMotionArgs>(
1260 AllOf(WithMotionAction(
1261 AMOTION_EVENT_ACTION_POINTER_UP |
1262 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1263 WithMotionClassification(MotionClassification::PINCH),
1264 WithGesturePinchScaleFactor(1.0f, EPSILON),
1265 WithPointerCount(2u))),
1266 VariantWith<NotifyMotionArgs>(
1267 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
1268 WithMotionClassification(MotionClassification::PINCH),
1269 WithGesturePinchScaleFactor(1.0f, EPSILON),
1270 WithPointerCount(1u))),
1271 VariantWith<NotifyMotionArgs>(
1272 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1273 WithCoords(0, 0),
1274 WithMotionClassification(MotionClassification::NONE)))));
1275 ASSERT_THAT(args,
1276 Each(VariantWith<NotifyMotionArgs>(
1277 AllOf(WithToolType(ToolType::FINGER),
1278 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
1279 }
1280
TEST_F(GestureConverterTest,FlingTapDown)1281 TEST_F(GestureConverterTest, FlingTapDown) {
1282 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1283 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1284 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1285
1286 Gesture tapDownGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
1287 /*vx=*/0.f, /*vy=*/0.f, GESTURES_FLING_TAP_DOWN);
1288 std::list<NotifyArgs> args =
1289 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, tapDownGesture);
1290
1291 ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
1292 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER), WithCoords(0, 0),
1293 WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
1294 WithButtonState(0), WithPressure(0.0f),
1295 WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
1296 }
1297
TEST_F(GestureConverterTest,FlingTapDownAfterScrollStopsFling)1298 TEST_F(GestureConverterTest, FlingTapDownAfterScrollStopsFling) {
1299 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1300 input_flags::enable_touchpad_fling_stop(true);
1301 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1302 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1303
1304 Gesture scrollGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
1305 std::list<NotifyArgs> args =
1306 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, scrollGesture);
1307 Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
1308 GESTURES_FLING_START);
1309 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
1310
1311 Gesture tapDownGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
1312 /*vx=*/0.f, /*vy=*/0.f, GESTURES_FLING_TAP_DOWN);
1313 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, tapDownGesture);
1314 ASSERT_THAT(args,
1315 ElementsAre(VariantWith<NotifyMotionArgs>(
1316 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT)),
1317 VariantWith<NotifyMotionArgs>(
1318 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)),
1319 VariantWith<NotifyMotionArgs>(
1320 WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)),
1321 VariantWith<NotifyMotionArgs>(
1322 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER))));
1323 ASSERT_THAT(args,
1324 Each(VariantWith<NotifyMotionArgs>(
1325 AllOf(WithCoords(0, 0), WithToolType(ToolType::FINGER),
1326 WithDisplayId(ui::LogicalDisplayId::DEFAULT),
1327 WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE)))));
1328 }
1329
TEST_F(GestureConverterTest,Tap)1330 TEST_F(GestureConverterTest, Tap) {
1331 // Tap should produce button press/release events
1332 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1333 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1334 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1335
1336 Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
1337 /* vy= */ 0, GESTURES_FLING_TAP_DOWN);
1338 std::list<NotifyArgs> args =
1339 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
1340 // We don't need to check args here, since it's covered by the FlingTapDown test.
1341
1342 Gesture tapGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
1343 /* down= */ GESTURES_BUTTON_LEFT,
1344 /* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
1345 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, tapGesture);
1346
1347 ASSERT_THAT(args,
1348 ElementsAre(VariantWith<NotifyMotionArgs>(
1349 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
1350 WithButtonState(0), WithPressure(0.0f))),
1351 VariantWith<NotifyMotionArgs>(
1352 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1353 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
1354 WithPressure(1.0f))),
1355 VariantWith<NotifyMotionArgs>(
1356 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
1357 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
1358 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
1359 WithPressure(1.0f))),
1360 VariantWith<NotifyMotionArgs>(
1361 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
1362 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
1363 WithButtonState(0), WithPressure(1.0f))),
1364 VariantWith<NotifyMotionArgs>(
1365 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
1366 WithButtonState(0), WithPressure(0.0f))),
1367 VariantWith<NotifyMotionArgs>(
1368 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1369 WithButtonState(0), WithPressure(0.0f)))));
1370 ASSERT_THAT(args,
1371 Each(VariantWith<NotifyMotionArgs>(
1372 AllOf(WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
1373 WithToolType(ToolType::FINGER),
1374 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
1375 }
1376
TEST_F(GestureConverterTest,ThreeFingerTap_TriggersShortcut)1377 TEST_F(GestureConverterTest, ThreeFingerTap_TriggersShortcut) {
1378 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1379 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1380 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1381 converter.setThreeFingerTapShortcutEnabled(true);
1382
1383 Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*vx=*/0,
1384 /*vy=*/0, GESTURES_FLING_TAP_DOWN);
1385 std::list<NotifyArgs> args =
1386 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
1387 // We don't need to check args here, since it's covered by the FlingTapDown test.
1388
1389 Gesture tapGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
1390 /*down=*/GESTURES_BUTTON_MIDDLE, /*up=*/GESTURES_BUTTON_MIDDLE,
1391 /*is_tap=*/true);
1392 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, tapGesture);
1393
1394 ASSERT_TRUE(args.empty());
1395 mFakePolicy->assertTouchpadThreeFingerTapNotified();
1396 }
1397
TEST_F(GestureConverterTest,Click)1398 TEST_F(GestureConverterTest, Click) {
1399 // Click should produce button press/release events
1400 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1401 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1402 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1403
1404 Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
1405 /* vy= */ 0, GESTURES_FLING_TAP_DOWN);
1406 std::list<NotifyArgs> args =
1407 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
1408 // We don't need to check args here, since it's covered by the FlingTapDown test.
1409
1410 Gesture buttonDownGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
1411 /* down= */ GESTURES_BUTTON_LEFT,
1412 /* up= */ GESTURES_BUTTON_NONE, /* is_tap= */ false);
1413 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, buttonDownGesture);
1414
1415 ASSERT_THAT(args,
1416 ElementsAre(VariantWith<NotifyMotionArgs>(
1417 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
1418 WithButtonState(0), WithPressure(0.0f))),
1419 VariantWith<NotifyMotionArgs>(
1420 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1421 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
1422 WithPressure(1.0f))),
1423 VariantWith<NotifyMotionArgs>(
1424 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
1425 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
1426 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
1427 WithPressure(1.0f)))));
1428 ASSERT_THAT(args,
1429 Each(VariantWith<NotifyMotionArgs>(
1430 AllOf(WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
1431 WithToolType(ToolType::FINGER),
1432 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
1433
1434 Gesture buttonUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
1435 /* down= */ GESTURES_BUTTON_NONE,
1436 /* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ false);
1437 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, buttonUpGesture);
1438
1439 ASSERT_THAT(args,
1440 ElementsAre(VariantWith<NotifyMotionArgs>(
1441 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
1442 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
1443 WithPressure(1.0f))),
1444 VariantWith<NotifyMotionArgs>(
1445 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
1446 WithPressure(0.0f))),
1447 VariantWith<NotifyMotionArgs>(
1448 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1449 WithPressure(0.0f)))));
1450 ASSERT_THAT(args,
1451 Each(VariantWith<NotifyMotionArgs>(
1452 AllOf(WithButtonState(0), WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
1453 WithToolType(ToolType::FINGER),
1454 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
1455 }
1456
TEST_F_WITH_FLAGS(GestureConverterTest,TapWithTapToClickDisabled,REQUIRES_FLAGS_ENABLED (TOUCHPAD_PALM_REJECTION),REQUIRES_FLAGS_DISABLED (TOUCHPAD_PALM_REJECTION_V2))1457 TEST_F_WITH_FLAGS(GestureConverterTest, TapWithTapToClickDisabled,
1458 REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION),
1459 REQUIRES_FLAGS_DISABLED(TOUCHPAD_PALM_REJECTION_V2)) {
1460 nsecs_t currentTime = ARBITRARY_GESTURE_TIME;
1461
1462 // Tap should be ignored when disabled
1463 mReader->getContext()->setPreventingTouchpadTaps(true);
1464
1465 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1466 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1467 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1468
1469 Gesture flingGesture(kGestureFling, currentTime, currentTime, /* vx= */ 0,
1470 /* vy= */ 0, GESTURES_FLING_TAP_DOWN);
1471 std::list<NotifyArgs> args =
1472 converter.handleGesture(currentTime, currentTime, currentTime, flingGesture);
1473 // We don't need to check args here, since it's covered by the FlingTapDown test.
1474
1475 Gesture tapGesture(kGestureButtonsChange, currentTime, currentTime,
1476 /* down= */ GESTURES_BUTTON_LEFT,
1477 /* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
1478 args = converter.handleGesture(currentTime, currentTime, currentTime, tapGesture);
1479
1480 // no events should be generated
1481 ASSERT_EQ(0u, args.size());
1482
1483 // Future taps should be re-enabled
1484 ASSERT_FALSE(mReader->getContext()->isPreventingTouchpadTaps());
1485 }
1486
TEST_F_WITH_FLAGS(GestureConverterTest,TapWithTapToClickDisabledWithDelay,REQUIRES_FLAGS_ENABLED (TOUCHPAD_PALM_REJECTION_V2))1487 TEST_F_WITH_FLAGS(GestureConverterTest, TapWithTapToClickDisabledWithDelay,
1488 REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION_V2)) {
1489 nsecs_t currentTime = ARBITRARY_GESTURE_TIME;
1490
1491 // Tap should be ignored when disabled
1492 mReader->getContext()->setPreventingTouchpadTaps(true);
1493
1494 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1495 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1496 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1497
1498 Gesture flingGesture(kGestureFling, currentTime, currentTime, /* vx= */ 0,
1499 /* vy= */ 0, GESTURES_FLING_TAP_DOWN);
1500 std::list<NotifyArgs> args =
1501 converter.handleGesture(currentTime, currentTime, currentTime, flingGesture);
1502 // We don't need to check args here, since it's covered by the FlingTapDown test.
1503
1504 Gesture tapGesture(kGestureButtonsChange, currentTime, currentTime,
1505 /* down= */ GESTURES_BUTTON_LEFT,
1506 /* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
1507 args = converter.handleGesture(currentTime, currentTime, currentTime, tapGesture);
1508
1509 // no events should be generated
1510 ASSERT_EQ(0u, args.size());
1511
1512 // Future taps should be re-enabled
1513 ASSERT_FALSE(mReader->getContext()->isPreventingTouchpadTaps());
1514
1515 // taps before the threshold should still be ignored
1516 currentTime += TAP_ENABLE_DELAY_NANOS.count();
1517 flingGesture = Gesture(kGestureFling, currentTime, currentTime, /* vx= */ 0,
1518 /* vy= */ 0, GESTURES_FLING_TAP_DOWN);
1519 args = converter.handleGesture(currentTime, currentTime, currentTime, flingGesture);
1520
1521 ASSERT_EQ(1u, args.size());
1522 ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
1523 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithRelativeMotion(0, 0)));
1524
1525 tapGesture = Gesture(kGestureButtonsChange, currentTime, currentTime,
1526 /* down= */ GESTURES_BUTTON_LEFT,
1527 /* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
1528 args = converter.handleGesture(currentTime, currentTime, currentTime, tapGesture);
1529
1530 // no events should be generated
1531 ASSERT_EQ(0u, args.size());
1532
1533 // taps after the threshold should be recognised
1534 currentTime += 1;
1535 flingGesture = Gesture(kGestureFling, currentTime, currentTime, /* vx= */ 0,
1536 /* vy= */ 0, GESTURES_FLING_TAP_DOWN);
1537 args = converter.handleGesture(currentTime, currentTime, currentTime, flingGesture);
1538
1539 ASSERT_EQ(1u, args.size());
1540 ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
1541 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithRelativeMotion(0, 0)));
1542
1543 tapGesture = Gesture(kGestureButtonsChange, currentTime, currentTime,
1544 /* down= */ GESTURES_BUTTON_LEFT,
1545 /* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
1546 args = converter.handleGesture(currentTime, currentTime, currentTime, tapGesture);
1547 ASSERT_THAT(args,
1548 ElementsAre(VariantWith<NotifyMotionArgs>(
1549 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
1550 WithButtonState(0))),
1551 VariantWith<NotifyMotionArgs>(
1552 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1553 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY))),
1554 VariantWith<NotifyMotionArgs>(
1555 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
1556 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
1557 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY))),
1558 VariantWith<NotifyMotionArgs>(
1559 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
1560 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
1561 WithButtonState(0))),
1562 VariantWith<NotifyMotionArgs>(
1563 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
1564 WithButtonState(0))),
1565 VariantWith<NotifyMotionArgs>(
1566 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1567 WithButtonState(0)))));
1568 ASSERT_THAT(args, Each(VariantWith<NotifyMotionArgs>(WithRelativeMotion(0.f, 0.f))));
1569 }
1570
TEST_F_WITH_FLAGS(GestureConverterTest,ClickWithTapToClickDisabled,REQUIRES_FLAGS_ENABLED (TOUCHPAD_PALM_REJECTION))1571 TEST_F_WITH_FLAGS(GestureConverterTest, ClickWithTapToClickDisabled,
1572 REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION)) {
1573 // Click should still produce button press/release events
1574 mReader->getContext()->setPreventingTouchpadTaps(true);
1575
1576 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1577 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1578 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1579
1580 Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
1581 /* vy= */ 0, GESTURES_FLING_TAP_DOWN);
1582 std::list<NotifyArgs> args =
1583 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
1584 // We don't need to check args here, since it's covered by the FlingTapDown test.
1585
1586 Gesture buttonDownGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
1587 /* down= */ GESTURES_BUTTON_LEFT,
1588 /* up= */ GESTURES_BUTTON_NONE, /* is_tap= */ false);
1589 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, buttonDownGesture);
1590
1591 ASSERT_THAT(args,
1592 ElementsAre(VariantWith<NotifyMotionArgs>(
1593 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
1594 WithButtonState(0), WithPressure(0.0f))),
1595 VariantWith<NotifyMotionArgs>(
1596 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1597 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
1598 WithPressure(1.0f))),
1599 VariantWith<NotifyMotionArgs>(
1600 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
1601 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
1602 WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
1603 WithPressure(1.0f)))));
1604 ASSERT_THAT(args,
1605 Each(VariantWith<NotifyMotionArgs>(
1606 AllOf(WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
1607 WithToolType(ToolType::FINGER),
1608 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
1609
1610 Gesture buttonUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
1611 /* down= */ GESTURES_BUTTON_NONE,
1612 /* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ false);
1613 args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, buttonUpGesture);
1614
1615 ASSERT_THAT(args,
1616 ElementsAre(VariantWith<NotifyMotionArgs>(
1617 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
1618 WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
1619 WithButtonState(0), WithCoords(0, 0),
1620 WithRelativeMotion(0.f, 0.f),
1621 WithToolType(ToolType::FINGER), WithButtonState(0),
1622 WithPressure(1.0f),
1623 WithDisplayId(ui::LogicalDisplayId::DEFAULT))),
1624 VariantWith<NotifyMotionArgs>(
1625 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
1626 WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
1627 WithToolType(ToolType::FINGER), WithButtonState(0),
1628 WithPressure(0.0f),
1629 WithDisplayId(ui::LogicalDisplayId::DEFAULT))),
1630 VariantWith<NotifyMotionArgs>(
1631 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1632 WithCoords(0, 0), WithRelativeMotion(0, 0),
1633 WithToolType(ToolType::FINGER), WithButtonState(0),
1634 WithPressure(0.0f),
1635 WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
1636
1637 // Future taps should be re-enabled
1638 ASSERT_FALSE(mReader->getContext()->isPreventingTouchpadTaps());
1639 }
1640
TEST_F_WITH_FLAGS(GestureConverterTest,MoveEnablesTapToClick,REQUIRES_FLAGS_ENABLED (TOUCHPAD_PALM_REJECTION))1641 TEST_F_WITH_FLAGS(GestureConverterTest, MoveEnablesTapToClick,
1642 REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION)) {
1643 // initially disable tap-to-click
1644 mReader->getContext()->setPreventingTouchpadTaps(true);
1645
1646 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1647 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1648 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1649
1650 Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
1651 std::list<NotifyArgs> args =
1652 converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
1653 // We don't need to check args here, since it's covered by the Move test.
1654
1655 // Future taps should be re-enabled
1656 ASSERT_FALSE(mReader->getContext()->isPreventingTouchpadTaps());
1657 }
1658
TEST_F_WITH_FLAGS(GestureConverterTest,KeypressCancelsHoverMove,REQUIRES_FLAGS_ENABLED (TOUCHPAD_PALM_REJECTION_V2))1659 TEST_F_WITH_FLAGS(GestureConverterTest, KeypressCancelsHoverMove,
1660 REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION_V2)) {
1661 const nsecs_t gestureStartTime = 1000;
1662 InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1663 GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1664 converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1665
1666 // Start a move gesture at gestureStartTime
1667 Gesture moveGesture(kGestureMove, gestureStartTime, gestureStartTime, -5, 10);
1668 std::list<NotifyArgs> args =
1669 converter.handleGesture(gestureStartTime, READ_TIME, gestureStartTime, moveGesture);
1670 ASSERT_THAT(args,
1671 ElementsAre(VariantWith<NotifyMotionArgs>(
1672 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER)),
1673 VariantWith<NotifyMotionArgs>(
1674 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))));
1675
1676 // Key presses with IME connection should cancel ongoing move gesture
1677 nsecs_t currentTime = gestureStartTime + 100;
1678 mFakePolicy->setIsInputMethodConnectionActive(true);
1679 mReader->getContext()->setLastKeyDownTimestamp(currentTime);
1680 moveGesture = Gesture(kGestureMove, currentTime, currentTime, -5, 10);
1681 args = converter.handleGesture(currentTime, READ_TIME, gestureStartTime, moveGesture);
1682 ASSERT_THAT(args,
1683 ElementsAre(VariantWith<NotifyMotionArgs>(
1684 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT))));
1685
1686 // any updates in existing move gesture should be ignored
1687 moveGesture = Gesture(kGestureMove, currentTime, currentTime, -5, 10);
1688 args = converter.handleGesture(currentTime, READ_TIME, gestureStartTime, moveGesture);
1689 ASSERT_EQ(0u, args.size());
1690
1691 // New gesture should not be affected
1692 currentTime += 100;
1693 moveGesture = Gesture(kGestureMove, currentTime, currentTime, -5, 10);
1694 args = converter.handleGesture(currentTime, READ_TIME, currentTime, moveGesture);
1695 ASSERT_THAT(args,
1696 ElementsAre(VariantWith<NotifyMotionArgs>(
1697 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER)),
1698 VariantWith<NotifyMotionArgs>(
1699 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))));
1700 }
1701
1702 } // namespace android
1703