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