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