1 /*
2 * Copyright (C) 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 #pragma once
18
19 #include <cmath>
20 #include <compare>
21 #include <ios>
22
23 #include <android-base/stringprintf.h>
24 #include <android/input.h>
25 #include <gmock/gmock.h>
26 #include <gtest/gtest.h>
27 #include <input/Input.h>
28 #include <input/PrintTools.h>
29
30 #include "NotifyArgs.h"
31 #include "TestConstants.h"
32
33 namespace android {
34
35 struct PointF {
36 float x;
37 float y;
38 auto operator<=>(const PointF&) const = default;
39 };
40
pointFToString(const PointF & p)41 inline std::string pointFToString(const PointF& p) {
42 return std::string("(") + std::to_string(p.x) + ", " + std::to_string(p.y) + ")";
43 }
44
45 /// Source
46 class WithSourceMatcher {
47 public:
48 using is_gtest_matcher = void;
WithSourceMatcher(uint32_t source)49 explicit WithSourceMatcher(uint32_t source) : mSource(source) {}
50
MatchAndExplain(const NotifyMotionArgs & args,std::ostream *)51 bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
52 return mSource == args.source;
53 }
54
MatchAndExplain(const NotifyKeyArgs & args,std::ostream *)55 bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
56 return mSource == args.source;
57 }
58
MatchAndExplain(const InputEvent & event,std::ostream *)59 bool MatchAndExplain(const InputEvent& event, std::ostream*) const {
60 return mSource == event.getSource();
61 }
62
DescribeTo(std::ostream * os)63 void DescribeTo(std::ostream* os) const {
64 *os << "with source " << inputEventSourceToString(mSource);
65 }
66
DescribeNegationTo(std::ostream * os)67 void DescribeNegationTo(std::ostream* os) const { *os << "wrong source"; }
68
69 private:
70 const uint32_t mSource;
71 };
72
WithSource(uint32_t source)73 inline WithSourceMatcher WithSource(uint32_t source) {
74 return WithSourceMatcher(source);
75 }
76
77 /// Key action
78 class WithKeyActionMatcher {
79 public:
80 using is_gtest_matcher = void;
WithKeyActionMatcher(int32_t action)81 explicit WithKeyActionMatcher(int32_t action) : mAction(action) {}
82
MatchAndExplain(const NotifyKeyArgs & args,std::ostream *)83 bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
84 return mAction == args.action;
85 }
86
MatchAndExplain(const KeyEvent & event,std::ostream *)87 bool MatchAndExplain(const KeyEvent& event, std::ostream*) const {
88 return mAction == event.getAction();
89 }
90
DescribeTo(std::ostream * os)91 void DescribeTo(std::ostream* os) const {
92 *os << "with key action " << KeyEvent::actionToString(mAction);
93 }
94
DescribeNegationTo(std::ostream * os)95 void DescribeNegationTo(std::ostream* os) const { *os << "wrong action"; }
96
97 private:
98 const int32_t mAction;
99 };
100
WithKeyAction(int32_t action)101 inline WithKeyActionMatcher WithKeyAction(int32_t action) {
102 return WithKeyActionMatcher(action);
103 }
104
105 /// Motion action
106 class WithMotionActionMatcher {
107 public:
108 using is_gtest_matcher = void;
WithMotionActionMatcher(int32_t action)109 explicit WithMotionActionMatcher(int32_t action) : mAction(action) {}
110
MatchAndExplain(const NotifyMotionArgs & args,std::ostream *)111 bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
112 bool matches = mAction == args.action;
113 if (args.action == AMOTION_EVENT_ACTION_CANCEL) {
114 matches &= (args.flags & AMOTION_EVENT_FLAG_CANCELED) != 0;
115 }
116 return matches;
117 }
118
MatchAndExplain(const MotionEvent & event,std::ostream *)119 bool MatchAndExplain(const MotionEvent& event, std::ostream*) const {
120 bool matches = mAction == event.getAction();
121 if (event.getAction() == AMOTION_EVENT_ACTION_CANCEL) {
122 matches &= (event.getFlags() & AMOTION_EVENT_FLAG_CANCELED) != 0;
123 }
124 return matches;
125 }
126
DescribeTo(std::ostream * os)127 void DescribeTo(std::ostream* os) const {
128 *os << "with motion action " << MotionEvent::actionToString(mAction);
129 if (mAction == AMOTION_EVENT_ACTION_CANCEL) {
130 *os << " and FLAG_CANCELED";
131 }
132 }
133
DescribeNegationTo(std::ostream * os)134 void DescribeNegationTo(std::ostream* os) const { *os << "wrong action"; }
135
136 private:
137 const int32_t mAction;
138 };
139
WithMotionAction(int32_t action)140 inline WithMotionActionMatcher WithMotionAction(int32_t action) {
141 return WithMotionActionMatcher(action);
142 }
143
144 /// Display Id
145 class WithDisplayIdMatcher {
146 public:
147 using is_gtest_matcher = void;
WithDisplayIdMatcher(ui::LogicalDisplayId displayId)148 explicit WithDisplayIdMatcher(ui::LogicalDisplayId displayId) : mDisplayId(displayId) {}
149
MatchAndExplain(const NotifyMotionArgs & args,std::ostream *)150 bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
151 return mDisplayId == args.displayId;
152 }
153
MatchAndExplain(const NotifyKeyArgs & args,std::ostream *)154 bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
155 return mDisplayId == args.displayId;
156 }
157
MatchAndExplain(const InputEvent & event,std::ostream *)158 bool MatchAndExplain(const InputEvent& event, std::ostream*) const {
159 return mDisplayId == event.getDisplayId();
160 }
161
DescribeTo(std::ostream * os)162 void DescribeTo(std::ostream* os) const { *os << "with display id " << mDisplayId; }
163
DescribeNegationTo(std::ostream * os)164 void DescribeNegationTo(std::ostream* os) const { *os << "wrong display id"; }
165
166 private:
167 const ui::LogicalDisplayId mDisplayId;
168 };
169
WithDisplayId(ui::LogicalDisplayId displayId)170 inline WithDisplayIdMatcher WithDisplayId(ui::LogicalDisplayId displayId) {
171 return WithDisplayIdMatcher(displayId);
172 }
173
174 /// Device Id
175 class WithDeviceIdMatcher {
176 public:
177 using is_gtest_matcher = void;
WithDeviceIdMatcher(int32_t deviceId)178 explicit WithDeviceIdMatcher(int32_t deviceId) : mDeviceId(deviceId) {}
179
MatchAndExplain(const NotifyMotionArgs & args,std::ostream *)180 bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
181 return mDeviceId == args.deviceId;
182 }
183
MatchAndExplain(const NotifyKeyArgs & args,std::ostream *)184 bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
185 return mDeviceId == args.deviceId;
186 }
187
MatchAndExplain(const NotifyDeviceResetArgs & args,std::ostream *)188 bool MatchAndExplain(const NotifyDeviceResetArgs& args, std::ostream*) const {
189 return mDeviceId == args.deviceId;
190 }
191
MatchAndExplain(const InputEvent & event,std::ostream *)192 bool MatchAndExplain(const InputEvent& event, std::ostream*) const {
193 return mDeviceId == event.getDeviceId();
194 }
195
DescribeTo(std::ostream * os)196 void DescribeTo(std::ostream* os) const { *os << "with device id " << mDeviceId; }
197
DescribeNegationTo(std::ostream * os)198 void DescribeNegationTo(std::ostream* os) const { *os << "wrong device id"; }
199
200 private:
201 const int32_t mDeviceId;
202 };
203
WithDeviceId(int32_t deviceId)204 inline WithDeviceIdMatcher WithDeviceId(int32_t deviceId) {
205 return WithDeviceIdMatcher(deviceId);
206 }
207
208 /// Flags
209 class WithFlagsMatcher {
210 public:
211 using is_gtest_matcher = void;
WithFlagsMatcher(int32_t flags)212 explicit WithFlagsMatcher(int32_t flags) : mFlags(flags) {}
213
MatchAndExplain(const NotifyMotionArgs & args,std::ostream *)214 bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
215 return mFlags == args.flags;
216 }
217
MatchAndExplain(const NotifyKeyArgs & args,std::ostream *)218 bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
219 return mFlags == args.flags;
220 }
221
MatchAndExplain(const MotionEvent & event,std::ostream *)222 bool MatchAndExplain(const MotionEvent& event, std::ostream*) const {
223 return mFlags == event.getFlags();
224 }
225
MatchAndExplain(const KeyEvent & event,std::ostream *)226 bool MatchAndExplain(const KeyEvent& event, std::ostream*) const {
227 return mFlags == event.getFlags();
228 }
229
DescribeTo(std::ostream * os)230 void DescribeTo(std::ostream* os) const {
231 *os << "with flags " << base::StringPrintf("0x%x", mFlags);
232 }
233
DescribeNegationTo(std::ostream * os)234 void DescribeNegationTo(std::ostream* os) const { *os << "wrong flags"; }
235
236 private:
237 const int32_t mFlags;
238 };
239
WithFlags(int32_t flags)240 inline WithFlagsMatcher WithFlags(int32_t flags) {
241 return WithFlagsMatcher(flags);
242 }
243
244 /// DownTime
245 class WithDownTimeMatcher {
246 public:
247 using is_gtest_matcher = void;
WithDownTimeMatcher(nsecs_t downTime)248 explicit WithDownTimeMatcher(nsecs_t downTime) : mDownTime(downTime) {}
249
MatchAndExplain(const NotifyMotionArgs & args,std::ostream *)250 bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
251 return mDownTime == args.downTime;
252 }
253
MatchAndExplain(const NotifyKeyArgs & args,std::ostream *)254 bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
255 return mDownTime == args.downTime;
256 }
257
MatchAndExplain(const MotionEvent & event,std::ostream *)258 bool MatchAndExplain(const MotionEvent& event, std::ostream*) const {
259 return mDownTime == event.getDownTime();
260 }
261
MatchAndExplain(const KeyEvent & event,std::ostream *)262 bool MatchAndExplain(const KeyEvent& event, std::ostream*) const {
263 return mDownTime == event.getDownTime();
264 }
265
DescribeTo(std::ostream * os)266 void DescribeTo(std::ostream* os) const { *os << "with down time " << mDownTime; }
267
DescribeNegationTo(std::ostream * os)268 void DescribeNegationTo(std::ostream* os) const { *os << "wrong down time"; }
269
270 private:
271 const nsecs_t mDownTime;
272 };
273
WithDownTime(nsecs_t downTime)274 inline WithDownTimeMatcher WithDownTime(nsecs_t downTime) {
275 return WithDownTimeMatcher(downTime);
276 }
277
278 /// Coordinate matcher
279 class WithCoordsMatcher {
280 public:
281 using is_gtest_matcher = void;
WithCoordsMatcher(size_t pointerIndex,float x,float y)282 explicit WithCoordsMatcher(size_t pointerIndex, float x, float y)
283 : mPointerIndex(pointerIndex), mX(x), mY(y) {}
284
MatchAndExplain(const MotionEvent & event,std::ostream * os)285 bool MatchAndExplain(const MotionEvent& event, std::ostream* os) const {
286 if (mPointerIndex >= event.getPointerCount()) {
287 *os << "Pointer index " << mPointerIndex << " is out of bounds";
288 return false;
289 }
290
291 bool matches = mX == event.getX(mPointerIndex) && mY == event.getY(mPointerIndex);
292 if (!matches) {
293 *os << "expected coords (" << mX << ", " << mY << ") at pointer index " << mPointerIndex
294 << ", but got (" << event.getX(mPointerIndex) << ", " << event.getY(mPointerIndex)
295 << ")";
296 }
297 return matches;
298 }
299
MatchAndExplain(const NotifyMotionArgs & event,std::ostream * os)300 bool MatchAndExplain(const NotifyMotionArgs& event, std::ostream* os) const {
301 if (mPointerIndex >= event.pointerCoords.size()) {
302 *os << "Pointer index " << mPointerIndex << " is out of bounds";
303 return false;
304 }
305
306 bool matches = mX == event.pointerCoords[mPointerIndex].getX() &&
307 mY == event.pointerCoords[mPointerIndex].getY();
308 if (!matches) {
309 *os << "expected coords (" << mX << ", " << mY << ") at pointer index " << mPointerIndex
310 << ", but got (" << event.pointerCoords[mPointerIndex].getX() << ", "
311 << event.pointerCoords[mPointerIndex].getY() << ")";
312 }
313 return matches;
314 }
315
DescribeTo(std::ostream * os)316 void DescribeTo(std::ostream* os) const {
317 *os << "with coords (" << mX << ", " << mY << ") at pointer index " << mPointerIndex;
318 }
319
DescribeNegationTo(std::ostream * os)320 void DescribeNegationTo(std::ostream* os) const { *os << "wrong coords"; }
321
322 private:
323 const size_t mPointerIndex;
324 const float mX;
325 const float mY;
326 };
327
WithCoords(float x,float y)328 inline WithCoordsMatcher WithCoords(float x, float y) {
329 return WithCoordsMatcher(0, x, y);
330 }
331
WithPointerCoords(size_t pointerIndex,float x,float y)332 inline WithCoordsMatcher WithPointerCoords(size_t pointerIndex, float x, float y) {
333 return WithCoordsMatcher(pointerIndex, x, y);
334 }
335
336 /// Raw coordinate matcher
337 class WithRawCoordsMatcher {
338 public:
339 using is_gtest_matcher = void;
WithRawCoordsMatcher(size_t pointerIndex,float rawX,float rawY)340 explicit WithRawCoordsMatcher(size_t pointerIndex, float rawX, float rawY)
341 : mPointerIndex(pointerIndex), mRawX(rawX), mRawY(rawY) {}
342
MatchAndExplain(const MotionEvent & event,std::ostream * os)343 bool MatchAndExplain(const MotionEvent& event, std::ostream* os) const {
344 if (mPointerIndex >= event.getPointerCount()) {
345 *os << "Pointer index " << mPointerIndex << " is out of bounds";
346 return false;
347 }
348
349 bool matches =
350 mRawX == event.getRawX(mPointerIndex) && mRawY == event.getRawY(mPointerIndex);
351 if (!matches) {
352 *os << "expected raw coords (" << mRawX << ", " << mRawY << ") at pointer index "
353 << mPointerIndex << ", but got (" << event.getRawX(mPointerIndex) << ", "
354 << event.getRawY(mPointerIndex) << ")";
355 }
356 return matches;
357 }
358
DescribeTo(std::ostream * os)359 void DescribeTo(std::ostream* os) const {
360 *os << "with raw coords (" << mRawX << ", " << mRawY << ") at pointer index "
361 << mPointerIndex;
362 }
363
DescribeNegationTo(std::ostream * os)364 void DescribeNegationTo(std::ostream* os) const { *os << "wrong raw coords"; }
365
366 private:
367 const size_t mPointerIndex;
368 const float mRawX;
369 const float mRawY;
370 };
371
WithRawCoords(float rawX,float rawY)372 inline WithRawCoordsMatcher WithRawCoords(float rawX, float rawY) {
373 return WithRawCoordsMatcher(0, rawX, rawY);
374 }
375
WithPointerRawCoords(size_t pointerIndex,float rawX,float rawY)376 inline WithRawCoordsMatcher WithPointerRawCoords(size_t pointerIndex, float rawX, float rawY) {
377 return WithRawCoordsMatcher(pointerIndex, rawX, rawY);
378 }
379
380 /// Pointer count
381 class WithPointerCountMatcher {
382 public:
383 using is_gtest_matcher = void;
WithPointerCountMatcher(size_t pointerCount)384 explicit WithPointerCountMatcher(size_t pointerCount) : mPointerCount(pointerCount) {}
385
MatchAndExplain(const MotionEvent & event,std::ostream * os)386 bool MatchAndExplain(const MotionEvent& event, std::ostream* os) const {
387 if (event.getPointerCount() != mPointerCount) {
388 *os << "expected pointer count " << mPointerCount << ", but got "
389 << event.getPointerCount();
390 return false;
391 }
392 return true;
393 }
394
MatchAndExplain(const NotifyMotionArgs & event,std::ostream * os)395 bool MatchAndExplain(const NotifyMotionArgs& event, std::ostream* os) const {
396 if (event.pointerCoords.size() != mPointerCount) {
397 *os << "expected pointer count " << mPointerCount << ", but got "
398 << event.pointerCoords.size();
399 return false;
400 }
401 return true;
402 }
403
DescribeTo(std::ostream * os)404 void DescribeTo(std::ostream* os) const { *os << "with pointer count " << mPointerCount; }
405
DescribeNegationTo(std::ostream * os)406 void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointer count"; }
407
408 private:
409 const size_t mPointerCount;
410 };
411
WithPointerCount(size_t pointerCount)412 inline WithPointerCountMatcher WithPointerCount(size_t pointerCount) {
413 return WithPointerCountMatcher(pointerCount);
414 }
415
416 /// Pointers matcher
417 class WithPointersMatcher {
418 public:
419 using is_gtest_matcher = void;
WithPointersMatcher(std::map<int32_t,PointF> pointers)420 explicit WithPointersMatcher(std::map<int32_t, PointF> pointers) : mPointers(pointers) {}
421
MatchAndExplain(const MotionEvent & event,std::ostream * os)422 bool MatchAndExplain(const MotionEvent& event, std::ostream* os) const {
423 std::map<int32_t, PointF> actualPointers;
424 for (size_t pointerIndex = 0; pointerIndex < event.getPointerCount(); pointerIndex++) {
425 const int32_t pointerId = event.getPointerId(pointerIndex);
426 actualPointers[pointerId] = {event.getX(pointerIndex), event.getY(pointerIndex)};
427 }
428
429 if (mPointers != actualPointers) {
430 *os << "expected pointers " << dumpMap(mPointers, constToString, pointFToString)
431 << ", but got " << dumpMap(actualPointers, constToString, pointFToString);
432 return false;
433 }
434 return true;
435 }
436
MatchAndExplain(const NotifyMotionArgs & event,std::ostream * os)437 bool MatchAndExplain(const NotifyMotionArgs& event, std::ostream* os) const {
438 std::map<int32_t, PointF> actualPointers;
439 for (size_t pointerIndex = 0; pointerIndex < event.pointerCoords.size(); pointerIndex++) {
440 const int32_t pointerId = event.pointerProperties[pointerIndex].id;
441 actualPointers[pointerId] = {event.pointerCoords[pointerIndex].getX(),
442 event.pointerCoords[pointerIndex].getY()};
443 }
444
445 if (mPointers != actualPointers) {
446 *os << "expected pointers " << dumpMap(mPointers, constToString, pointFToString)
447 << ", but got " << dumpMap(actualPointers, constToString, pointFToString);
448 return false;
449 }
450 return true;
451 }
452
DescribeTo(std::ostream * os)453 void DescribeTo(std::ostream* os) const {
454 *os << "with pointers " << dumpMap(mPointers, constToString, pointFToString);
455 }
456
DescribeNegationTo(std::ostream * os)457 void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointers"; }
458
459 private:
460 const std::map<int32_t, PointF> mPointers;
461 };
462
WithPointers(const std::map<int32_t,PointF> & pointers)463 inline WithPointersMatcher WithPointers(
464 const std::map<int32_t /*id*/, PointF /*coords*/>& pointers) {
465 return WithPointersMatcher(pointers);
466 }
467
468 /// Pointer ids matcher
469 class WithPointerIdsMatcher {
470 public:
471 using is_gtest_matcher = void;
WithPointerIdsMatcher(std::set<int32_t> pointerIds)472 explicit WithPointerIdsMatcher(std::set<int32_t> pointerIds) : mPointerIds(pointerIds) {}
473
MatchAndExplain(const MotionEvent & event,std::ostream * os)474 bool MatchAndExplain(const MotionEvent& event, std::ostream* os) const {
475 std::set<int32_t> actualPointerIds;
476 for (size_t pointerIndex = 0; pointerIndex < event.getPointerCount(); pointerIndex++) {
477 const PointerProperties* properties = event.getPointerProperties(pointerIndex);
478 actualPointerIds.insert(properties->id);
479 }
480
481 if (mPointerIds != actualPointerIds) {
482 *os << "expected pointer ids " << dumpSet(mPointerIds) << ", but got "
483 << dumpSet(actualPointerIds);
484 return false;
485 }
486 return true;
487 }
488
MatchAndExplain(const NotifyMotionArgs & event,std::ostream * os)489 bool MatchAndExplain(const NotifyMotionArgs& event, std::ostream* os) const {
490 std::set<int32_t> actualPointerIds;
491 for (const PointerProperties& properties : event.pointerProperties) {
492 actualPointerIds.insert(properties.id);
493 }
494
495 if (mPointerIds != actualPointerIds) {
496 *os << "expected pointer ids " << dumpSet(mPointerIds) << ", but got "
497 << dumpSet(actualPointerIds);
498 return false;
499 }
500 return true;
501 }
502
DescribeTo(std::ostream * os)503 void DescribeTo(std::ostream* os) const { *os << "with pointer ids " << dumpSet(mPointerIds); }
504
DescribeNegationTo(std::ostream * os)505 void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointer ids"; }
506
507 private:
508 const std::set<int32_t> mPointerIds;
509 };
510
WithPointerIds(const std::set<int32_t> & pointerIds)511 inline WithPointerIdsMatcher WithPointerIds(const std::set<int32_t /*id*/>& pointerIds) {
512 return WithPointerIdsMatcher(pointerIds);
513 }
514
515 /// Key code
516 class WithKeyCodeMatcher {
517 public:
518 using is_gtest_matcher = void;
WithKeyCodeMatcher(int32_t keyCode)519 explicit WithKeyCodeMatcher(int32_t keyCode) : mKeyCode(keyCode) {}
520
MatchAndExplain(const NotifyKeyArgs & args,std::ostream *)521 bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
522 return mKeyCode == args.keyCode;
523 }
524
MatchAndExplain(const KeyEvent & event,std::ostream *)525 bool MatchAndExplain(const KeyEvent& event, std::ostream*) const {
526 return mKeyCode == event.getKeyCode();
527 }
528
DescribeTo(std::ostream * os)529 void DescribeTo(std::ostream* os) const {
530 *os << "with key code " << KeyEvent::getLabel(mKeyCode);
531 }
532
DescribeNegationTo(std::ostream * os)533 void DescribeNegationTo(std::ostream* os) const { *os << "wrong key code"; }
534
535 private:
536 const int32_t mKeyCode;
537 };
538
WithKeyCode(int32_t keyCode)539 inline WithKeyCodeMatcher WithKeyCode(int32_t keyCode) {
540 return WithKeyCodeMatcher(keyCode);
541 }
542
543 /// EventId
544 class WithEventIdMatcher {
545 public:
546 using is_gtest_matcher = void;
WithEventIdMatcher(int32_t eventId)547 explicit WithEventIdMatcher(int32_t eventId) : mEventId(eventId) {}
548
MatchAndExplain(const NotifyMotionArgs & args,std::ostream *)549 bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
550 return mEventId == args.id;
551 }
552
MatchAndExplain(const NotifyKeyArgs & args,std::ostream *)553 bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
554 return mEventId == args.id;
555 }
556
MatchAndExplain(const InputEvent & event,std::ostream *)557 bool MatchAndExplain(const InputEvent& event, std::ostream*) const {
558 return mEventId == event.getId();
559 }
560
DescribeTo(std::ostream * os)561 void DescribeTo(std::ostream* os) const { *os << "with eventId 0x" << std::hex << mEventId; }
562
DescribeNegationTo(std::ostream * os)563 void DescribeNegationTo(std::ostream* os) const {
564 *os << "with eventId not equal to 0x" << std::hex << mEventId;
565 }
566
567 private:
568 const int32_t mEventId;
569 };
570
WithEventId(int32_t eventId)571 inline WithEventIdMatcher WithEventId(int32_t eventId) {
572 return WithEventIdMatcher(eventId);
573 }
574
575 /// EventIdSource
576 class WithEventIdSourceMatcher {
577 public:
578 using is_gtest_matcher = void;
WithEventIdSourceMatcher(IdGenerator::Source eventIdSource)579 explicit WithEventIdSourceMatcher(IdGenerator::Source eventIdSource)
580 : mEventIdSource(eventIdSource) {}
581
MatchAndExplain(const NotifyMotionArgs & args,std::ostream *)582 bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
583 return mEventIdSource == IdGenerator::getSource(args.id);
584 }
585
MatchAndExplain(const NotifyKeyArgs & args,std::ostream *)586 bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
587 return mEventIdSource == IdGenerator::getSource(args.id);
588 }
589
MatchAndExplain(const InputEvent & event,std::ostream *)590 bool MatchAndExplain(const InputEvent& event, std::ostream*) const {
591 return mEventIdSource == IdGenerator::getSource(event.getId());
592 }
593
DescribeTo(std::ostream * os)594 void DescribeTo(std::ostream* os) const {
595 *os << "with eventId from source 0x" << std::hex << ftl::to_underlying(mEventIdSource);
596 }
597
DescribeNegationTo(std::ostream * os)598 void DescribeNegationTo(std::ostream* os) const { *os << "wrong event from source"; }
599
600 private:
601 const IdGenerator::Source mEventIdSource;
602 };
603
WithEventIdSource(IdGenerator::Source eventIdSource)604 inline WithEventIdSourceMatcher WithEventIdSource(IdGenerator::Source eventIdSource) {
605 return WithEventIdSourceMatcher(eventIdSource);
606 }
607
608 MATCHER_P(WithRepeatCount, repeatCount, "KeyEvent with specified repeat count") {
609 return arg.getRepeatCount() == repeatCount;
610 }
611
612 MATCHER_P2(WithPointerId, index, id, "MotionEvent with specified pointer ID for pointer index") {
613 const auto argPointerId = arg.pointerProperties[index].id;
614 *result_listener << "expected pointer with index " << index << " to have ID " << argPointerId;
615 return argPointerId == id;
616 }
617
618 MATCHER_P2(WithCursorPosition, x, y, "InputEvent with specified cursor position") {
619 const auto argX = arg.xCursorPosition;
620 const auto argY = arg.yCursorPosition;
621 *result_listener << "expected cursor position (" << x << ", " << y << "), but got (" << argX
622 << ", " << argY << ")";
623 return (isnan(x) ? isnan(argX) : x == argX) && (isnan(y) ? isnan(argY) : y == argY);
624 }
625
626 MATCHER_P2(WithRelativeMotion, x, y, "InputEvent with specified relative motion") {
627 const auto argX = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
628 const auto argY = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
629 *result_listener << "expected relative motion (" << x << ", " << y << "), but got (" << argX
630 << ", " << argY << ")";
631 return argX == x && argY == y;
632 }
633
634 MATCHER_P3(WithGestureOffset, dx, dy, epsilon,
635 "InputEvent with specified touchpad gesture offset") {
636 const auto argGestureX = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET);
637 const auto argGestureY = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET);
638 const double xDiff = fabs(argGestureX - dx);
639 const double yDiff = fabs(argGestureY - dy);
640 *result_listener << "expected gesture offset (" << dx << ", " << dy << ") within " << epsilon
641 << ", but got (" << argGestureX << ", " << argGestureY << ")";
642 return xDiff <= epsilon && yDiff <= epsilon;
643 }
644
645 MATCHER_P3(WithGestureScrollDistance, x, y, epsilon,
646 "InputEvent with specified touchpad gesture scroll distance") {
647 const auto argXDistance =
648 arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_X_DISTANCE);
649 const auto argYDistance =
650 arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_Y_DISTANCE);
651 const double xDiff = fabs(argXDistance - x);
652 const double yDiff = fabs(argYDistance - y);
653 *result_listener << "expected gesture offset (" << x << ", " << y << ") within " << epsilon
654 << ", but got (" << argXDistance << ", " << argYDistance << ")";
655 return xDiff <= epsilon && yDiff <= epsilon;
656 }
657
658 MATCHER_P2(WithGesturePinchScaleFactor, factor, epsilon,
659 "InputEvent with specified touchpad pinch gesture scale factor") {
660 const auto argScaleFactor =
661 arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR);
662 *result_listener << "expected gesture scale factor " << factor << " within " << epsilon
663 << " but got " << argScaleFactor;
664 return fabs(argScaleFactor - factor) <= epsilon;
665 }
666
667 MATCHER_P(WithGestureSwipeFingerCount, count,
668 "InputEvent with specified touchpad swipe finger count") {
669 const auto argFingerCount =
670 arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_SWIPE_FINGER_COUNT);
671 *result_listener << "expected gesture swipe finger count " << count << " but got "
672 << argFingerCount;
673 return fabs(argFingerCount - count) <= EPSILON;
674 }
675
676 MATCHER_P(WithPressure, pressure, "InputEvent with specified pressure") {
677 const auto argPressure = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE);
678 *result_listener << "expected pressure " << pressure << ", but got " << argPressure;
679 return argPressure == pressure;
680 }
681
682 MATCHER_P(WithSize, size, "MotionEvent with specified size") {
683 const auto argSize = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_SIZE);
684 *result_listener << "expected size " << size << ", but got " << argSize;
685 return argSize == size;
686 }
687
688 MATCHER_P(WithOrientation, orientation, "MotionEvent with specified orientation") {
689 const auto argOrientation = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
690 *result_listener << "expected orientation " << orientation << ", but got " << argOrientation;
691 return argOrientation == orientation;
692 }
693
694 MATCHER_P(WithDistance, distance, "MotionEvent with specified distance") {
695 const auto argDistance = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_DISTANCE);
696 *result_listener << "expected distance " << distance << ", but got " << argDistance;
697 return argDistance == distance;
698 }
699
700 MATCHER_P2(WithTouchDimensions, maj, min, "InputEvent with specified touch dimensions") {
701 const auto argMajor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR);
702 const auto argMinor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR);
703 *result_listener << "expected touch dimensions " << maj << " major x " << min
704 << " minor, but got " << argMajor << " major x " << argMinor << " minor";
705 return argMajor == maj && argMinor == min;
706 }
707
708 MATCHER_P2(WithToolDimensions, maj, min, "InputEvent with specified tool dimensions") {
709 const auto argMajor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR);
710 const auto argMinor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR);
711 *result_listener << "expected tool dimensions " << maj << " major x " << min
712 << " minor, but got " << argMajor << " major x " << argMinor << " minor";
713 return argMajor == maj && argMinor == min;
714 }
715
716 MATCHER_P(WithToolType, toolType, "InputEvent with specified tool type") {
717 const auto argToolType = arg.pointerProperties[0].toolType;
718 *result_listener << "expected tool type " << ftl::enum_string(toolType) << ", but got "
719 << ftl::enum_string(argToolType);
720 return argToolType == toolType;
721 }
722
723 MATCHER_P2(WithPointerToolType, pointer, toolType,
724 "InputEvent with specified tool type for pointer") {
725 const auto argToolType = arg.pointerProperties[pointer].toolType;
726 *result_listener << "expected pointer " << pointer << " to have tool type "
727 << ftl::enum_string(toolType) << ", but got " << ftl::enum_string(argToolType);
728 return argToolType == toolType;
729 }
730
731 MATCHER_P(WithMotionClassification, classification,
732 "InputEvent with specified MotionClassification") {
733 *result_listener << "expected classification " << motionClassificationToString(classification)
734 << ", but got " << motionClassificationToString(arg.classification);
735 return arg.classification == classification;
736 }
737
738 MATCHER_P(WithButtonState, buttons, "InputEvent with specified button state") {
739 *result_listener << "expected button state " << buttons << ", but got " << arg.buttonState;
740 return arg.buttonState == buttons;
741 }
742
743 MATCHER_P(WithMetaState, metaState, "InputEvent with specified meta state") {
744 *result_listener << "expected meta state 0x" << std::hex << metaState << ", but got 0x"
745 << arg.metaState;
746 return arg.metaState == metaState;
747 }
748
749 MATCHER_P(WithActionButton, actionButton, "InputEvent with specified action button") {
750 *result_listener << "expected action button " << actionButton << ", but got "
751 << arg.actionButton;
752 return arg.actionButton == actionButton;
753 }
754
755 MATCHER_P(WithEventTime, eventTime, "InputEvent with specified eventTime") {
756 *result_listener << "expected event time " << eventTime << ", but got " << arg.eventTime;
757 return arg.eventTime == eventTime;
758 }
759
760 MATCHER_P(WithDownTime, downTime, "InputEvent with specified downTime") {
761 *result_listener << "expected down time " << downTime << ", but got " << arg.downTime;
762 return arg.downTime == downTime;
763 }
764
765 MATCHER_P2(WithPrecision, xPrecision, yPrecision, "MotionEvent with specified precision") {
766 *result_listener << "expected x-precision " << xPrecision << " and y-precision " << yPrecision
767 << ", but got " << arg.xPrecision << " and " << arg.yPrecision;
768 return arg.xPrecision == xPrecision && arg.yPrecision == yPrecision;
769 }
770
771 MATCHER_P(WithPolicyFlags, policyFlags, "InputEvent with specified policy flags") {
772 *result_listener << "expected policy flags 0x" << std::hex << policyFlags << ", but got 0x"
773 << arg.policyFlags;
774 return arg.policyFlags == static_cast<uint32_t>(policyFlags);
775 }
776
777 MATCHER_P(WithEdgeFlags, edgeFlags, "InputEvent with specified edge flags") {
778 *result_listener << "expected edge flags 0x" << std::hex << edgeFlags << ", but got 0x"
779 << arg.edgeFlags;
780 return arg.edgeFlags == edgeFlags;
781 }
782
783 } // namespace android
784