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