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