• 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 
21 #include <android/input.h>
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 #include <input/Input.h>
25 
26 #include "TestConstants.h"
27 
28 namespace android {
29 
30 MATCHER_P(WithMotionAction, action, "MotionEvent with specified action") {
31     bool matches = action == arg.action;
32     if (!matches) {
33         *result_listener << "expected action " << MotionEvent::actionToString(action)
34                          << ", but got " << MotionEvent::actionToString(arg.action);
35     }
36     if (action == AMOTION_EVENT_ACTION_CANCEL) {
37         if (!matches) {
38             *result_listener << "; ";
39         }
40         *result_listener << "expected FLAG_CANCELED to be set with ACTION_CANCEL, but was not set";
41         matches &= (arg.flags & AMOTION_EVENT_FLAG_CANCELED) != 0;
42     }
43     return matches;
44 }
45 
46 MATCHER_P(WithKeyAction, action, "KeyEvent with specified action") {
47     *result_listener << "expected action " << KeyEvent::actionToString(action) << ", but got "
48                      << KeyEvent::actionToString(arg.action);
49     return arg.action == action;
50 }
51 
52 MATCHER_P(WithSource, source, "InputEvent with specified source") {
53     *result_listener << "expected source " << inputEventSourceToString(source) << ", but got "
54                      << inputEventSourceToString(arg.source);
55     return arg.source == source;
56 }
57 
58 MATCHER_P(WithDisplayId, displayId, "InputEvent with specified displayId") {
59     *result_listener << "expected displayId " << displayId << ", but got " << arg.displayId;
60     return arg.displayId == displayId;
61 }
62 
63 MATCHER_P(WithDeviceId, deviceId, "InputEvent with specified deviceId") {
64     *result_listener << "expected deviceId " << deviceId << ", but got " << arg.deviceId;
65     return arg.deviceId == deviceId;
66 }
67 
68 MATCHER_P(WithKeyCode, keyCode, "KeyEvent with specified key code") {
69     *result_listener << "expected key code " << keyCode << ", but got " << arg.keyCode;
70     return arg.keyCode == keyCode;
71 }
72 
73 MATCHER_P(WithPointerCount, count, "MotionEvent with specified number of pointers") {
74     *result_listener << "expected " << count << " pointer(s), but got " << arg.getPointerCount();
75     return arg.getPointerCount() == count;
76 }
77 
78 MATCHER_P2(WithPointerId, index, id, "MotionEvent with specified pointer ID for pointer index") {
79     const auto argPointerId = arg.pointerProperties[index].id;
80     *result_listener << "expected pointer with index " << index << " to have ID " << argPointerId;
81     return argPointerId == id;
82 }
83 
84 MATCHER_P2(WithCoords, x, y, "InputEvent with specified coords") {
85     const auto argX = arg.pointerCoords[0].getX();
86     const auto argY = arg.pointerCoords[0].getY();
87     *result_listener << "expected coords (" << x << ", " << y << "), but got (" << argX << ", "
88                      << argY << ")";
89     return argX == x && argY == y;
90 }
91 
92 MATCHER_P3(WithPointerCoords, pointer, x, y, "InputEvent with specified coords for pointer") {
93     const auto argX = arg.pointerCoords[pointer].getX();
94     const auto argY = arg.pointerCoords[pointer].getY();
95     *result_listener << "expected pointer " << pointer << " to have coords (" << x << ", " << y
96                      << "), but got (" << argX << ", " << argY << ")";
97     return argX == x && argY == y;
98 }
99 
100 MATCHER_P2(WithRelativeMotion, x, y, "InputEvent with specified relative motion") {
101     const auto argX = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
102     const auto argY = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
103     *result_listener << "expected relative motion (" << x << ", " << y << "), but got (" << argX
104                      << ", " << argY << ")";
105     return argX == x && argY == y;
106 }
107 
108 MATCHER_P3(WithGestureOffset, dx, dy, epsilon,
109            "InputEvent with specified touchpad gesture offset") {
110     const auto argGestureX = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET);
111     const auto argGestureY = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET);
112     const double xDiff = fabs(argGestureX - dx);
113     const double yDiff = fabs(argGestureY - dy);
114     *result_listener << "expected gesture offset (" << dx << ", " << dy << ") within " << epsilon
115                      << ", but got (" << argGestureX << ", " << argGestureY << ")";
116     return xDiff <= epsilon && yDiff <= epsilon;
117 }
118 
119 MATCHER_P3(WithGestureScrollDistance, x, y, epsilon,
120            "InputEvent with specified touchpad gesture scroll distance") {
121     const auto argXDistance =
122             arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_X_DISTANCE);
123     const auto argYDistance =
124             arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_Y_DISTANCE);
125     const double xDiff = fabs(argXDistance - x);
126     const double yDiff = fabs(argYDistance - y);
127     *result_listener << "expected gesture offset (" << x << ", " << y << ") within " << epsilon
128                      << ", but got (" << argXDistance << ", " << argYDistance << ")";
129     return xDiff <= epsilon && yDiff <= epsilon;
130 }
131 
132 MATCHER_P2(WithGesturePinchScaleFactor, factor, epsilon,
133            "InputEvent with specified touchpad pinch gesture scale factor") {
134     const auto argScaleFactor =
135             arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR);
136     *result_listener << "expected gesture scale factor " << factor << " within " << epsilon
137                      << " but got " << argScaleFactor;
138     return fabs(argScaleFactor - factor) <= epsilon;
139 }
140 
141 MATCHER_P(WithGestureSwipeFingerCount, count,
142           "InputEvent with specified touchpad swipe finger count") {
143     const auto argFingerCount =
144             arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_SWIPE_FINGER_COUNT);
145     *result_listener << "expected gesture swipe finger count " << count << " but got "
146                      << argFingerCount;
147     return fabs(argFingerCount - count) <= EPSILON;
148 }
149 
150 MATCHER_P(WithPressure, pressure, "InputEvent with specified pressure") {
151     const auto argPressure = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE);
152     *result_listener << "expected pressure " << pressure << ", but got " << argPressure;
153     return argPressure == pressure;
154 }
155 
156 MATCHER_P2(WithTouchDimensions, maj, min, "InputEvent with specified touch dimensions") {
157     const auto argMajor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR);
158     const auto argMinor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR);
159     *result_listener << "expected touch dimensions " << maj << " major x " << min
160                      << " minor, but got " << argMajor << " major x " << argMinor << " minor";
161     return argMajor == maj && argMinor == min;
162 }
163 
164 MATCHER_P2(WithToolDimensions, maj, min, "InputEvent with specified tool dimensions") {
165     const auto argMajor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR);
166     const auto argMinor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR);
167     *result_listener << "expected tool dimensions " << maj << " major x " << min
168                      << " minor, but got " << argMajor << " major x " << argMinor << " minor";
169     return argMajor == maj && argMinor == min;
170 }
171 
172 MATCHER_P(WithToolType, toolType, "InputEvent with specified tool type") {
173     const auto argToolType = arg.pointerProperties[0].toolType;
174     *result_listener << "expected tool type " << ftl::enum_string(toolType) << ", but got "
175                      << ftl::enum_string(argToolType);
176     return argToolType == toolType;
177 }
178 
179 MATCHER_P2(WithPointerToolType, pointer, toolType,
180            "InputEvent with specified tool type for pointer") {
181     const auto argToolType = arg.pointerProperties[pointer].toolType;
182     *result_listener << "expected pointer " << pointer << " to have tool type "
183                      << ftl::enum_string(toolType) << ", but got " << ftl::enum_string(argToolType);
184     return argToolType == toolType;
185 }
186 
187 MATCHER_P(WithFlags, flags, "InputEvent with specified flags") {
188     *result_listener << "expected flags " << flags << ", but got " << arg.flags;
189     return arg.flags == static_cast<int32_t>(flags);
190 }
191 
192 MATCHER_P(WithMotionClassification, classification,
193           "InputEvent with specified MotionClassification") {
194     *result_listener << "expected classification " << motionClassificationToString(classification)
195                      << ", but got " << motionClassificationToString(arg.classification);
196     return arg.classification == classification;
197 }
198 
199 MATCHER_P(WithButtonState, buttons, "InputEvent with specified button state") {
200     *result_listener << "expected button state " << buttons << ", but got " << arg.buttonState;
201     return arg.buttonState == buttons;
202 }
203 
204 MATCHER_P(WithActionButton, actionButton, "InputEvent with specified action button") {
205     *result_listener << "expected action button " << actionButton << ", but got "
206                      << arg.actionButton;
207     return arg.actionButton == actionButton;
208 }
209 
210 MATCHER_P(WithEventTime, eventTime, "InputEvent with specified eventTime") {
211     *result_listener << "expected event time " << eventTime << ", but got " << arg.eventTime;
212     return arg.eventTime == eventTime;
213 }
214 
215 MATCHER_P(WithDownTime, downTime, "InputEvent with specified downTime") {
216     *result_listener << "expected down time " << downTime << ", but got " << arg.downTime;
217     return arg.downTime == downTime;
218 }
219 
220 MATCHER_P2(WithPrecision, xPrecision, yPrecision, "MotionEvent with specified precision") {
221     *result_listener << "expected x-precision " << xPrecision << " and y-precision " << yPrecision
222                      << ", but got " << arg.xPrecision << " and " << arg.yPrecision;
223     return arg.xPrecision == xPrecision && arg.yPrecision == yPrecision;
224 }
225 
226 } // namespace android
227