blob: e7313a2b93030f5ca1f5c3094a5519d8bb64fc54 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 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
Dominik Laskowski2f01d772022-03-23 16:01:29 -070017#include <cinttypes>
18#include <memory>
19
Prabir Pradhan2770d242019-09-02 18:07:11 -070020#include <CursorInputMapper.h>
21#include <InputDevice.h>
22#include <InputMapper.h>
23#include <InputReader.h>
Prabir Pradhan1aed8582019-12-30 11:46:51 -080024#include <InputReaderBase.h>
25#include <InputReaderFactory.h>
Arthur Hung6d5b4b22022-01-21 07:21:10 +000026#include <JoystickInputMapper.h>
Prabir Pradhan2770d242019-09-02 18:07:11 -070027#include <KeyboardInputMapper.h>
28#include <MultiTouchInputMapper.h>
Chris Ye1dd2e5c2021-04-04 23:12:41 -070029#include <PeripheralController.h>
Chris Yef59a2f42020-10-16 12:55:26 -070030#include <SensorInputMapper.h>
Prabir Pradhan2770d242019-09-02 18:07:11 -070031#include <SingleTouchInputMapper.h>
32#include <SwitchInputMapper.h>
33#include <TestInputListener.h>
Prabir Pradhan739dca42022-09-09 20:12:01 +000034#include <TestInputListenerMatchers.h>
Prabir Pradhan2770d242019-09-02 18:07:11 -070035#include <TouchInputMapper.h>
Prabir Pradhan1aed8582019-12-30 11:46:51 -080036#include <UinputDevice.h>
Chris Ye87143712020-11-10 05:05:58 +000037#include <VibratorInputMapper.h>
Prabir Pradhan2574dfa2019-10-16 16:35:07 -070038#include <android-base/thread_annotations.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080039#include <gtest/gtest.h>
chaviw3277faf2021-05-19 16:45:23 -050040#include <gui/constants.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080041
Siarhei Vishniakou21e96e62022-10-27 10:23:37 -070042#include <thread>
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +000043#include "android/hardware/input/InputDeviceCountryCode.h"
Michael Wrightdde67b82020-10-27 16:09:22 +000044#include "input/DisplayViewport.h"
45#include "input/Input.h"
Michael Wright17db18e2020-06-26 20:51:44 +010046
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +000047using android::hardware::input::InputDeviceCountryCode;
48
Michael Wrightd02c5b62014-02-10 15:10:22 -080049namespace android {
50
Dominik Laskowski2f01d772022-03-23 16:01:29 -070051using namespace ftl::flag_operators;
Prabir Pradhan739dca42022-09-09 20:12:01 +000052using testing::AllOf;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -070053using std::chrono_literals::operator""ms;
54
55// Timeout for waiting for an expected event
56static constexpr std::chrono::duration WAIT_TIMEOUT = 100ms;
57
Michael Wrightd02c5b62014-02-10 15:10:22 -080058// An arbitrary time value.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +000059static constexpr nsecs_t ARBITRARY_TIME = 1234;
60static constexpr nsecs_t READ_TIME = 4321;
Michael Wrightd02c5b62014-02-10 15:10:22 -080061
62// Arbitrary display properties.
arthurhungcc7f9802020-04-30 17:55:40 +080063static constexpr int32_t DISPLAY_ID = 0;
Prabir Pradhanc13ff082022-09-08 22:03:30 +000064static const std::string DISPLAY_UNIQUE_ID = "local:1";
arthurhungcc7f9802020-04-30 17:55:40 +080065static constexpr int32_t SECONDARY_DISPLAY_ID = DISPLAY_ID + 1;
Prabir Pradhanc13ff082022-09-08 22:03:30 +000066static const std::string SECONDARY_DISPLAY_UNIQUE_ID = "local:2";
arthurhungcc7f9802020-04-30 17:55:40 +080067static constexpr int32_t DISPLAY_WIDTH = 480;
68static constexpr int32_t DISPLAY_HEIGHT = 800;
69static constexpr int32_t VIRTUAL_DISPLAY_ID = 1;
70static constexpr int32_t VIRTUAL_DISPLAY_WIDTH = 400;
71static constexpr int32_t VIRTUAL_DISPLAY_HEIGHT = 500;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -070072static const char* VIRTUAL_DISPLAY_UNIQUE_ID = "virtual:1";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -070073static constexpr std::optional<uint8_t> NO_PORT = std::nullopt; // no physical port is specified
Michael Wrightd02c5b62014-02-10 15:10:22 -080074
arthurhungcc7f9802020-04-30 17:55:40 +080075static constexpr int32_t FIRST_SLOT = 0;
76static constexpr int32_t SECOND_SLOT = 1;
77static constexpr int32_t THIRD_SLOT = 2;
78static constexpr int32_t INVALID_TRACKING_ID = -1;
79static constexpr int32_t FIRST_TRACKING_ID = 0;
80static constexpr int32_t SECOND_TRACKING_ID = 1;
81static constexpr int32_t THIRD_TRACKING_ID = 2;
Chris Yee2b1e5c2021-03-10 22:45:12 -080082static constexpr int32_t DEFAULT_BATTERY = 1;
Kim Low03ea0352020-11-06 12:45:07 -080083static constexpr int32_t BATTERY_STATUS = 4;
84static constexpr int32_t BATTERY_CAPACITY = 66;
Prabir Pradhane287ecd2022-09-07 21:18:05 +000085static const std::string BATTERY_DEVPATH = "/sys/devices/mydevice/power_supply/mybattery";
Chris Ye3fdbfef2021-01-06 18:45:18 -080086static constexpr int32_t LIGHT_BRIGHTNESS = 0x55000000;
87static constexpr int32_t LIGHT_COLOR = 0x7F448866;
88static constexpr int32_t LIGHT_PLAYER_ID = 2;
arthurhungcc7f9802020-04-30 17:55:40 +080089
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080090static constexpr int32_t ACTION_POINTER_0_DOWN =
91 AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
92static constexpr int32_t ACTION_POINTER_0_UP =
93 AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
94static constexpr int32_t ACTION_POINTER_1_DOWN =
95 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
96static constexpr int32_t ACTION_POINTER_1_UP =
97 AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
98
Michael Wrightd02c5b62014-02-10 15:10:22 -080099// Error tolerance for floating point assertions.
100static const float EPSILON = 0.001f;
101
102template<typename T>
103static inline T min(T a, T b) {
104 return a < b ? a : b;
105}
106
107static inline float avg(float x, float y) {
108 return (x + y) / 2;
109}
110
Chris Ye3fdbfef2021-01-06 18:45:18 -0800111// Mapping for light color name and the light color
112const std::unordered_map<std::string, LightColor> LIGHT_COLORS = {{"red", LightColor::RED},
113 {"green", LightColor::GREEN},
114 {"blue", LightColor::BLUE}};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800115
Prabir Pradhanc14266f2021-05-12 15:56:24 -0700116static int32_t getInverseRotation(int32_t orientation) {
117 switch (orientation) {
118 case DISPLAY_ORIENTATION_90:
119 return DISPLAY_ORIENTATION_270;
120 case DISPLAY_ORIENTATION_270:
121 return DISPLAY_ORIENTATION_90;
122 default:
123 return orientation;
124 }
125}
126
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800127static void assertAxisResolution(MultiTouchInputMapper& mapper, int axis, float resolution) {
128 InputDeviceInfo info;
129 mapper.populateDeviceInfo(&info);
130
131 const InputDeviceInfo::MotionRange* motionRange =
132 info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
133 ASSERT_NEAR(motionRange->resolution, resolution, EPSILON);
134}
135
136static void assertAxisNotPresent(MultiTouchInputMapper& mapper, int axis) {
137 InputDeviceInfo info;
138 mapper.populateDeviceInfo(&info);
139
140 const InputDeviceInfo::MotionRange* motionRange =
141 info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
142 ASSERT_EQ(nullptr, motionRange);
143}
144
Siarhei Vishniakou21e96e62022-10-27 10:23:37 -0700145[[maybe_unused]] static void dumpReader(InputReader& reader) {
146 std::string dump;
147 reader.dump(dump);
148 std::istringstream iss(dump);
149 for (std::string line; std::getline(iss, line);) {
150 ALOGE("%s", line.c_str());
151 std::this_thread::sleep_for(std::chrono::milliseconds(1));
152 }
153}
154
Michael Wrightd02c5b62014-02-10 15:10:22 -0800155// --- FakePointerController ---
156
157class FakePointerController : public PointerControllerInterface {
158 bool mHaveBounds;
159 float mMinX, mMinY, mMaxX, mMaxY;
160 float mX, mY;
161 int32_t mButtonState;
Arthur Hungc7ad2d02018-12-18 17:41:29 +0800162 int32_t mDisplayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800163
Michael Wrightd02c5b62014-02-10 15:10:22 -0800164public:
165 FakePointerController() :
166 mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0), mX(0), mY(0),
Arthur Hungc7ad2d02018-12-18 17:41:29 +0800167 mButtonState(0), mDisplayId(ADISPLAY_ID_DEFAULT) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800168 }
169
Michael Wright17db18e2020-06-26 20:51:44 +0100170 virtual ~FakePointerController() {}
171
Michael Wrightd02c5b62014-02-10 15:10:22 -0800172 void setBounds(float minX, float minY, float maxX, float maxY) {
173 mHaveBounds = true;
174 mMinX = minX;
175 mMinY = minY;
176 mMaxX = maxX;
177 mMaxY = maxY;
178 }
179
Chris Yea52ade12020-08-27 16:49:20 -0700180 void setPosition(float x, float y) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800181 mX = x;
182 mY = y;
183 }
184
Chris Yea52ade12020-08-27 16:49:20 -0700185 void setButtonState(int32_t buttonState) override { mButtonState = buttonState; }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800186
Chris Yea52ade12020-08-27 16:49:20 -0700187 int32_t getButtonState() const override { return mButtonState; }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800188
Chris Yea52ade12020-08-27 16:49:20 -0700189 void getPosition(float* outX, float* outY) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800190 *outX = mX;
191 *outY = mY;
192 }
193
Chris Yea52ade12020-08-27 16:49:20 -0700194 int32_t getDisplayId() const override { return mDisplayId; }
Arthur Hungc7ad2d02018-12-18 17:41:29 +0800195
Chris Yea52ade12020-08-27 16:49:20 -0700196 void setDisplayViewport(const DisplayViewport& viewport) override {
Garfield Tan888a6a42020-01-09 11:39:16 -0800197 mDisplayId = viewport.displayId;
198 }
199
Arthur Hung7c645402019-01-25 17:45:42 +0800200 const std::map<int32_t, std::vector<int32_t>>& getSpots() {
201 return mSpotsByDisplay;
202 }
203
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204private:
Chris Yea52ade12020-08-27 16:49:20 -0700205 bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800206 *outMinX = mMinX;
207 *outMinY = mMinY;
208 *outMaxX = mMaxX;
209 *outMaxY = mMaxY;
210 return mHaveBounds;
211 }
212
Chris Yea52ade12020-08-27 16:49:20 -0700213 void move(float deltaX, float deltaY) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800214 mX += deltaX;
215 if (mX < mMinX) mX = mMinX;
216 if (mX > mMaxX) mX = mMaxX;
217 mY += deltaY;
218 if (mY < mMinY) mY = mMinY;
219 if (mY > mMaxY) mY = mMaxY;
220 }
221
Chris Yea52ade12020-08-27 16:49:20 -0700222 void fade(Transition) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800223
Chris Yea52ade12020-08-27 16:49:20 -0700224 void unfade(Transition) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800225
Chris Yea52ade12020-08-27 16:49:20 -0700226 void setPresentation(Presentation) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800227
Chris Yea52ade12020-08-27 16:49:20 -0700228 void setSpots(const PointerCoords*, const uint32_t*, BitSet32 spotIdBits,
229 int32_t displayId) override {
Arthur Hung7c645402019-01-25 17:45:42 +0800230 std::vector<int32_t> newSpots;
231 // Add spots for fingers that are down.
232 for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
233 uint32_t id = idBits.clearFirstMarkedBit();
234 newSpots.push_back(id);
235 }
236
237 mSpotsByDisplay[displayId] = newSpots;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800238 }
239
Prabir Pradhan197e0862022-07-01 14:28:00 +0000240 void clearSpots() override { mSpotsByDisplay.clear(); }
Arthur Hung7c645402019-01-25 17:45:42 +0800241
242 std::map<int32_t, std::vector<int32_t>> mSpotsByDisplay;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800243};
244
245
246// --- FakeInputReaderPolicy ---
247
248class FakeInputReaderPolicy : public InputReaderPolicyInterface {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700249 std::mutex mLock;
250 std::condition_variable mDevicesChangedCondition;
251
Michael Wrightd02c5b62014-02-10 15:10:22 -0800252 InputReaderConfiguration mConfig;
Prabir Pradhan2853b7a2021-08-23 14:08:51 +0000253 std::shared_ptr<FakePointerController> mPointerController;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700254 std::vector<InputDeviceInfo> mInputDevices GUARDED_BY(mLock);
255 bool mInputDevicesChanged GUARDED_BY(mLock){false};
Siarhei Vishniakoud6343922018-07-06 23:33:37 +0100256 std::vector<DisplayViewport> mViewports;
Jason Gerecke489fda82012-09-07 17:19:40 -0700257 TouchAffineTransformation transform;
Prabir Pradhanda20b172022-09-26 17:01:18 +0000258 std::optional<int32_t /*deviceId*/> mStylusGestureNotified GUARDED_BY(mLock){};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800259
260protected:
Chris Yea52ade12020-08-27 16:49:20 -0700261 virtual ~FakeInputReaderPolicy() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800262
263public:
264 FakeInputReaderPolicy() {
265 }
266
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700267 void assertInputDevicesChanged() {
Prabir Pradhan1aed8582019-12-30 11:46:51 -0800268 waitForInputDevices([](bool devicesChanged) {
269 if (!devicesChanged) {
270 FAIL() << "Timed out waiting for notifyInputDevicesChanged() to be called.";
271 }
272 });
273 }
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700274
Prabir Pradhan1aed8582019-12-30 11:46:51 -0800275 void assertInputDevicesNotChanged() {
276 waitForInputDevices([](bool devicesChanged) {
277 if (devicesChanged) {
278 FAIL() << "Expected notifyInputDevicesChanged() to not be called.";
279 }
280 });
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700281 }
282
Prabir Pradhanda20b172022-09-26 17:01:18 +0000283 void assertStylusGestureNotified(int32_t deviceId) {
284 std::scoped_lock lock(mLock);
285 ASSERT_TRUE(mStylusGestureNotified);
286 ASSERT_EQ(deviceId, *mStylusGestureNotified);
287 mStylusGestureNotified.reset();
288 }
289
290 void assertStylusGestureNotNotified() {
291 std::scoped_lock lock(mLock);
292 ASSERT_FALSE(mStylusGestureNotified);
293 }
294
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700295 virtual void clearViewports() {
Siarhei Vishniakoud6343922018-07-06 23:33:37 +0100296 mViewports.clear();
Siarhei Vishniakoud6343922018-07-06 23:33:37 +0100297 mConfig.setDisplayViewports(mViewports);
Santos Cordonfa5cf462017-04-05 10:37:00 -0700298 }
299
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700300 std::optional<DisplayViewport> getDisplayViewportByUniqueId(const std::string& uniqueId) const {
301 return mConfig.getDisplayViewportByUniqueId(uniqueId);
302 }
303 std::optional<DisplayViewport> getDisplayViewportByType(ViewportType type) const {
304 return mConfig.getDisplayViewportByType(type);
305 }
306
307 std::optional<DisplayViewport> getDisplayViewportByPort(uint8_t displayPort) const {
308 return mConfig.getDisplayViewportByPort(displayPort);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700309 }
310
Prabir Pradhan5632d622021-09-06 07:57:20 -0700311 void addDisplayViewport(DisplayViewport viewport) {
312 mViewports.push_back(std::move(viewport));
313 mConfig.setDisplayViewports(mViewports);
314 }
315
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700316 void addDisplayViewport(int32_t displayId, int32_t width, int32_t height, int32_t orientation,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000317 bool isActive, const std::string& uniqueId,
Prabir Pradhan5632d622021-09-06 07:57:20 -0700318 std::optional<uint8_t> physicalPort, ViewportType type) {
319 const bool isRotated =
320 (orientation == DISPLAY_ORIENTATION_90 || orientation == DISPLAY_ORIENTATION_270);
321 DisplayViewport v;
322 v.displayId = displayId;
323 v.orientation = orientation;
324 v.logicalLeft = 0;
325 v.logicalTop = 0;
326 v.logicalRight = isRotated ? height : width;
327 v.logicalBottom = isRotated ? width : height;
328 v.physicalLeft = 0;
329 v.physicalTop = 0;
330 v.physicalRight = isRotated ? height : width;
331 v.physicalBottom = isRotated ? width : height;
332 v.deviceWidth = isRotated ? height : width;
333 v.deviceHeight = isRotated ? width : height;
334 v.isActive = isActive;
335 v.uniqueId = uniqueId;
336 v.physicalPort = physicalPort;
337 v.type = type;
338
339 addDisplayViewport(v);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800340 }
341
Arthur Hung6cd19a42019-08-30 19:04:12 +0800342 bool updateViewport(const DisplayViewport& viewport) {
343 size_t count = mViewports.size();
344 for (size_t i = 0; i < count; i++) {
345 const DisplayViewport& currentViewport = mViewports[i];
346 if (currentViewport.displayId == viewport.displayId) {
347 mViewports[i] = viewport;
348 mConfig.setDisplayViewports(mViewports);
349 return true;
350 }
351 }
352 // no viewport found.
353 return false;
354 }
355
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100356 void addExcludedDeviceName(const std::string& deviceName) {
357 mConfig.excludedDeviceNames.push_back(deviceName);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800358 }
359
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700360 void addInputPortAssociation(const std::string& inputPort, uint8_t displayPort) {
361 mConfig.portAssociations.insert({inputPort, displayPort});
362 }
363
Christine Franks1ba71cc2021-04-07 14:37:42 -0700364 void addInputUniqueIdAssociation(const std::string& inputUniqueId,
365 const std::string& displayUniqueId) {
366 mConfig.uniqueIdAssociations.insert({inputUniqueId, displayUniqueId});
367 }
368
Siarhei Vishniakouc6f61192019-07-23 18:12:31 +0000369 void addDisabledDevice(int32_t deviceId) { mConfig.disabledDevices.insert(deviceId); }
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700370
Siarhei Vishniakouc6f61192019-07-23 18:12:31 +0000371 void removeDisabledDevice(int32_t deviceId) { mConfig.disabledDevices.erase(deviceId); }
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700372
Prabir Pradhan2853b7a2021-08-23 14:08:51 +0000373 void setPointerController(std::shared_ptr<FakePointerController> controller) {
374 mPointerController = std::move(controller);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800375 }
376
377 const InputReaderConfiguration* getReaderConfiguration() const {
378 return &mConfig;
379 }
380
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800381 const std::vector<InputDeviceInfo>& getInputDevices() const {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800382 return mInputDevices;
383 }
384
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100385 TouchAffineTransformation getTouchAffineTransformation(const std::string& inputDeviceDescriptor,
Jason Gerecke71b16e82014-03-10 09:47:59 -0700386 int32_t surfaceRotation) {
Jason Gerecke489fda82012-09-07 17:19:40 -0700387 return transform;
388 }
389
390 void setTouchAffineTransformation(const TouchAffineTransformation t) {
391 transform = t;
Jason Gerecke12d6baa2014-01-27 18:34:20 -0800392 }
393
Prabir Pradhan5cc1a692021-08-06 14:01:18 +0000394 PointerCaptureRequest setPointerCapture(bool enabled) {
395 mConfig.pointerCaptureRequest = {enabled, mNextPointerCaptureSequenceNumber++};
396 return mConfig.pointerCaptureRequest;
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -0800397 }
398
Arthur Hung7c645402019-01-25 17:45:42 +0800399 void setShowTouches(bool enabled) {
400 mConfig.showTouches = enabled;
401 }
402
Garfield Tan888a6a42020-01-09 11:39:16 -0800403 void setDefaultPointerDisplayId(int32_t pointerDisplayId) {
404 mConfig.defaultPointerDisplayId = pointerDisplayId;
405 }
406
HQ Liue6983c72022-04-19 22:14:56 +0000407 void setPointerGestureEnabled(bool enabled) { mConfig.pointerGesturesEnabled = enabled; }
408
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -0800409 float getPointerGestureMovementSpeedRatio() { return mConfig.pointerGestureMovementSpeedRatio; }
410
HQ Liue6983c72022-04-19 22:14:56 +0000411 float getPointerGestureZoomSpeedRatio() { return mConfig.pointerGestureZoomSpeedRatio; }
412
Prabir Pradhanf99d6e72022-04-21 15:28:35 +0000413 void setVelocityControlParams(const VelocityControlParameters& params) {
414 mConfig.pointerVelocityControlParameters = params;
415 mConfig.wheelVelocityControlParameters = params;
416 }
417
Michael Wrightd02c5b62014-02-10 15:10:22 -0800418private:
Prabir Pradhan5cc1a692021-08-06 14:01:18 +0000419 uint32_t mNextPointerCaptureSequenceNumber = 0;
420
Chris Yea52ade12020-08-27 16:49:20 -0700421 void getReaderConfiguration(InputReaderConfiguration* outConfig) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800422 *outConfig = mConfig;
423 }
424
Prabir Pradhan2853b7a2021-08-23 14:08:51 +0000425 std::shared_ptr<PointerControllerInterface> obtainPointerController(
426 int32_t /*deviceId*/) override {
427 return mPointerController;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800428 }
429
Chris Yea52ade12020-08-27 16:49:20 -0700430 void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700431 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800432 mInputDevices = inputDevices;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700433 mInputDevicesChanged = true;
434 mDevicesChangedCondition.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800435 }
436
Chris Yea52ade12020-08-27 16:49:20 -0700437 std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
438 const InputDeviceIdentifier&) override {
Yi Kong9b14ac62018-07-17 13:48:38 -0700439 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800440 }
441
Chris Yea52ade12020-08-27 16:49:20 -0700442 std::string getDeviceAlias(const InputDeviceIdentifier&) override { return ""; }
Prabir Pradhan1aed8582019-12-30 11:46:51 -0800443
444 void waitForInputDevices(std::function<void(bool)> processDevicesChanged) {
445 std::unique_lock<std::mutex> lock(mLock);
446 base::ScopedLockAssertion assumeLocked(mLock);
447
448 const bool devicesChanged =
449 mDevicesChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
450 return mInputDevicesChanged;
451 });
452 ASSERT_NO_FATAL_FAILURE(processDevicesChanged(devicesChanged));
453 mInputDevicesChanged = false;
454 }
Prabir Pradhanda20b172022-09-26 17:01:18 +0000455
456 void notifyStylusGestureStarted(int32_t deviceId, nsecs_t eventTime) override {
457 std::scoped_lock<std::mutex> lock(mLock);
458 mStylusGestureNotified = deviceId;
459 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800460};
461
Michael Wrightd02c5b62014-02-10 15:10:22 -0800462// --- FakeEventHub ---
463
464class FakeEventHub : public EventHubInterface {
465 struct KeyInfo {
466 int32_t keyCode;
467 uint32_t flags;
468 };
469
Chris Yef59a2f42020-10-16 12:55:26 -0700470 struct SensorInfo {
471 InputDeviceSensorType sensorType;
472 int32_t sensorDataIndex;
473 };
474
Michael Wrightd02c5b62014-02-10 15:10:22 -0800475 struct Device {
476 InputDeviceIdentifier identifier;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700477 ftl::Flags<InputDeviceClass> classes;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800478 PropertyMap configuration;
479 KeyedVector<int, RawAbsoluteAxisInfo> absoluteAxes;
480 KeyedVector<int, bool> relativeAxes;
481 KeyedVector<int32_t, int32_t> keyCodeStates;
482 KeyedVector<int32_t, int32_t> scanCodeStates;
483 KeyedVector<int32_t, int32_t> switchStates;
484 KeyedVector<int32_t, int32_t> absoluteAxisValue;
485 KeyedVector<int32_t, KeyInfo> keysByScanCode;
486 KeyedVector<int32_t, KeyInfo> keysByUsageCode;
487 KeyedVector<int32_t, bool> leds;
Philip Junker4af3b3d2021-12-14 10:36:55 +0100488 // fake mapping which would normally come from keyCharacterMap
489 std::unordered_map<int32_t, int32_t> keyCodeMapping;
Chris Yef59a2f42020-10-16 12:55:26 -0700490 std::unordered_map<int32_t, SensorInfo> sensorsByAbsCode;
491 BitArray<MSC_MAX> mscBitmask;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800492 std::vector<VirtualKeyDefinition> virtualKeys;
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700493 bool enabled;
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +0000494 InputDeviceCountryCode countryCode;
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700495
496 status_t enable() {
497 enabled = true;
498 return OK;
499 }
500
501 status_t disable() {
502 enabled = false;
503 return OK;
504 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800505
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700506 explicit Device(ftl::Flags<InputDeviceClass> classes) : classes(classes), enabled(true) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800507 };
508
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700509 std::mutex mLock;
510 std::condition_variable mEventsCondition;
511
Michael Wrightd02c5b62014-02-10 15:10:22 -0800512 KeyedVector<int32_t, Device*> mDevices;
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100513 std::vector<std::string> mExcludedDevices;
Siarhei Vishniakou370039c2021-02-04 22:09:01 +0000514 std::vector<RawEvent> mEvents GUARDED_BY(mLock);
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -0600515 std::unordered_map<int32_t /*deviceId*/, std::vector<TouchVideoFrame>> mVideoFrames;
Chris Ye87143712020-11-10 05:05:58 +0000516 std::vector<int32_t> mVibrators = {0, 1};
Chris Ye3fdbfef2021-01-06 18:45:18 -0800517 std::unordered_map<int32_t, RawLightInfo> mRawLightInfos;
518 // Simulates a device light brightness, from light id to light brightness.
519 std::unordered_map<int32_t /* lightId */, int32_t /* brightness*/> mLightBrightness;
520 // Simulates a device light intensities, from light id to light intensities map.
521 std::unordered_map<int32_t /* lightId */, std::unordered_map<LightColor, int32_t>>
522 mLightIntensities;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800523
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -0700524public:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800525 virtual ~FakeEventHub() {
526 for (size_t i = 0; i < mDevices.size(); i++) {
527 delete mDevices.valueAt(i);
528 }
529 }
530
Michael Wrightd02c5b62014-02-10 15:10:22 -0800531 FakeEventHub() { }
532
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700533 void addDevice(int32_t deviceId, const std::string& name,
534 ftl::Flags<InputDeviceClass> classes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800535 Device* device = new Device(classes);
536 device->identifier.name = name;
537 mDevices.add(deviceId, device);
538
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000539 enqueueEvent(ARBITRARY_TIME, READ_TIME, deviceId, EventHubInterface::DEVICE_ADDED, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800540 }
541
542 void removeDevice(int32_t deviceId) {
543 delete mDevices.valueFor(deviceId);
544 mDevices.removeItem(deviceId);
545
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000546 enqueueEvent(ARBITRARY_TIME, READ_TIME, deviceId, EventHubInterface::DEVICE_REMOVED, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800547 }
548
Prabir Pradhanae4ff282022-08-23 16:21:39 +0000549 bool isDeviceEnabled(int32_t deviceId) const override {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700550 Device* device = getDevice(deviceId);
Yi Kong9b14ac62018-07-17 13:48:38 -0700551 if (device == nullptr) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700552 ALOGE("Incorrect device id=%" PRId32 " provided to %s", deviceId, __func__);
553 return false;
554 }
555 return device->enabled;
556 }
557
Prabir Pradhanae4ff282022-08-23 16:21:39 +0000558 status_t enableDevice(int32_t deviceId) override {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700559 status_t result;
560 Device* device = getDevice(deviceId);
Yi Kong9b14ac62018-07-17 13:48:38 -0700561 if (device == nullptr) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700562 ALOGE("Incorrect device id=%" PRId32 " provided to %s", deviceId, __func__);
563 return BAD_VALUE;
564 }
565 if (device->enabled) {
566 ALOGW("Duplicate call to %s, device %" PRId32 " already enabled", __func__, deviceId);
567 return OK;
568 }
569 result = device->enable();
570 return result;
571 }
572
Prabir Pradhanae4ff282022-08-23 16:21:39 +0000573 status_t disableDevice(int32_t deviceId) override {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700574 Device* device = getDevice(deviceId);
Yi Kong9b14ac62018-07-17 13:48:38 -0700575 if (device == nullptr) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700576 ALOGE("Incorrect device id=%" PRId32 " provided to %s", deviceId, __func__);
577 return BAD_VALUE;
578 }
579 if (!device->enabled) {
580 ALOGW("Duplicate call to %s, device %" PRId32 " already disabled", __func__, deviceId);
581 return OK;
582 }
583 return device->disable();
584 }
585
Michael Wrightd02c5b62014-02-10 15:10:22 -0800586 void finishDeviceScan() {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000587 enqueueEvent(ARBITRARY_TIME, READ_TIME, 0, EventHubInterface::FINISHED_DEVICE_SCAN, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800588 }
589
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -0700590 void addConfigurationProperty(int32_t deviceId, const char* key, const char* value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800591 Device* device = getDevice(deviceId);
592 device->configuration.addProperty(key, value);
593 }
594
595 void addConfigurationMap(int32_t deviceId, const PropertyMap* configuration) {
596 Device* device = getDevice(deviceId);
597 device->configuration.addAll(configuration);
598 }
599
600 void addAbsoluteAxis(int32_t deviceId, int axis,
601 int32_t minValue, int32_t maxValue, int flat, int fuzz, int resolution = 0) {
602 Device* device = getDevice(deviceId);
603
604 RawAbsoluteAxisInfo info;
605 info.valid = true;
606 info.minValue = minValue;
607 info.maxValue = maxValue;
608 info.flat = flat;
609 info.fuzz = fuzz;
610 info.resolution = resolution;
611 device->absoluteAxes.add(axis, info);
612 }
613
614 void addRelativeAxis(int32_t deviceId, int32_t axis) {
615 Device* device = getDevice(deviceId);
616 device->relativeAxes.add(axis, true);
617 }
618
619 void setKeyCodeState(int32_t deviceId, int32_t keyCode, int32_t state) {
620 Device* device = getDevice(deviceId);
621 device->keyCodeStates.replaceValueFor(keyCode, state);
622 }
623
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +0000624 void setCountryCode(int32_t deviceId, InputDeviceCountryCode countryCode) {
625 Device* device = getDevice(deviceId);
626 device->countryCode = countryCode;
627 }
628
Michael Wrightd02c5b62014-02-10 15:10:22 -0800629 void setScanCodeState(int32_t deviceId, int32_t scanCode, int32_t state) {
630 Device* device = getDevice(deviceId);
631 device->scanCodeStates.replaceValueFor(scanCode, state);
632 }
633
634 void setSwitchState(int32_t deviceId, int32_t switchCode, int32_t state) {
635 Device* device = getDevice(deviceId);
636 device->switchStates.replaceValueFor(switchCode, state);
637 }
638
639 void setAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t value) {
640 Device* device = getDevice(deviceId);
641 device->absoluteAxisValue.replaceValueFor(axis, value);
642 }
643
644 void addKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
645 int32_t keyCode, uint32_t flags) {
646 Device* device = getDevice(deviceId);
647 KeyInfo info;
648 info.keyCode = keyCode;
649 info.flags = flags;
650 if (scanCode) {
651 device->keysByScanCode.add(scanCode, info);
652 }
653 if (usageCode) {
654 device->keysByUsageCode.add(usageCode, info);
655 }
656 }
657
Philip Junker4af3b3d2021-12-14 10:36:55 +0100658 void addKeyCodeMapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) {
659 Device* device = getDevice(deviceId);
660 device->keyCodeMapping.insert_or_assign(fromKeyCode, toKeyCode);
661 }
662
Michael Wrightd02c5b62014-02-10 15:10:22 -0800663 void addLed(int32_t deviceId, int32_t led, bool initialState) {
664 Device* device = getDevice(deviceId);
665 device->leds.add(led, initialState);
666 }
667
Chris Yef59a2f42020-10-16 12:55:26 -0700668 void addSensorAxis(int32_t deviceId, int32_t absCode, InputDeviceSensorType sensorType,
669 int32_t sensorDataIndex) {
670 Device* device = getDevice(deviceId);
671 SensorInfo info;
672 info.sensorType = sensorType;
673 info.sensorDataIndex = sensorDataIndex;
674 device->sensorsByAbsCode.emplace(absCode, info);
675 }
676
677 void setMscEvent(int32_t deviceId, int32_t mscEvent) {
678 Device* device = getDevice(deviceId);
679 typename BitArray<MSC_MAX>::Buffer buffer;
680 buffer[mscEvent / 32] = 1 << mscEvent % 32;
681 device->mscBitmask.loadFromBuffer(buffer);
682 }
683
Chris Ye3fdbfef2021-01-06 18:45:18 -0800684 void addRawLightInfo(int32_t rawId, RawLightInfo&& info) {
685 mRawLightInfos.emplace(rawId, std::move(info));
686 }
687
688 void fakeLightBrightness(int32_t rawId, int32_t brightness) {
689 mLightBrightness.emplace(rawId, brightness);
690 }
691
692 void fakeLightIntensities(int32_t rawId,
693 const std::unordered_map<LightColor, int32_t> intensities) {
694 mLightIntensities.emplace(rawId, std::move(intensities));
695 }
696
Michael Wrightd02c5b62014-02-10 15:10:22 -0800697 bool getLedState(int32_t deviceId, int32_t led) {
698 Device* device = getDevice(deviceId);
699 return device->leds.valueFor(led);
700 }
701
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100702 std::vector<std::string>& getExcludedDevices() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800703 return mExcludedDevices;
704 }
705
706 void addVirtualKeyDefinition(int32_t deviceId, const VirtualKeyDefinition& definition) {
707 Device* device = getDevice(deviceId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800708 device->virtualKeys.push_back(definition);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800709 }
710
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000711 void enqueueEvent(nsecs_t when, nsecs_t readTime, int32_t deviceId, int32_t type, int32_t code,
712 int32_t value) {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700713 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800714 RawEvent event;
715 event.when = when;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000716 event.readTime = readTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800717 event.deviceId = deviceId;
718 event.type = type;
719 event.code = code;
720 event.value = value;
721 mEvents.push_back(event);
722
723 if (type == EV_ABS) {
724 setAbsoluteAxisValue(deviceId, code, value);
725 }
726 }
727
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -0600728 void setVideoFrames(std::unordered_map<int32_t /*deviceId*/,
729 std::vector<TouchVideoFrame>> videoFrames) {
730 mVideoFrames = std::move(videoFrames);
731 }
732
Michael Wrightd02c5b62014-02-10 15:10:22 -0800733 void assertQueueIsEmpty() {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700734 std::unique_lock<std::mutex> lock(mLock);
735 base::ScopedLockAssertion assumeLocked(mLock);
736 const bool queueIsEmpty =
737 mEventsCondition.wait_for(lock, WAIT_TIMEOUT,
738 [this]() REQUIRES(mLock) { return mEvents.size() == 0; });
739 if (!queueIsEmpty) {
740 FAIL() << "Timed out waiting for EventHub queue to be emptied.";
741 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800742 }
743
744private:
745 Device* getDevice(int32_t deviceId) const {
746 ssize_t index = mDevices.indexOfKey(deviceId);
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100747 return index >= 0 ? mDevices.valueAt(index) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800748 }
749
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700750 ftl::Flags<InputDeviceClass> getDeviceClasses(int32_t deviceId) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800751 Device* device = getDevice(deviceId);
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700752 return device ? device->classes : ftl::Flags<InputDeviceClass>(0);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800753 }
754
Chris Yea52ade12020-08-27 16:49:20 -0700755 InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800756 Device* device = getDevice(deviceId);
757 return device ? device->identifier : InputDeviceIdentifier();
758 }
759
Chris Yea52ade12020-08-27 16:49:20 -0700760 int32_t getDeviceControllerNumber(int32_t) const override { return 0; }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800761
Chris Yea52ade12020-08-27 16:49:20 -0700762 void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800763 Device* device = getDevice(deviceId);
764 if (device) {
765 *outConfiguration = device->configuration;
766 }
767 }
768
Chris Yea52ade12020-08-27 16:49:20 -0700769 status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
770 RawAbsoluteAxisInfo* outAxisInfo) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800771 Device* device = getDevice(deviceId);
Siarhei Vishniakou21e96e62022-10-27 10:23:37 -0700772 if (device) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800773 ssize_t index = device->absoluteAxes.indexOfKey(axis);
774 if (index >= 0) {
775 *outAxisInfo = device->absoluteAxes.valueAt(index);
776 return OK;
777 }
778 }
779 outAxisInfo->clear();
780 return -1;
781 }
782
Chris Yea52ade12020-08-27 16:49:20 -0700783 bool hasRelativeAxis(int32_t deviceId, int axis) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800784 Device* device = getDevice(deviceId);
785 if (device) {
786 return device->relativeAxes.indexOfKey(axis) >= 0;
787 }
788 return false;
789 }
790
Chris Yea52ade12020-08-27 16:49:20 -0700791 bool hasInputProperty(int32_t, int) const override { return false; }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800792
Chris Yef59a2f42020-10-16 12:55:26 -0700793 bool hasMscEvent(int32_t deviceId, int mscEvent) const override final {
794 Device* device = getDevice(deviceId);
795 if (device) {
796 return mscEvent >= 0 && mscEvent <= MSC_MAX ? device->mscBitmask.test(mscEvent) : false;
797 }
798 return false;
799 }
800
Chris Yea52ade12020-08-27 16:49:20 -0700801 status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t metaState,
802 int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800803 Device* device = getDevice(deviceId);
804 if (device) {
805 const KeyInfo* key = getKey(device, scanCode, usageCode);
806 if (key) {
807 if (outKeycode) {
808 *outKeycode = key->keyCode;
809 }
810 if (outFlags) {
811 *outFlags = key->flags;
812 }
Dmitry Torokhov0faaa0b2015-09-24 13:13:55 -0700813 if (outMetaState) {
814 *outMetaState = metaState;
815 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800816 return OK;
817 }
818 }
819 return NAME_NOT_FOUND;
820 }
821
822 const KeyInfo* getKey(Device* device, int32_t scanCode, int32_t usageCode) const {
823 if (usageCode) {
824 ssize_t index = device->keysByUsageCode.indexOfKey(usageCode);
825 if (index >= 0) {
826 return &device->keysByUsageCode.valueAt(index);
827 }
828 }
829 if (scanCode) {
830 ssize_t index = device->keysByScanCode.indexOfKey(scanCode);
831 if (index >= 0) {
832 return &device->keysByScanCode.valueAt(index);
833 }
834 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700835 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800836 }
837
Chris Yea52ade12020-08-27 16:49:20 -0700838 status_t mapAxis(int32_t, int32_t, AxisInfo*) const override { return NAME_NOT_FOUND; }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800839
Prabir Pradhanae4ff282022-08-23 16:21:39 +0000840 base::Result<std::pair<InputDeviceSensorType, int32_t>> mapSensor(
841 int32_t deviceId, int32_t absCode) const override {
Chris Yef59a2f42020-10-16 12:55:26 -0700842 Device* device = getDevice(deviceId);
843 if (!device) {
844 return Errorf("Sensor device not found.");
845 }
846 auto it = device->sensorsByAbsCode.find(absCode);
847 if (it == device->sensorsByAbsCode.end()) {
848 return Errorf("Sensor map not found.");
849 }
850 const SensorInfo& info = it->second;
851 return std::make_pair(info.sensorType, info.sensorDataIndex);
852 }
853
Chris Yea52ade12020-08-27 16:49:20 -0700854 void setExcludedDevices(const std::vector<std::string>& devices) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800855 mExcludedDevices = devices;
856 }
857
Siarhei Vishniakou7b3ea0b2022-09-16 14:23:20 -0700858 std::vector<RawEvent> getEvents(int) override {
Siarhei Vishniakou370039c2021-02-04 22:09:01 +0000859 std::scoped_lock lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800860
Siarhei Vishniakou7b3ea0b2022-09-16 14:23:20 -0700861 std::vector<RawEvent> buffer;
862 std::swap(buffer, mEvents);
Siarhei Vishniakou370039c2021-02-04 22:09:01 +0000863
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700864 mEventsCondition.notify_all();
Siarhei Vishniakou7b3ea0b2022-09-16 14:23:20 -0700865 return buffer;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800866 }
867
Chris Yea52ade12020-08-27 16:49:20 -0700868 std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) override {
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -0600869 auto it = mVideoFrames.find(deviceId);
870 if (it != mVideoFrames.end()) {
871 std::vector<TouchVideoFrame> frames = std::move(it->second);
872 mVideoFrames.erase(deviceId);
873 return frames;
874 }
Siarhei Vishniakouadd89292018-12-13 19:23:36 -0800875 return {};
876 }
877
Chris Yea52ade12020-08-27 16:49:20 -0700878 int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800879 Device* device = getDevice(deviceId);
880 if (device) {
881 ssize_t index = device->scanCodeStates.indexOfKey(scanCode);
882 if (index >= 0) {
883 return device->scanCodeStates.valueAt(index);
884 }
885 }
886 return AKEY_STATE_UNKNOWN;
887 }
888
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +0000889 InputDeviceCountryCode getCountryCode(int32_t deviceId) const override {
890 Device* device = getDevice(deviceId);
891 if (device) {
892 return device->countryCode;
893 }
894 return InputDeviceCountryCode::INVALID;
895 }
896
Chris Yea52ade12020-08-27 16:49:20 -0700897 int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800898 Device* device = getDevice(deviceId);
899 if (device) {
900 ssize_t index = device->keyCodeStates.indexOfKey(keyCode);
901 if (index >= 0) {
902 return device->keyCodeStates.valueAt(index);
903 }
904 }
905 return AKEY_STATE_UNKNOWN;
906 }
907
Chris Yea52ade12020-08-27 16:49:20 -0700908 int32_t getSwitchState(int32_t deviceId, int32_t sw) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800909 Device* device = getDevice(deviceId);
910 if (device) {
911 ssize_t index = device->switchStates.indexOfKey(sw);
912 if (index >= 0) {
913 return device->switchStates.valueAt(index);
914 }
915 }
916 return AKEY_STATE_UNKNOWN;
917 }
918
Chris Yea52ade12020-08-27 16:49:20 -0700919 status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
920 int32_t* outValue) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800921 Device* device = getDevice(deviceId);
922 if (device) {
923 ssize_t index = device->absoluteAxisValue.indexOfKey(axis);
924 if (index >= 0) {
925 *outValue = device->absoluteAxisValue.valueAt(index);
926 return OK;
927 }
928 }
929 *outValue = 0;
930 return -1;
931 }
932
Philip Junker4af3b3d2021-12-14 10:36:55 +0100933 int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const override {
934 Device* device = getDevice(deviceId);
935 if (!device) {
936 return AKEYCODE_UNKNOWN;
937 }
938 auto it = device->keyCodeMapping.find(locationKeyCode);
939 return it != device->keyCodeMapping.end() ? it->second : locationKeyCode;
940 }
941
Chris Yea52ade12020-08-27 16:49:20 -0700942 // Return true if the device has non-empty key layout.
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700943 bool markSupportedKeyCodes(int32_t deviceId, const std::vector<int32_t>& keyCodes,
Chris Yea52ade12020-08-27 16:49:20 -0700944 uint8_t* outFlags) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800945 bool result = false;
946 Device* device = getDevice(deviceId);
947 if (device) {
Chris Yea52ade12020-08-27 16:49:20 -0700948 result = device->keysByScanCode.size() > 0 || device->keysByUsageCode.size() > 0;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700949 for (size_t i = 0; i < keyCodes.size(); i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800950 for (size_t j = 0; j < device->keysByScanCode.size(); j++) {
951 if (keyCodes[i] == device->keysByScanCode.valueAt(j).keyCode) {
952 outFlags[i] = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800953 }
954 }
955 for (size_t j = 0; j < device->keysByUsageCode.size(); j++) {
956 if (keyCodes[i] == device->keysByUsageCode.valueAt(j).keyCode) {
957 outFlags[i] = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800958 }
959 }
960 }
961 }
962 return result;
963 }
964
Chris Yea52ade12020-08-27 16:49:20 -0700965 bool hasScanCode(int32_t deviceId, int32_t scanCode) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800966 Device* device = getDevice(deviceId);
967 if (device) {
968 ssize_t index = device->keysByScanCode.indexOfKey(scanCode);
969 return index >= 0;
970 }
971 return false;
972 }
973
Arthur Hungcb40a002021-08-03 14:31:01 +0000974 bool hasKeyCode(int32_t deviceId, int32_t keyCode) const override {
975 Device* device = getDevice(deviceId);
976 if (!device) {
977 return false;
978 }
979 for (size_t i = 0; i < device->keysByScanCode.size(); i++) {
980 if (keyCode == device->keysByScanCode.valueAt(i).keyCode) {
981 return true;
982 }
983 }
984 for (size_t j = 0; j < device->keysByUsageCode.size(); j++) {
985 if (keyCode == device->keysByUsageCode.valueAt(j).keyCode) {
986 return true;
987 }
988 }
989 return false;
990 }
991
Chris Yea52ade12020-08-27 16:49:20 -0700992 bool hasLed(int32_t deviceId, int32_t led) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800993 Device* device = getDevice(deviceId);
994 return device && device->leds.indexOfKey(led) >= 0;
995 }
996
Chris Yea52ade12020-08-27 16:49:20 -0700997 void setLedState(int32_t deviceId, int32_t led, bool on) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800998 Device* device = getDevice(deviceId);
999 if (device) {
1000 ssize_t index = device->leds.indexOfKey(led);
1001 if (index >= 0) {
1002 device->leds.replaceValueAt(led, on);
1003 } else {
1004 ADD_FAILURE()
1005 << "Attempted to set the state of an LED that the EventHub declared "
1006 "was not present. led=" << led;
1007 }
1008 }
1009 }
1010
Chris Yea52ade12020-08-27 16:49:20 -07001011 void getVirtualKeyDefinitions(
1012 int32_t deviceId, std::vector<VirtualKeyDefinition>& outVirtualKeys) const override {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001013 outVirtualKeys.clear();
1014
1015 Device* device = getDevice(deviceId);
1016 if (device) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001017 outVirtualKeys = device->virtualKeys;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001018 }
1019 }
1020
Chris Yea52ade12020-08-27 16:49:20 -07001021 const std::shared_ptr<KeyCharacterMap> getKeyCharacterMap(int32_t) const override {
Yi Kong9b14ac62018-07-17 13:48:38 -07001022 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001023 }
1024
Chris Yea52ade12020-08-27 16:49:20 -07001025 bool setKeyboardLayoutOverlay(int32_t, std::shared_ptr<KeyCharacterMap>) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001026 return false;
1027 }
1028
Chris Yea52ade12020-08-27 16:49:20 -07001029 void vibrate(int32_t, const VibrationElement&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001030
Chris Yea52ade12020-08-27 16:49:20 -07001031 void cancelVibrate(int32_t) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001032
Prabir Pradhanae4ff282022-08-23 16:21:39 +00001033 std::vector<int32_t> getVibratorIds(int32_t deviceId) const override { return mVibrators; };
Chris Ye87143712020-11-10 05:05:58 +00001034
Chris Yee2b1e5c2021-03-10 22:45:12 -08001035 std::optional<int32_t> getBatteryCapacity(int32_t, int32_t) const override {
1036 return BATTERY_CAPACITY;
1037 }
Kim Low03ea0352020-11-06 12:45:07 -08001038
Chris Yee2b1e5c2021-03-10 22:45:12 -08001039 std::optional<int32_t> getBatteryStatus(int32_t, int32_t) const override {
1040 return BATTERY_STATUS;
1041 }
1042
Andy Chenf9f1a022022-08-29 20:07:10 -04001043 std::vector<int32_t> getRawBatteryIds(int32_t deviceId) const override {
1044 return {DEFAULT_BATTERY};
1045 }
Chris Yee2b1e5c2021-03-10 22:45:12 -08001046
Prabir Pradhanae4ff282022-08-23 16:21:39 +00001047 std::optional<RawBatteryInfo> getRawBatteryInfo(int32_t deviceId,
1048 int32_t batteryId) const override {
Prabir Pradhane287ecd2022-09-07 21:18:05 +00001049 if (batteryId != DEFAULT_BATTERY) return {};
1050 static const auto BATTERY_INFO = RawBatteryInfo{.id = DEFAULT_BATTERY,
1051 .name = "default battery",
1052 .flags = InputBatteryClass::CAPACITY,
1053 .path = BATTERY_DEVPATH};
1054 return BATTERY_INFO;
Chris Yee2b1e5c2021-03-10 22:45:12 -08001055 }
Kim Low03ea0352020-11-06 12:45:07 -08001056
Prabir Pradhanae4ff282022-08-23 16:21:39 +00001057 std::vector<int32_t> getRawLightIds(int32_t deviceId) const override {
Chris Ye3fdbfef2021-01-06 18:45:18 -08001058 std::vector<int32_t> ids;
1059 for (const auto& [rawId, info] : mRawLightInfos) {
1060 ids.push_back(rawId);
1061 }
1062 return ids;
1063 }
1064
Prabir Pradhanae4ff282022-08-23 16:21:39 +00001065 std::optional<RawLightInfo> getRawLightInfo(int32_t deviceId, int32_t lightId) const override {
Chris Ye3fdbfef2021-01-06 18:45:18 -08001066 auto it = mRawLightInfos.find(lightId);
1067 if (it == mRawLightInfos.end()) {
1068 return std::nullopt;
1069 }
1070 return it->second;
1071 }
1072
1073 void setLightBrightness(int32_t deviceId, int32_t lightId, int32_t brightness) override {
1074 mLightBrightness.emplace(lightId, brightness);
1075 }
1076
1077 void setLightIntensities(int32_t deviceId, int32_t lightId,
1078 std::unordered_map<LightColor, int32_t> intensities) override {
1079 mLightIntensities.emplace(lightId, intensities);
1080 };
1081
Prabir Pradhanae4ff282022-08-23 16:21:39 +00001082 std::optional<int32_t> getLightBrightness(int32_t deviceId, int32_t lightId) const override {
Chris Ye3fdbfef2021-01-06 18:45:18 -08001083 auto lightIt = mLightBrightness.find(lightId);
1084 if (lightIt == mLightBrightness.end()) {
1085 return std::nullopt;
1086 }
1087 return lightIt->second;
1088 }
1089
1090 std::optional<std::unordered_map<LightColor, int32_t>> getLightIntensities(
Prabir Pradhanae4ff282022-08-23 16:21:39 +00001091 int32_t deviceId, int32_t lightId) const override {
Chris Ye3fdbfef2021-01-06 18:45:18 -08001092 auto lightIt = mLightIntensities.find(lightId);
1093 if (lightIt == mLightIntensities.end()) {
1094 return std::nullopt;
1095 }
1096 return lightIt->second;
1097 };
1098
Prabir Pradhanae4ff282022-08-23 16:21:39 +00001099 void dump(std::string&) const override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001100
Prabir Pradhanae4ff282022-08-23 16:21:39 +00001101 void monitor() const override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001102
Chris Yea52ade12020-08-27 16:49:20 -07001103 void requestReopenDevices() override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001104
Chris Yea52ade12020-08-27 16:49:20 -07001105 void wake() override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001106};
1107
Michael Wrightd02c5b62014-02-10 15:10:22 -08001108// --- FakeInputMapper ---
1109
1110class FakeInputMapper : public InputMapper {
1111 uint32_t mSources;
1112 int32_t mKeyboardType;
1113 int32_t mMetaState;
1114 KeyedVector<int32_t, int32_t> mKeyCodeStates;
1115 KeyedVector<int32_t, int32_t> mScanCodeStates;
1116 KeyedVector<int32_t, int32_t> mSwitchStates;
Philip Junker4af3b3d2021-12-14 10:36:55 +01001117 // fake mapping which would normally come from keyCharacterMap
1118 std::unordered_map<int32_t, int32_t> mKeyCodeMapping;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001119 std::vector<int32_t> mSupportedKeyCodes;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001120
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001121 std::mutex mLock;
1122 std::condition_variable mStateChangedCondition;
1123 bool mConfigureWasCalled GUARDED_BY(mLock);
1124 bool mResetWasCalled GUARDED_BY(mLock);
1125 bool mProcessWasCalled GUARDED_BY(mLock);
1126 RawEvent mLastEvent GUARDED_BY(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001127
Arthur Hungc23540e2018-11-29 20:42:11 +08001128 std::optional<DisplayViewport> mViewport;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001129public:
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -08001130 FakeInputMapper(InputDeviceContext& deviceContext, uint32_t sources)
1131 : InputMapper(deviceContext),
1132 mSources(sources),
1133 mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001134 mMetaState(0),
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -08001135 mConfigureWasCalled(false),
1136 mResetWasCalled(false),
1137 mProcessWasCalled(false) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001138
Chris Yea52ade12020-08-27 16:49:20 -07001139 virtual ~FakeInputMapper() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001140
1141 void setKeyboardType(int32_t keyboardType) {
1142 mKeyboardType = keyboardType;
1143 }
1144
1145 void setMetaState(int32_t metaState) {
1146 mMetaState = metaState;
1147 }
1148
1149 void assertConfigureWasCalled() {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001150 std::unique_lock<std::mutex> lock(mLock);
1151 base::ScopedLockAssertion assumeLocked(mLock);
1152 const bool configureCalled =
1153 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
1154 return mConfigureWasCalled;
1155 });
1156 if (!configureCalled) {
1157 FAIL() << "Expected configure() to have been called.";
1158 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001159 mConfigureWasCalled = false;
1160 }
1161
1162 void assertResetWasCalled() {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001163 std::unique_lock<std::mutex> lock(mLock);
1164 base::ScopedLockAssertion assumeLocked(mLock);
1165 const bool resetCalled =
1166 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
1167 return mResetWasCalled;
1168 });
1169 if (!resetCalled) {
1170 FAIL() << "Expected reset() to have been called.";
1171 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001172 mResetWasCalled = false;
1173 }
1174
Yi Kong9b14ac62018-07-17 13:48:38 -07001175 void assertProcessWasCalled(RawEvent* outLastEvent = nullptr) {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001176 std::unique_lock<std::mutex> lock(mLock);
1177 base::ScopedLockAssertion assumeLocked(mLock);
1178 const bool processCalled =
1179 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
1180 return mProcessWasCalled;
1181 });
1182 if (!processCalled) {
1183 FAIL() << "Expected process() to have been called.";
1184 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001185 if (outLastEvent) {
1186 *outLastEvent = mLastEvent;
1187 }
1188 mProcessWasCalled = false;
1189 }
1190
1191 void setKeyCodeState(int32_t keyCode, int32_t state) {
1192 mKeyCodeStates.replaceValueFor(keyCode, state);
1193 }
1194
1195 void setScanCodeState(int32_t scanCode, int32_t state) {
1196 mScanCodeStates.replaceValueFor(scanCode, state);
1197 }
1198
1199 void setSwitchState(int32_t switchCode, int32_t state) {
1200 mSwitchStates.replaceValueFor(switchCode, state);
1201 }
1202
1203 void addSupportedKeyCode(int32_t keyCode) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001204 mSupportedKeyCodes.push_back(keyCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001205 }
1206
Philip Junker4af3b3d2021-12-14 10:36:55 +01001207 void addKeyCodeMapping(int32_t fromKeyCode, int32_t toKeyCode) {
1208 mKeyCodeMapping.insert_or_assign(fromKeyCode, toKeyCode);
1209 }
1210
Michael Wrightd02c5b62014-02-10 15:10:22 -08001211private:
Philip Junker4af3b3d2021-12-14 10:36:55 +01001212 uint32_t getSources() const override { return mSources; }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001213
Chris Yea52ade12020-08-27 16:49:20 -07001214 void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001215 InputMapper::populateDeviceInfo(deviceInfo);
1216
1217 if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) {
1218 deviceInfo->setKeyboardType(mKeyboardType);
1219 }
1220 }
1221
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07001222 std::list<NotifyArgs> configure(nsecs_t, const InputReaderConfiguration* config,
1223 uint32_t changes) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001224 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001225 mConfigureWasCalled = true;
Arthur Hungc23540e2018-11-29 20:42:11 +08001226
1227 // Find the associated viewport if exist.
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -08001228 const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
Arthur Hungc23540e2018-11-29 20:42:11 +08001229 if (displayPort && (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
1230 mViewport = config->getDisplayViewportByPort(*displayPort);
1231 }
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001232
1233 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07001234 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001235 }
1236
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07001237 std::list<NotifyArgs> reset(nsecs_t) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001238 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001239 mResetWasCalled = true;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001240 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07001241 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001242 }
1243
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07001244 std::list<NotifyArgs> process(const RawEvent* rawEvent) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001245 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001246 mLastEvent = *rawEvent;
1247 mProcessWasCalled = true;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001248 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07001249 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001250 }
1251
Chris Yea52ade12020-08-27 16:49:20 -07001252 int32_t getKeyCodeState(uint32_t, int32_t keyCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001253 ssize_t index = mKeyCodeStates.indexOfKey(keyCode);
1254 return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
1255 }
1256
Philip Junker4af3b3d2021-12-14 10:36:55 +01001257 int32_t getKeyCodeForKeyLocation(int32_t locationKeyCode) const override {
1258 auto it = mKeyCodeMapping.find(locationKeyCode);
1259 return it != mKeyCodeMapping.end() ? it->second : locationKeyCode;
1260 }
1261
Chris Yea52ade12020-08-27 16:49:20 -07001262 int32_t getScanCodeState(uint32_t, int32_t scanCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001263 ssize_t index = mScanCodeStates.indexOfKey(scanCode);
1264 return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
1265 }
1266
Chris Yea52ade12020-08-27 16:49:20 -07001267 int32_t getSwitchState(uint32_t, int32_t switchCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001268 ssize_t index = mSwitchStates.indexOfKey(switchCode);
1269 return index >= 0 ? mSwitchStates.valueAt(index) : AKEY_STATE_UNKNOWN;
1270 }
1271
Chris Yea52ade12020-08-27 16:49:20 -07001272 // Return true if the device has non-empty key layout.
Siarhei Vishniakou74007942022-06-13 13:57:47 -07001273 bool markSupportedKeyCodes(uint32_t, const std::vector<int32_t>& keyCodes,
Chris Yea52ade12020-08-27 16:49:20 -07001274 uint8_t* outFlags) override {
Siarhei Vishniakou74007942022-06-13 13:57:47 -07001275 for (size_t i = 0; i < keyCodes.size(); i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001276 for (size_t j = 0; j < mSupportedKeyCodes.size(); j++) {
1277 if (keyCodes[i] == mSupportedKeyCodes[j]) {
1278 outFlags[i] = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001279 }
1280 }
1281 }
Chris Yea52ade12020-08-27 16:49:20 -07001282 bool result = mSupportedKeyCodes.size() > 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001283 return result;
1284 }
1285
1286 virtual int32_t getMetaState() {
1287 return mMetaState;
1288 }
1289
1290 virtual void fadePointer() {
1291 }
Arthur Hungc23540e2018-11-29 20:42:11 +08001292
1293 virtual std::optional<int32_t> getAssociatedDisplay() {
1294 if (mViewport) {
1295 return std::make_optional(mViewport->displayId);
1296 }
1297 return std::nullopt;
1298 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001299};
1300
1301
1302// --- InstrumentedInputReader ---
1303
1304class InstrumentedInputReader : public InputReader {
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001305 std::queue<std::shared_ptr<InputDevice>> mNextDevices;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001306
1307public:
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07001308 InstrumentedInputReader(std::shared_ptr<EventHubInterface> eventHub,
1309 const sp<InputReaderPolicyInterface>& policy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001310 InputListenerInterface& listener)
arthurhungdcef2dc2020-08-11 14:47:50 +08001311 : InputReader(eventHub, policy, listener), mFakeContext(this) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001312
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +00001313 virtual ~InstrumentedInputReader() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001314
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001315 void pushNextDevice(std::shared_ptr<InputDevice> device) { mNextDevices.push(device); }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001316
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001317 std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +00001318 const std::string& location = "") {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001319 InputDeviceIdentifier identifier;
1320 identifier.name = name;
Arthur Hungc23540e2018-11-29 20:42:11 +08001321 identifier.location = location;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001322 int32_t generation = deviceId + 1;
arthurhungdcef2dc2020-08-11 14:47:50 +08001323 return std::make_shared<InputDevice>(&mFakeContext, deviceId, generation, identifier);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001324 }
1325
Prabir Pradhan28efc192019-11-05 01:10:04 +00001326 // Make the protected loopOnce method accessible to tests.
1327 using InputReader::loopOnce;
1328
Michael Wrightd02c5b62014-02-10 15:10:22 -08001329protected:
Chris Ye1c2e0892020-11-30 21:41:44 -08001330 virtual std::shared_ptr<InputDevice> createDeviceLocked(int32_t eventHubId,
1331 const InputDeviceIdentifier& identifier)
1332 REQUIRES(mLock) {
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001333 if (!mNextDevices.empty()) {
1334 std::shared_ptr<InputDevice> device(std::move(mNextDevices.front()));
1335 mNextDevices.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001336 return device;
1337 }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001338 return InputReader::createDeviceLocked(eventHubId, identifier);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001339 }
1340
arthurhungdcef2dc2020-08-11 14:47:50 +08001341 // --- FakeInputReaderContext ---
1342 class FakeInputReaderContext : public ContextImpl {
1343 int32_t mGlobalMetaState;
1344 bool mUpdateGlobalMetaStateWasCalled;
1345 int32_t mGeneration;
1346
1347 public:
1348 FakeInputReaderContext(InputReader* reader)
1349 : ContextImpl(reader),
1350 mGlobalMetaState(0),
1351 mUpdateGlobalMetaStateWasCalled(false),
1352 mGeneration(1) {}
1353
1354 virtual ~FakeInputReaderContext() {}
1355
1356 void assertUpdateGlobalMetaStateWasCalled() {
1357 ASSERT_TRUE(mUpdateGlobalMetaStateWasCalled)
1358 << "Expected updateGlobalMetaState() to have been called.";
1359 mUpdateGlobalMetaStateWasCalled = false;
1360 }
1361
1362 void setGlobalMetaState(int32_t state) { mGlobalMetaState = state; }
1363
1364 uint32_t getGeneration() { return mGeneration; }
1365
1366 void updateGlobalMetaState() override {
1367 mUpdateGlobalMetaStateWasCalled = true;
1368 ContextImpl::updateGlobalMetaState();
1369 }
1370
1371 int32_t getGlobalMetaState() override {
1372 return mGlobalMetaState | ContextImpl::getGlobalMetaState();
1373 }
1374
1375 int32_t bumpGeneration() override {
1376 mGeneration = ContextImpl::bumpGeneration();
1377 return mGeneration;
1378 }
1379 } mFakeContext;
1380
Michael Wrightd02c5b62014-02-10 15:10:22 -08001381 friend class InputReaderTest;
arthurhungdcef2dc2020-08-11 14:47:50 +08001382
1383public:
1384 FakeInputReaderContext* getContext() { return &mFakeContext; }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001385};
1386
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001387// --- InputReaderPolicyTest ---
1388class InputReaderPolicyTest : public testing::Test {
Siarhei Vishniakoucd7ac1e2018-10-15 13:39:50 -07001389protected:
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001390 sp<FakeInputReaderPolicy> mFakePolicy;
1391
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07001392 void SetUp() override { mFakePolicy = sp<FakeInputReaderPolicy>::make(); }
Chris Yea52ade12020-08-27 16:49:20 -07001393 void TearDown() override { mFakePolicy.clear(); }
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001394};
1395
1396/**
1397 * Check that empty set of viewports is an acceptable configuration.
1398 * Also try to get internal viewport two different ways - by type and by uniqueId.
1399 *
1400 * There will be confusion if two viewports with empty uniqueId and identical type are present.
1401 * Such configuration is not currently allowed.
1402 */
1403TEST_F(InputReaderPolicyTest, Viewports_GetCleared) {
Siarhei Vishniakoucd7ac1e2018-10-15 13:39:50 -07001404 static const std::string uniqueId = "local:0";
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001405
1406 // We didn't add any viewports yet, so there shouldn't be any.
1407 std::optional<DisplayViewport> internalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001408 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001409 ASSERT_FALSE(internalViewport);
1410
1411 // Add an internal viewport, then clear it
1412 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001413 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId, NO_PORT,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001414 ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001415
1416 // Check matching by uniqueId
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07001417 internalViewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001418 ASSERT_TRUE(internalViewport);
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001419 ASSERT_EQ(ViewportType::INTERNAL, internalViewport->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001420
1421 // Check matching by viewport type
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001422 internalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001423 ASSERT_TRUE(internalViewport);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07001424 ASSERT_EQ(uniqueId, internalViewport->uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001425
1426 mFakePolicy->clearViewports();
1427 // Make sure nothing is found after clear
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07001428 internalViewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001429 ASSERT_FALSE(internalViewport);
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001430 internalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001431 ASSERT_FALSE(internalViewport);
1432}
1433
1434TEST_F(InputReaderPolicyTest, Viewports_GetByType) {
1435 const std::string internalUniqueId = "local:0";
1436 const std::string externalUniqueId = "local:1";
1437 const std::string virtualUniqueId1 = "virtual:2";
1438 const std::string virtualUniqueId2 = "virtual:3";
1439 constexpr int32_t virtualDisplayId1 = 2;
1440 constexpr int32_t virtualDisplayId2 = 3;
1441
1442 // Add an internal viewport
1443 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001444 DISPLAY_ORIENTATION_0, true /*isActive*/, internalUniqueId,
1445 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001446 // Add an external viewport
1447 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001448 DISPLAY_ORIENTATION_0, true /*isActive*/, externalUniqueId,
1449 NO_PORT, ViewportType::EXTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001450 // Add an virtual viewport
1451 mFakePolicy->addDisplayViewport(virtualDisplayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001452 DISPLAY_ORIENTATION_0, true /*isActive*/, virtualUniqueId1,
1453 NO_PORT, ViewportType::VIRTUAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001454 // Add another virtual viewport
1455 mFakePolicy->addDisplayViewport(virtualDisplayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001456 DISPLAY_ORIENTATION_0, true /*isActive*/, virtualUniqueId2,
1457 NO_PORT, ViewportType::VIRTUAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001458
1459 // Check matching by type for internal
1460 std::optional<DisplayViewport> internalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001461 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001462 ASSERT_TRUE(internalViewport);
1463 ASSERT_EQ(internalUniqueId, internalViewport->uniqueId);
1464
1465 // Check matching by type for external
1466 std::optional<DisplayViewport> externalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001467 mFakePolicy->getDisplayViewportByType(ViewportType::EXTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001468 ASSERT_TRUE(externalViewport);
1469 ASSERT_EQ(externalUniqueId, externalViewport->uniqueId);
1470
1471 // Check matching by uniqueId for virtual viewport #1
1472 std::optional<DisplayViewport> virtualViewport1 =
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07001473 mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId1);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001474 ASSERT_TRUE(virtualViewport1);
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001475 ASSERT_EQ(ViewportType::VIRTUAL, virtualViewport1->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001476 ASSERT_EQ(virtualUniqueId1, virtualViewport1->uniqueId);
1477 ASSERT_EQ(virtualDisplayId1, virtualViewport1->displayId);
1478
1479 // Check matching by uniqueId for virtual viewport #2
1480 std::optional<DisplayViewport> virtualViewport2 =
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07001481 mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId2);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001482 ASSERT_TRUE(virtualViewport2);
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001483 ASSERT_EQ(ViewportType::VIRTUAL, virtualViewport2->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001484 ASSERT_EQ(virtualUniqueId2, virtualViewport2->uniqueId);
1485 ASSERT_EQ(virtualDisplayId2, virtualViewport2->displayId);
1486}
1487
1488
1489/**
1490 * We can have 2 viewports of the same kind. We can distinguish them by uniqueId, and confirm
1491 * that lookup works by checking display id.
1492 * Check that 2 viewports of each kind is possible, for all existing viewport types.
1493 */
1494TEST_F(InputReaderPolicyTest, Viewports_TwoOfSameType) {
1495 const std::string uniqueId1 = "uniqueId1";
1496 const std::string uniqueId2 = "uniqueId2";
1497 constexpr int32_t displayId1 = 2;
1498 constexpr int32_t displayId2 = 3;
1499
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001500 std::vector<ViewportType> types = {ViewportType::INTERNAL, ViewportType::EXTERNAL,
1501 ViewportType::VIRTUAL};
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001502 for (const ViewportType& type : types) {
1503 mFakePolicy->clearViewports();
1504 // Add a viewport
1505 mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001506 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1,
1507 NO_PORT, type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001508 // Add another viewport
1509 mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001510 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2,
1511 NO_PORT, type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001512
1513 // Check that correct display viewport was returned by comparing the display IDs.
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07001514 std::optional<DisplayViewport> viewport1 =
1515 mFakePolicy->getDisplayViewportByUniqueId(uniqueId1);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001516 ASSERT_TRUE(viewport1);
1517 ASSERT_EQ(displayId1, viewport1->displayId);
1518 ASSERT_EQ(type, viewport1->type);
1519
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07001520 std::optional<DisplayViewport> viewport2 =
1521 mFakePolicy->getDisplayViewportByUniqueId(uniqueId2);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001522 ASSERT_TRUE(viewport2);
1523 ASSERT_EQ(displayId2, viewport2->displayId);
1524 ASSERT_EQ(type, viewport2->type);
1525
1526 // When there are multiple viewports of the same kind, and uniqueId is not specified
1527 // in the call to getDisplayViewport, then that situation is not supported.
1528 // The viewports can be stored in any order, so we cannot rely on the order, since that
1529 // is just implementation detail.
1530 // However, we can check that it still returns *a* viewport, we just cannot assert
1531 // which one specifically is returned.
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07001532 std::optional<DisplayViewport> someViewport = mFakePolicy->getDisplayViewportByType(type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07001533 ASSERT_TRUE(someViewport);
1534 }
1535}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001536
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07001537/**
Michael Wrightdde67b82020-10-27 16:09:22 +00001538 * When we have multiple internal displays make sure we always return the default display when
1539 * querying by type.
1540 */
1541TEST_F(InputReaderPolicyTest, Viewports_ByTypeReturnsDefaultForInternal) {
1542 const std::string uniqueId1 = "uniqueId1";
1543 const std::string uniqueId2 = "uniqueId2";
1544 constexpr int32_t nonDefaultDisplayId = 2;
1545 static_assert(nonDefaultDisplayId != ADISPLAY_ID_DEFAULT,
1546 "Test display ID should not be ADISPLAY_ID_DEFAULT");
1547
1548 // Add the default display first and ensure it gets returned.
1549 mFakePolicy->clearViewports();
1550 mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001551 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +00001552 ViewportType::INTERNAL);
1553 mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001554 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +00001555 ViewportType::INTERNAL);
1556
1557 std::optional<DisplayViewport> viewport =
1558 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
1559 ASSERT_TRUE(viewport);
1560 ASSERT_EQ(ADISPLAY_ID_DEFAULT, viewport->displayId);
1561 ASSERT_EQ(ViewportType::INTERNAL, viewport->type);
1562
1563 // Add the default display second to make sure order doesn't matter.
1564 mFakePolicy->clearViewports();
1565 mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001566 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +00001567 ViewportType::INTERNAL);
1568 mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001569 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +00001570 ViewportType::INTERNAL);
1571
1572 viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
1573 ASSERT_TRUE(viewport);
1574 ASSERT_EQ(ADISPLAY_ID_DEFAULT, viewport->displayId);
1575 ASSERT_EQ(ViewportType::INTERNAL, viewport->type);
1576}
1577
1578/**
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07001579 * Check getDisplayViewportByPort
1580 */
1581TEST_F(InputReaderPolicyTest, Viewports_GetByPort) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001582 constexpr ViewportType type = ViewportType::EXTERNAL;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07001583 const std::string uniqueId1 = "uniqueId1";
1584 const std::string uniqueId2 = "uniqueId2";
1585 constexpr int32_t displayId1 = 1;
1586 constexpr int32_t displayId2 = 2;
1587 const uint8_t hdmi1 = 0;
1588 const uint8_t hdmi2 = 1;
1589 const uint8_t hdmi3 = 2;
1590
1591 mFakePolicy->clearViewports();
1592 // Add a viewport that's associated with some display port that's not of interest.
1593 mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001594 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1, hdmi3,
1595 type);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07001596 // Add another viewport, connected to HDMI1 port
1597 mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001598 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2, hdmi1,
1599 type);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07001600
1601 // Check that correct display viewport was returned by comparing the display ports.
1602 std::optional<DisplayViewport> hdmi1Viewport = mFakePolicy->getDisplayViewportByPort(hdmi1);
1603 ASSERT_TRUE(hdmi1Viewport);
1604 ASSERT_EQ(displayId2, hdmi1Viewport->displayId);
1605 ASSERT_EQ(uniqueId2, hdmi1Viewport->uniqueId);
1606
1607 // Check that we can still get the same viewport using the uniqueId
1608 hdmi1Viewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId2);
1609 ASSERT_TRUE(hdmi1Viewport);
1610 ASSERT_EQ(displayId2, hdmi1Viewport->displayId);
1611 ASSERT_EQ(uniqueId2, hdmi1Viewport->uniqueId);
1612 ASSERT_EQ(type, hdmi1Viewport->type);
1613
1614 // Check that we cannot find a port with "HDMI2", because we never added one
1615 std::optional<DisplayViewport> hdmi2Viewport = mFakePolicy->getDisplayViewportByPort(hdmi2);
1616 ASSERT_FALSE(hdmi2Viewport);
1617}
1618
Michael Wrightd02c5b62014-02-10 15:10:22 -08001619// --- InputReaderTest ---
1620
1621class InputReaderTest : public testing::Test {
1622protected:
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001623 std::unique_ptr<TestInputListener> mFakeListener;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001624 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07001625 std::shared_ptr<FakeEventHub> mFakeEventHub;
Prabir Pradhan28efc192019-11-05 01:10:04 +00001626 std::unique_ptr<InstrumentedInputReader> mReader;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001627
Chris Yea52ade12020-08-27 16:49:20 -07001628 void SetUp() override {
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07001629 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07001630 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001631 mFakeListener = std::make_unique<TestInputListener>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001632
Prabir Pradhan28efc192019-11-05 01:10:04 +00001633 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001634 *mFakeListener);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001635 }
1636
Chris Yea52ade12020-08-27 16:49:20 -07001637 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001638 mFakeListener.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001639 mFakePolicy.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001640 }
1641
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001642 void addDevice(int32_t eventHubId, const std::string& name,
1643 ftl::Flags<InputDeviceClass> classes, const PropertyMap* configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001644 mFakeEventHub->addDevice(eventHubId, name, classes);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001645
1646 if (configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001647 mFakeEventHub->addConfigurationMap(eventHubId, configuration);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001648 }
1649 mFakeEventHub->finishDeviceScan();
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001650 mReader->loopOnce();
1651 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001652 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1653 ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001654 }
1655
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001656 void disableDevice(int32_t deviceId) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07001657 mFakePolicy->addDisabledDevice(deviceId);
Prabir Pradhan28efc192019-11-05 01:10:04 +00001658 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_ENABLED_STATE);
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07001659 }
1660
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001661 void enableDevice(int32_t deviceId) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07001662 mFakePolicy->removeDisabledDevice(deviceId);
Prabir Pradhan28efc192019-11-05 01:10:04 +00001663 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_ENABLED_STATE);
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07001664 }
1665
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001666 FakeInputMapper& addDeviceWithFakeInputMapper(int32_t deviceId, int32_t eventHubId,
Chris Ye1b0c7342020-07-28 21:57:03 -07001667 const std::string& name,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001668 ftl::Flags<InputDeviceClass> classes,
1669 uint32_t sources,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001670 const PropertyMap* configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001671 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, name);
1672 FakeInputMapper& mapper = device->addMapper<FakeInputMapper>(eventHubId, sources);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001673 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001674 addDevice(eventHubId, name, classes, configuration);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001675 return mapper;
1676 }
1677};
1678
Chris Ye98d3f532020-10-01 21:48:59 -07001679TEST_F(InputReaderTest, PolicyGetInputDevices) {
1680 ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr));
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001681 ASSERT_NO_FATAL_FAILURE(addDevice(2, "ignored", ftl::Flags<InputDeviceClass>(0),
Chris Ye98d3f532020-10-01 21:48:59 -07001682 nullptr)); // no classes so device will be ignored
Michael Wrightd02c5b62014-02-10 15:10:22 -08001683
1684 // Should also have received a notification describing the new input devices.
Chris Ye98d3f532020-10-01 21:48:59 -07001685 const std::vector<InputDeviceInfo>& inputDevices = mFakePolicy->getInputDevices();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001686 ASSERT_EQ(1U, inputDevices.size());
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001687 ASSERT_EQ(END_RESERVED_ID + 1, inputDevices[0].getId());
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01001688 ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001689 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
1690 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00001691 ASSERT_EQ(0U, inputDevices[0].getMotionRanges().size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001692}
1693
Chris Yee7310032020-09-22 15:36:28 -07001694TEST_F(InputReaderTest, GetMergedInputDevices) {
1695 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1696 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
1697 // Add two subdevices to device
1698 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1699 // Must add at least one mapper or the device will be ignored!
1700 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
1701 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
1702
1703 // Push same device instance for next device to be added, so they'll have same identifier.
1704 mReader->pushNextDevice(device);
1705 mReader->pushNextDevice(device);
1706 ASSERT_NO_FATAL_FAILURE(
1707 addDevice(eventHubIds[0], "fake1", InputDeviceClass::KEYBOARD, nullptr));
1708 ASSERT_NO_FATAL_FAILURE(
1709 addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
1710
1711 // Two devices will be merged to one input device as they have same identifier
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00001712 ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
Chris Yee7310032020-09-22 15:36:28 -07001713}
1714
Chris Yee14523a2020-12-19 13:46:00 -08001715TEST_F(InputReaderTest, GetMergedInputDevicesEnabled) {
1716 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1717 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
1718 // Add two subdevices to device
1719 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1720 // Must add at least one mapper or the device will be ignored!
1721 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
1722 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
1723
1724 // Push same device instance for next device to be added, so they'll have same identifier.
1725 mReader->pushNextDevice(device);
1726 mReader->pushNextDevice(device);
1727 // Sensor device is initially disabled
1728 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1",
1729 InputDeviceClass::KEYBOARD | InputDeviceClass::SENSOR,
1730 nullptr));
1731 // Device is disabled because the only sub device is a sensor device and disabled initially.
1732 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1733 ASSERT_FALSE(device->isEnabled());
1734 ASSERT_NO_FATAL_FAILURE(
1735 addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
1736 // The merged device is enabled if any sub device is enabled
1737 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1738 ASSERT_TRUE(device->isEnabled());
1739}
1740
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07001741TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001742 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001743 constexpr ftl::Flags<InputDeviceClass> deviceClass(InputDeviceClass::KEYBOARD);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001744 constexpr int32_t eventHubId = 1;
1745 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07001746 // Must add at least one mapper or the device will be ignored!
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001747 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001748 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001749 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07001750
Yi Kong9b14ac62018-07-17 13:48:38 -07001751 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07001752
1753 NotifyDeviceResetArgs resetArgs;
1754 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07001755 ASSERT_EQ(deviceId, resetArgs.deviceId);
1756
1757 ASSERT_EQ(device->isEnabled(), true);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001758 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001759 mReader->loopOnce();
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07001760
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001761 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07001762 ASSERT_EQ(deviceId, resetArgs.deviceId);
1763 ASSERT_EQ(device->isEnabled(), false);
1764
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001765 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001766 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001767 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
1768 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasNotCalled());
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07001769 ASSERT_EQ(device->isEnabled(), false);
1770
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001771 enableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001772 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001773 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07001774 ASSERT_EQ(deviceId, resetArgs.deviceId);
1775 ASSERT_EQ(device->isEnabled(), true);
1776}
1777
Michael Wrightd02c5b62014-02-10 15:10:22 -08001778TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001779 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001780 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001781 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001782 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001783 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001784 AINPUT_SOURCE_KEYBOARD, nullptr);
1785 mapper.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001786
1787 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(0,
1788 AINPUT_SOURCE_ANY, AKEYCODE_A))
1789 << "Should return unknown when the device id is >= 0 but unknown.";
1790
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001791 ASSERT_EQ(AKEY_STATE_UNKNOWN,
1792 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
1793 << "Should return unknown when the device id is valid but the sources are not "
1794 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001795
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001796 ASSERT_EQ(AKEY_STATE_DOWN,
1797 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
1798 AKEYCODE_A))
1799 << "Should return value provided by mapper when device id is valid and the device "
1800 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001801
1802 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(-1,
1803 AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
1804 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
1805
1806 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(-1,
1807 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
1808 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
1809}
1810
Philip Junker4af3b3d2021-12-14 10:36:55 +01001811TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_ForwardsRequestsToMappers) {
1812 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1813 constexpr int32_t eventHubId = 1;
1814 FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "keyboard",
1815 InputDeviceClass::KEYBOARD,
1816 AINPUT_SOURCE_KEYBOARD, nullptr);
1817 mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
1818
1819 ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(0, AKEYCODE_Y))
1820 << "Should return unknown when the device with the specified id is not found.";
1821
1822 ASSERT_EQ(AKEYCODE_Z, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
1823 << "Should return correct mapping when device id is valid and mapping exists.";
1824
1825 ASSERT_EQ(AKEYCODE_A, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_A))
1826 << "Should return the location key code when device id is valid and there's no "
1827 "mapping.";
1828}
1829
1830TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_NoKeyboardMapper) {
1831 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1832 constexpr int32_t eventHubId = 1;
1833 FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "joystick",
1834 InputDeviceClass::JOYSTICK,
1835 AINPUT_SOURCE_GAMEPAD, nullptr);
1836 mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
1837
1838 ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
1839 << "Should return unknown when the device id is valid but there is no keyboard mapper";
1840}
1841
Michael Wrightd02c5b62014-02-10 15:10:22 -08001842TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001843 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001844 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001845 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001846 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001847 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001848 AINPUT_SOURCE_KEYBOARD, nullptr);
1849 mapper.setScanCodeState(KEY_A, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001850
1851 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(0,
1852 AINPUT_SOURCE_ANY, KEY_A))
1853 << "Should return unknown when the device id is >= 0 but unknown.";
1854
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001855 ASSERT_EQ(AKEY_STATE_UNKNOWN,
1856 mReader->getScanCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, KEY_A))
1857 << "Should return unknown when the device id is valid but the sources are not "
1858 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001859
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001860 ASSERT_EQ(AKEY_STATE_DOWN,
1861 mReader->getScanCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
1862 KEY_A))
1863 << "Should return value provided by mapper when device id is valid and the device "
1864 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001865
1866 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(-1,
1867 AINPUT_SOURCE_TRACKBALL, KEY_A))
1868 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
1869
1870 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(-1,
1871 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
1872 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
1873}
1874
1875TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001876 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001877 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001878 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001879 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001880 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001881 AINPUT_SOURCE_KEYBOARD, nullptr);
1882 mapper.setSwitchState(SW_LID, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001883
1884 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(0,
1885 AINPUT_SOURCE_ANY, SW_LID))
1886 << "Should return unknown when the device id is >= 0 but unknown.";
1887
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001888 ASSERT_EQ(AKEY_STATE_UNKNOWN,
1889 mReader->getSwitchState(deviceId, AINPUT_SOURCE_TRACKBALL, SW_LID))
1890 << "Should return unknown when the device id is valid but the sources are not "
1891 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001892
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001893 ASSERT_EQ(AKEY_STATE_DOWN,
1894 mReader->getSwitchState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
1895 SW_LID))
1896 << "Should return value provided by mapper when device id is valid and the device "
1897 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001898
1899 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(-1,
1900 AINPUT_SOURCE_TRACKBALL, SW_LID))
1901 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
1902
1903 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(-1,
1904 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
1905 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
1906}
1907
1908TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001909 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001910 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001911 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001912 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001913 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001914 AINPUT_SOURCE_KEYBOARD, nullptr);
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01001915
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001916 mapper.addSupportedKeyCode(AKEYCODE_A);
1917 mapper.addSupportedKeyCode(AKEYCODE_B);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001918
Siarhei Vishniakou74007942022-06-13 13:57:47 -07001919 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001920 uint8_t flags[4] = { 0, 0, 0, 1 };
1921
Siarhei Vishniakou74007942022-06-13 13:57:47 -07001922 ASSERT_FALSE(mReader->hasKeys(0, AINPUT_SOURCE_ANY, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -08001923 << "Should return false when device id is >= 0 but unknown.";
1924 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
1925
1926 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -07001927 ASSERT_FALSE(mReader->hasKeys(deviceId, AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001928 << "Should return false when device id is valid but the sources are not supported by "
1929 "the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001930 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
1931
1932 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -07001933 ASSERT_TRUE(mReader->hasKeys(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001934 keyCodes, flags))
1935 << "Should return value provided by mapper when device id is valid and the device "
1936 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001937 ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
1938
1939 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -07001940 ASSERT_FALSE(mReader->hasKeys(-1, AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
1941 << "Should return false when the device id is < 0 but the sources are not supported by "
1942 "any device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001943 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
1944
1945 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -07001946 ASSERT_TRUE(
1947 mReader->hasKeys(-1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
1948 << "Should return value provided by mapper when device id is < 0 and one of the "
1949 "devices supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001950 ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
1951}
1952
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001953TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001954 constexpr int32_t eventHubId = 1;
Chris Ye1b0c7342020-07-28 21:57:03 -07001955 addDevice(eventHubId, "ignored", InputDeviceClass::KEYBOARD, nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001956
1957 NotifyConfigurationChangedArgs args;
1958
1959 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(&args));
1960 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
1961}
1962
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001963TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001964 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001965 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001966 constexpr nsecs_t when = 0;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001967 constexpr int32_t eventHubId = 1;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001968 constexpr nsecs_t readTime = 2;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001969 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001970 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001971 AINPUT_SOURCE_KEYBOARD, nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001972
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001973 mFakeEventHub->enqueueEvent(when, readTime, eventHubId, EV_KEY, KEY_A, 1);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001974 mReader->loopOnce();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001975 ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
1976
1977 RawEvent event;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001978 ASSERT_NO_FATAL_FAILURE(mapper.assertProcessWasCalled(&event));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001979 ASSERT_EQ(when, event.when);
1980 ASSERT_EQ(readTime, event.readTime);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001981 ASSERT_EQ(eventHubId, event.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001982 ASSERT_EQ(EV_KEY, event.type);
1983 ASSERT_EQ(KEY_A, event.code);
1984 ASSERT_EQ(1, event.value);
1985}
1986
Garfield Tan1c7bc862020-01-28 13:24:04 -08001987TEST_F(InputReaderTest, DeviceReset_RandomId) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001988 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001989 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001990 constexpr int32_t eventHubId = 1;
1991 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
Prabir Pradhan42611e02018-11-27 14:04:02 -08001992 // Must add at least one mapper or the device will be ignored!
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001993 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001994 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001995 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Prabir Pradhan42611e02018-11-27 14:04:02 -08001996
1997 NotifyDeviceResetArgs resetArgs;
1998 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001999 int32_t prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08002000
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002001 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00002002 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07002003 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -08002004 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08002005 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08002006
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002007 enableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00002008 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07002009 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -08002010 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08002011 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08002012
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002013 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00002014 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07002015 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -08002016 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08002017 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08002018}
2019
Garfield Tan1c7bc862020-01-28 13:24:04 -08002020TEST_F(InputReaderTest, DeviceReset_GenerateIdWithInputReaderSource) {
2021 constexpr int32_t deviceId = 1;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002022 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002023 constexpr int32_t eventHubId = 1;
2024 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
2025 // Must add at least one mapper or the device will be ignored!
2026 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08002027 mReader->pushNextDevice(device);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002028 ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr));
2029
2030 NotifyDeviceResetArgs resetArgs;
2031 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2032 ASSERT_EQ(IdGenerator::Source::INPUT_READER, IdGenerator::getSource(resetArgs.id));
2033}
2034
Arthur Hungc23540e2018-11-29 20:42:11 +08002035TEST_F(InputReaderTest, Device_CanDispatchToDisplay) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002036 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002037 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002038 constexpr int32_t eventHubId = 1;
Arthur Hungc23540e2018-11-29 20:42:11 +08002039 const char* DEVICE_LOCATION = "USB1";
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002040 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
2041 FakeInputMapper& mapper =
2042 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_TOUCHSCREEN);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08002043 mReader->pushNextDevice(device);
Arthur Hungc23540e2018-11-29 20:42:11 +08002044
2045 const uint8_t hdmi1 = 1;
2046
2047 // Associated touch screen with second display.
2048 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
2049
2050 // Add default and second display.
Prabir Pradhan28efc192019-11-05 01:10:04 +00002051 mFakePolicy->clearViewports();
Arthur Hungc23540e2018-11-29 20:42:11 +08002052 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00002053 DISPLAY_ORIENTATION_0, true /*isActive*/, "local:0", NO_PORT,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01002054 ViewportType::INTERNAL);
Arthur Hungc23540e2018-11-29 20:42:11 +08002055 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00002056 DISPLAY_ORIENTATION_0, true /*isActive*/, "local:1", hdmi1,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01002057 ViewportType::EXTERNAL);
Arthur Hungc23540e2018-11-29 20:42:11 +08002058 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00002059 mReader->loopOnce();
Prabir Pradhan28efc192019-11-05 01:10:04 +00002060
2061 // Add the device, and make sure all of the callbacks are triggered.
2062 // The device is added after the input port associations are processed since
2063 // we do not yet support dynamic device-to-display associations.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002064 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07002065 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled());
Prabir Pradhan28efc192019-11-05 01:10:04 +00002066 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002067 ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
Arthur Hungc23540e2018-11-29 20:42:11 +08002068
Arthur Hung2c9a3342019-07-23 14:18:59 +08002069 // Device should only dispatch to the specified display.
Arthur Hungc23540e2018-11-29 20:42:11 +08002070 ASSERT_EQ(deviceId, device->getId());
2071 ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, DISPLAY_ID));
2072 ASSERT_TRUE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
Arthur Hung2c9a3342019-07-23 14:18:59 +08002073
2074 // Can't dispatch event from a disabled device.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002075 disableDevice(deviceId);
Prabir Pradhan28efc192019-11-05 01:10:04 +00002076 mReader->loopOnce();
Arthur Hung2c9a3342019-07-23 14:18:59 +08002077 ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
Arthur Hungc23540e2018-11-29 20:42:11 +08002078}
2079
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08002080TEST_F(InputReaderTest, WhenEnabledChanges_AllSubdevicesAreUpdated) {
2081 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002082 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08002083 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
2084 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
2085 // Must add at least one mapper or the device will be ignored!
2086 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
2087 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
2088 mReader->pushNextDevice(device);
2089 mReader->pushNextDevice(device);
2090 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
2091 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
2092
2093 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
2094
2095 NotifyDeviceResetArgs resetArgs;
2096 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2097 ASSERT_EQ(deviceId, resetArgs.deviceId);
2098 ASSERT_TRUE(device->isEnabled());
2099 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
2100 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
2101
2102 disableDevice(deviceId);
2103 mReader->loopOnce();
2104
2105 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2106 ASSERT_EQ(deviceId, resetArgs.deviceId);
2107 ASSERT_FALSE(device->isEnabled());
2108 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
2109 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
2110
2111 enableDevice(deviceId);
2112 mReader->loopOnce();
2113
2114 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2115 ASSERT_EQ(deviceId, resetArgs.deviceId);
2116 ASSERT_TRUE(device->isEnabled());
2117 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
2118 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
2119}
2120
2121TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToSubdeviceMappers) {
2122 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002123 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08002124 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
2125 // Add two subdevices to device
2126 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
2127 FakeInputMapper& mapperDevice1 =
2128 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
2129 FakeInputMapper& mapperDevice2 =
2130 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
2131 mReader->pushNextDevice(device);
2132 mReader->pushNextDevice(device);
2133 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
2134 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
2135
2136 mapperDevice1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
2137 mapperDevice2.setKeyCodeState(AKEYCODE_B, AKEY_STATE_DOWN);
2138
2139 ASSERT_EQ(AKEY_STATE_DOWN,
2140 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_A));
2141 ASSERT_EQ(AKEY_STATE_DOWN,
2142 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_B));
2143 ASSERT_EQ(AKEY_STATE_UNKNOWN,
2144 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_C));
2145}
2146
Prabir Pradhan7e186182020-11-10 13:56:45 -08002147TEST_F(InputReaderTest, ChangingPointerCaptureNotifiesInputListener) {
2148 NotifyPointerCaptureChangedArgs args;
2149
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00002150 auto request = mFakePolicy->setPointerCapture(true);
Prabir Pradhan7e186182020-11-10 13:56:45 -08002151 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
2152 mReader->loopOnce();
2153 mFakeListener->assertNotifyCaptureWasCalled(&args);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00002154 ASSERT_TRUE(args.request.enable) << "Pointer Capture should be enabled.";
2155 ASSERT_EQ(args.request, request) << "Pointer Capture sequence number should match.";
Prabir Pradhan7e186182020-11-10 13:56:45 -08002156
2157 mFakePolicy->setPointerCapture(false);
2158 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
2159 mReader->loopOnce();
2160 mFakeListener->assertNotifyCaptureWasCalled(&args);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00002161 ASSERT_FALSE(args.request.enable) << "Pointer Capture should be disabled.";
Prabir Pradhan7e186182020-11-10 13:56:45 -08002162
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00002163 // Verify that the Pointer Capture state is not updated when the configuration value
Prabir Pradhan7e186182020-11-10 13:56:45 -08002164 // does not change.
2165 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
2166 mReader->loopOnce();
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00002167 mFakeListener->assertNotifyCaptureWasNotCalled();
Prabir Pradhan7e186182020-11-10 13:56:45 -08002168}
2169
Chris Ye87143712020-11-10 05:05:58 +00002170class FakeVibratorInputMapper : public FakeInputMapper {
2171public:
2172 FakeVibratorInputMapper(InputDeviceContext& deviceContext, uint32_t sources)
2173 : FakeInputMapper(deviceContext, sources) {}
2174
2175 std::vector<int32_t> getVibratorIds() override { return getDeviceContext().getVibratorIds(); }
2176};
2177
2178TEST_F(InputReaderTest, VibratorGetVibratorIds) {
2179 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002180 ftl::Flags<InputDeviceClass> deviceClass =
2181 InputDeviceClass::KEYBOARD | InputDeviceClass::VIBRATOR;
Chris Ye87143712020-11-10 05:05:58 +00002182 constexpr int32_t eventHubId = 1;
2183 const char* DEVICE_LOCATION = "BLUETOOTH";
2184 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
2185 FakeVibratorInputMapper& mapper =
2186 device->addMapper<FakeVibratorInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
2187 mReader->pushNextDevice(device);
2188
2189 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
2190 ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
2191
2192 ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
2193 ASSERT_EQ(mReader->getVibratorIds(deviceId).size(), 2U);
2194}
2195
Chris Ye1dd2e5c2021-04-04 23:12:41 -07002196// --- FakePeripheralController ---
Kim Low03ea0352020-11-06 12:45:07 -08002197
Chris Ye1dd2e5c2021-04-04 23:12:41 -07002198class FakePeripheralController : public PeripheralControllerInterface {
Chris Yee2b1e5c2021-03-10 22:45:12 -08002199public:
Chris Ye1dd2e5c2021-04-04 23:12:41 -07002200 FakePeripheralController(InputDeviceContext& deviceContext) : mDeviceContext(deviceContext) {}
Chris Yee2b1e5c2021-03-10 22:45:12 -08002201
Chris Ye1dd2e5c2021-04-04 23:12:41 -07002202 ~FakePeripheralController() override {}
Chris Yee2b1e5c2021-03-10 22:45:12 -08002203
Andy Chenf9f1a022022-08-29 20:07:10 -04002204 int32_t getEventHubId() const { return getDeviceContext().getEventHubId(); }
2205
Chris Yee2b1e5c2021-03-10 22:45:12 -08002206 void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {}
2207
2208 void dump(std::string& dump) override {}
2209
2210 std::optional<int32_t> getBatteryCapacity(int32_t batteryId) override {
2211 return getDeviceContext().getBatteryCapacity(batteryId);
Kim Low03ea0352020-11-06 12:45:07 -08002212 }
2213
Chris Yee2b1e5c2021-03-10 22:45:12 -08002214 std::optional<int32_t> getBatteryStatus(int32_t batteryId) override {
2215 return getDeviceContext().getBatteryStatus(batteryId);
Kim Low03ea0352020-11-06 12:45:07 -08002216 }
Chris Ye3fdbfef2021-01-06 18:45:18 -08002217
2218 bool setLightColor(int32_t lightId, int32_t color) override {
2219 getDeviceContext().setLightBrightness(lightId, color >> 24);
2220 return true;
2221 }
2222
2223 std::optional<int32_t> getLightColor(int32_t lightId) override {
2224 std::optional<int32_t> result = getDeviceContext().getLightBrightness(lightId);
2225 if (!result.has_value()) {
2226 return std::nullopt;
2227 }
2228 return result.value() << 24;
2229 }
Chris Yee2b1e5c2021-03-10 22:45:12 -08002230
2231 bool setLightPlayerId(int32_t lightId, int32_t playerId) override { return true; }
2232
2233 std::optional<int32_t> getLightPlayerId(int32_t lightId) override { return std::nullopt; }
2234
2235private:
2236 InputDeviceContext& mDeviceContext;
2237 inline int32_t getDeviceId() { return mDeviceContext.getId(); }
2238 inline InputDeviceContext& getDeviceContext() { return mDeviceContext; }
Andy Chenf9f1a022022-08-29 20:07:10 -04002239 inline InputDeviceContext& getDeviceContext() const { return mDeviceContext; }
Chris Ye3fdbfef2021-01-06 18:45:18 -08002240};
2241
Chris Yee2b1e5c2021-03-10 22:45:12 -08002242TEST_F(InputReaderTest, BatteryGetCapacity) {
2243 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002244 ftl::Flags<InputDeviceClass> deviceClass =
2245 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
Chris Yee2b1e5c2021-03-10 22:45:12 -08002246 constexpr int32_t eventHubId = 1;
2247 const char* DEVICE_LOCATION = "BLUETOOTH";
2248 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07002249 FakePeripheralController& controller =
2250 device->addController<FakePeripheralController>(eventHubId);
Chris Yee2b1e5c2021-03-10 22:45:12 -08002251 mReader->pushNextDevice(device);
2252
2253 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
2254
2255 ASSERT_EQ(controller.getBatteryCapacity(DEFAULT_BATTERY), BATTERY_CAPACITY);
2256 ASSERT_EQ(mReader->getBatteryCapacity(deviceId), BATTERY_CAPACITY);
2257}
2258
2259TEST_F(InputReaderTest, BatteryGetStatus) {
2260 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002261 ftl::Flags<InputDeviceClass> deviceClass =
2262 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
Chris Yee2b1e5c2021-03-10 22:45:12 -08002263 constexpr int32_t eventHubId = 1;
2264 const char* DEVICE_LOCATION = "BLUETOOTH";
2265 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07002266 FakePeripheralController& controller =
2267 device->addController<FakePeripheralController>(eventHubId);
Chris Yee2b1e5c2021-03-10 22:45:12 -08002268 mReader->pushNextDevice(device);
2269
2270 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
2271
2272 ASSERT_EQ(controller.getBatteryStatus(DEFAULT_BATTERY), BATTERY_STATUS);
2273 ASSERT_EQ(mReader->getBatteryStatus(deviceId), BATTERY_STATUS);
2274}
2275
Prabir Pradhane287ecd2022-09-07 21:18:05 +00002276TEST_F(InputReaderTest, BatteryGetDevicePath) {
2277 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
2278 ftl::Flags<InputDeviceClass> deviceClass =
2279 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
2280 constexpr int32_t eventHubId = 1;
2281 const char* DEVICE_LOCATION = "BLUETOOTH";
2282 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
2283 device->addController<FakePeripheralController>(eventHubId);
2284 mReader->pushNextDevice(device);
2285
2286 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
2287
2288 ASSERT_EQ(mReader->getBatteryDevicePath(deviceId), BATTERY_DEVPATH);
2289}
2290
Chris Ye3fdbfef2021-01-06 18:45:18 -08002291TEST_F(InputReaderTest, LightGetColor) {
2292 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002293 ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD | InputDeviceClass::LIGHT;
Chris Ye3fdbfef2021-01-06 18:45:18 -08002294 constexpr int32_t eventHubId = 1;
2295 const char* DEVICE_LOCATION = "BLUETOOTH";
2296 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07002297 FakePeripheralController& controller =
2298 device->addController<FakePeripheralController>(eventHubId);
Chris Ye3fdbfef2021-01-06 18:45:18 -08002299 mReader->pushNextDevice(device);
2300 RawLightInfo info = {.id = 1,
2301 .name = "Mono",
2302 .maxBrightness = 255,
2303 .flags = InputLightClass::BRIGHTNESS,
2304 .path = ""};
2305 mFakeEventHub->addRawLightInfo(1 /* rawId */, std::move(info));
2306 mFakeEventHub->fakeLightBrightness(1 /* rawId */, 0x55);
2307
2308 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Chris Ye3fdbfef2021-01-06 18:45:18 -08002309
Chris Yee2b1e5c2021-03-10 22:45:12 -08002310 ASSERT_TRUE(controller.setLightColor(1 /* lightId */, LIGHT_BRIGHTNESS));
2311 ASSERT_EQ(controller.getLightColor(1 /* lightId */), LIGHT_BRIGHTNESS);
Chris Ye3fdbfef2021-01-06 18:45:18 -08002312 ASSERT_TRUE(mReader->setLightColor(deviceId, 1 /* lightId */, LIGHT_BRIGHTNESS));
2313 ASSERT_EQ(mReader->getLightColor(deviceId, 1 /* lightId */), LIGHT_BRIGHTNESS);
2314}
2315
Prabir Pradhan1aed8582019-12-30 11:46:51 -08002316// --- InputReaderIntegrationTest ---
2317
2318// These tests create and interact with the InputReader only through its interface.
2319// The InputReader is started during SetUp(), which starts its processing in its own
2320// thread. The tests use linux uinput to emulate input devices.
2321// NOTE: Interacting with the physical device while these tests are running may cause
2322// the tests to fail.
2323class InputReaderIntegrationTest : public testing::Test {
2324protected:
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002325 std::unique_ptr<TestInputListener> mTestListener;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08002326 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002327 std::unique_ptr<InputReaderInterface> mReader;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08002328
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00002329 std::shared_ptr<FakePointerController> mFakePointerController;
2330
Chris Yea52ade12020-08-27 16:49:20 -07002331 void SetUp() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07002332#if !defined(__ANDROID__)
2333 GTEST_SKIP();
2334#endif
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07002335 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00002336 mFakePointerController = std::make_shared<FakePointerController>();
2337 mFakePolicy->setPointerController(mFakePointerController);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002338 mTestListener = std::make_unique<TestInputListener>(2000ms /*eventHappenedTimeout*/,
2339 30ms /*eventDidNotHappenTimeout*/);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08002340
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002341 mReader = std::make_unique<InputReader>(std::make_shared<EventHub>(), mFakePolicy,
2342 *mTestListener);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08002343 ASSERT_EQ(mReader->start(), OK);
2344
2345 // Since this test is run on a real device, all the input devices connected
2346 // to the test device will show up in mReader. We wait for those input devices to
2347 // show up before beginning the tests.
2348 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2349 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2350 }
2351
Chris Yea52ade12020-08-27 16:49:20 -07002352 void TearDown() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07002353#if !defined(__ANDROID__)
2354 return;
2355#endif
Prabir Pradhan1aed8582019-12-30 11:46:51 -08002356 ASSERT_EQ(mReader->stop(), OK);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002357 mReader.reset();
2358 mTestListener.reset();
Prabir Pradhan1aed8582019-12-30 11:46:51 -08002359 mFakePolicy.clear();
2360 }
Prabir Pradhanda20b172022-09-26 17:01:18 +00002361
2362 std::optional<InputDeviceInfo> findDeviceByName(const std::string& name) {
2363 const std::vector<InputDeviceInfo> inputDevices = mFakePolicy->getInputDevices();
2364 const auto& it = std::find_if(inputDevices.begin(), inputDevices.end(),
2365 [&name](const InputDeviceInfo& info) {
2366 return info.getIdentifier().name == name;
2367 });
2368 return it != inputDevices.end() ? std::make_optional(*it) : std::nullopt;
2369 }
Prabir Pradhan1aed8582019-12-30 11:46:51 -08002370};
2371
2372TEST_F(InputReaderIntegrationTest, TestInvalidDevice) {
2373 // An invalid input device that is only used for this test.
2374 class InvalidUinputDevice : public UinputDevice {
2375 public:
2376 InvalidUinputDevice() : UinputDevice("Invalid Device") {}
2377
2378 private:
2379 void configureDevice(int fd, uinput_user_dev* device) override {}
2380 };
2381
2382 const size_t numDevices = mFakePolicy->getInputDevices().size();
2383
2384 // UinputDevice does not set any event or key bits, so InputReader should not
2385 // consider it as a valid device.
2386 std::unique_ptr<UinputDevice> invalidDevice = createUinputDevice<InvalidUinputDevice>();
2387 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
2388 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
2389 ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
2390
2391 invalidDevice.reset();
2392 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
2393 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
2394 ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
2395}
2396
2397TEST_F(InputReaderIntegrationTest, AddNewDevice) {
2398 const size_t initialNumDevices = mFakePolicy->getInputDevices().size();
2399
2400 std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
2401 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2402 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2403 ASSERT_EQ(initialNumDevices + 1, mFakePolicy->getInputDevices().size());
2404
Prabir Pradhane1a41a82022-10-14 18:06:50 +00002405 const auto device = findDeviceByName(keyboard->getName());
2406 ASSERT_TRUE(device.has_value());
2407 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, device->getKeyboardType());
2408 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources());
2409 ASSERT_EQ(0U, device->getMotionRanges().size());
Prabir Pradhan1aed8582019-12-30 11:46:51 -08002410
2411 keyboard.reset();
2412 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2413 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2414 ASSERT_EQ(initialNumDevices, mFakePolicy->getInputDevices().size());
2415}
2416
2417TEST_F(InputReaderIntegrationTest, SendsEventsToInputListener) {
2418 std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
2419 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2420
2421 NotifyConfigurationChangedArgs configChangedArgs;
2422 ASSERT_NO_FATAL_FAILURE(
2423 mTestListener->assertNotifyConfigurationChangedWasCalled(&configChangedArgs));
Garfield Tanc51d1ba2020-01-28 13:24:04 -08002424 int32_t prevId = configChangedArgs.id;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08002425 nsecs_t prevTimestamp = configChangedArgs.eventTime;
2426
2427 NotifyKeyArgs keyArgs;
2428 keyboard->pressAndReleaseHomeKey();
2429 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
2430 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002431 ASSERT_NE(prevId, keyArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08002432 prevId = keyArgs.id;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08002433 ASSERT_LE(prevTimestamp, keyArgs.eventTime);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002434 ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08002435 prevTimestamp = keyArgs.eventTime;
2436
2437 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
2438 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002439 ASSERT_NE(prevId, keyArgs.id);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08002440 ASSERT_LE(prevTimestamp, keyArgs.eventTime);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002441 ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08002442}
Michael Wrightd02c5b62014-02-10 15:10:22 -08002443
Prabir Pradhane1a41a82022-10-14 18:06:50 +00002444TEST_F(InputReaderIntegrationTest, ExternalStylusesButtons) {
2445 std::unique_ptr<UinputExternalStylus> stylus = createUinputDevice<UinputExternalStylus>();
2446 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2447
2448 const auto device = findDeviceByName(stylus->getName());
2449 ASSERT_TRUE(device.has_value());
2450
Prabir Pradhana3621852022-10-14 18:57:23 +00002451 // An external stylus with buttons should also be recognized as a keyboard.
2452 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_STYLUS, device->getSources())
Prabir Pradhane1a41a82022-10-14 18:06:50 +00002453 << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
2454 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, device->getKeyboardType());
2455
2456 const auto DOWN =
2457 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD));
2458 const auto UP = AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD));
2459
2460 stylus->pressAndReleaseKey(BTN_STYLUS);
2461 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
2462 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
2463 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
2464 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
2465
2466 stylus->pressAndReleaseKey(BTN_STYLUS2);
2467 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
2468 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_SECONDARY))));
2469 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
2470 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_SECONDARY))));
2471
2472 stylus->pressAndReleaseKey(BTN_STYLUS3);
2473 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
2474 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
2475 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
2476 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
2477}
2478
Siarhei Vishniakoua0d2b802020-05-13 14:00:31 -07002479/**
2480 * The Steam controller sends BTN_GEAR_DOWN and BTN_GEAR_UP for the two "paddle" buttons
2481 * on the back. In this test, we make sure that BTN_GEAR_DOWN / BTN_WHEEL and BTN_GEAR_UP
2482 * are passed to the listener.
2483 */
2484static_assert(BTN_GEAR_DOWN == BTN_WHEEL);
2485TEST_F(InputReaderIntegrationTest, SendsGearDownAndUpToInputListener) {
2486 std::unique_ptr<UinputSteamController> controller = createUinputDevice<UinputSteamController>();
2487 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2488 NotifyKeyArgs keyArgs;
2489
2490 controller->pressAndReleaseKey(BTN_GEAR_DOWN);
2491 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
2492 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
2493 ASSERT_EQ(BTN_GEAR_DOWN, keyArgs.scanCode);
2494
2495 controller->pressAndReleaseKey(BTN_GEAR_UP);
2496 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
2497 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
2498 ASSERT_EQ(BTN_GEAR_UP, keyArgs.scanCode);
2499}
2500
Arthur Hungaab25622020-01-16 11:22:11 +08002501// --- TouchProcessTest ---
2502class TouchIntegrationTest : public InputReaderIntegrationTest {
2503protected:
Arthur Hungaab25622020-01-16 11:22:11 +08002504 const std::string UNIQUE_ID = "local:0";
2505
Chris Yea52ade12020-08-27 16:49:20 -07002506 void SetUp() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07002507#if !defined(__ANDROID__)
2508 GTEST_SKIP();
2509#endif
Arthur Hungaab25622020-01-16 11:22:11 +08002510 InputReaderIntegrationTest::SetUp();
2511 // At least add an internal display.
2512 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
2513 DISPLAY_ORIENTATION_0, UNIQUE_ID, NO_PORT,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01002514 ViewportType::INTERNAL);
Arthur Hungaab25622020-01-16 11:22:11 +08002515
2516 mDevice = createUinputDevice<UinputTouchScreen>(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT));
2517 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2518 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
Prabir Pradhanda20b172022-09-26 17:01:18 +00002519 const auto info = findDeviceByName(mDevice->getName());
2520 ASSERT_TRUE(info);
2521 mDeviceInfo = *info;
Arthur Hungaab25622020-01-16 11:22:11 +08002522 }
2523
2524 void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
2525 int32_t orientation, const std::string& uniqueId,
2526 std::optional<uint8_t> physicalPort,
2527 ViewportType viewportType) {
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00002528 mFakePolicy->addDisplayViewport(displayId, width, height, orientation, true /*isActive*/,
2529 uniqueId, physicalPort, viewportType);
Arthur Hungaab25622020-01-16 11:22:11 +08002530 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2531 }
2532
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002533 void assertReceivedMotion(int32_t action, const std::vector<Point>& points) {
2534 NotifyMotionArgs args;
2535 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2536 EXPECT_EQ(action, args.action);
2537 ASSERT_EQ(points.size(), args.pointerCount);
2538 for (size_t i = 0; i < args.pointerCount; i++) {
2539 EXPECT_EQ(points[i].x, args.pointerCoords[i].getX());
2540 EXPECT_EQ(points[i].y, args.pointerCoords[i].getY());
2541 }
2542 }
2543
Arthur Hungaab25622020-01-16 11:22:11 +08002544 std::unique_ptr<UinputTouchScreen> mDevice;
Prabir Pradhanda20b172022-09-26 17:01:18 +00002545 InputDeviceInfo mDeviceInfo;
Arthur Hungaab25622020-01-16 11:22:11 +08002546};
2547
2548TEST_F(TouchIntegrationTest, InputEvent_ProcessSingleTouch) {
2549 NotifyMotionArgs args;
2550 const Point centerPoint = mDevice->getCenterPoint();
2551
2552 // ACTION_DOWN
Arthur Hung9ad18942021-06-19 02:04:46 +00002553 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08002554 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002555 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08002556 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2557 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
2558
2559 // ACTION_MOVE
2560 mDevice->sendMove(centerPoint + Point(1, 1));
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002561 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08002562 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2563 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
2564
2565 // ACTION_UP
2566 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002567 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08002568 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2569 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
2570}
2571
2572TEST_F(TouchIntegrationTest, InputEvent_ProcessMultiTouch) {
2573 NotifyMotionArgs args;
2574 const Point centerPoint = mDevice->getCenterPoint();
2575
2576 // ACTION_DOWN
Arthur Hung9ad18942021-06-19 02:04:46 +00002577 mDevice->sendSlot(FIRST_SLOT);
2578 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08002579 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002580 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08002581 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2582 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
2583
2584 // ACTION_POINTER_DOWN (Second slot)
2585 const Point secondPoint = centerPoint + Point(100, 100);
2586 mDevice->sendSlot(SECOND_SLOT);
2587 mDevice->sendTrackingId(SECOND_TRACKING_ID);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002588 mDevice->sendDown(secondPoint);
2589 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08002590 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08002591 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08002592
2593 // ACTION_MOVE (Second slot)
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002594 mDevice->sendMove(secondPoint + Point(1, 1));
2595 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08002596 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2597 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
2598
2599 // ACTION_POINTER_UP (Second slot)
arthurhungcc7f9802020-04-30 17:55:40 +08002600 mDevice->sendPointerUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002601 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08002602 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08002603 ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08002604
2605 // ACTION_UP
2606 mDevice->sendSlot(FIRST_SLOT);
2607 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002608 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08002609 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2610 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
2611}
2612
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002613/**
2614 * What happens when a pointer goes up while another pointer moves in the same frame? Are POINTER_UP
2615 * events guaranteed to contain the same data as a preceding MOVE, or can they contain different
2616 * data?
2617 * In this test, we try to send a change in coordinates in Pointer 0 in the same frame as the
2618 * liftoff of Pointer 1. We check that POINTER_UP event is generated first, and the MOVE event
2619 * for Pointer 0 only is generated after.
2620 * Suppose we are only interested in learning the movement of Pointer 0. If we only observe MOVE
2621 * events, we will not miss any information.
2622 * Even though the Pointer 1 up event contains updated Pointer 0 coordinates, there is another MOVE
2623 * event generated afterwards that contains the newest movement of pointer 0.
2624 * This is important for palm rejection. If there is a subsequent InputListener stage that detects
2625 * palms, and wants to cancel Pointer 1, then it is safe to simply drop POINTER_1_UP event without
2626 * losing information about non-palm pointers.
2627 */
2628TEST_F(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerUp) {
2629 NotifyMotionArgs args;
2630 const Point centerPoint = mDevice->getCenterPoint();
2631
2632 // ACTION_DOWN
2633 mDevice->sendSlot(FIRST_SLOT);
2634 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2635 mDevice->sendDown(centerPoint);
2636 mDevice->sendSync();
2637 assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
2638
2639 // ACTION_POINTER_DOWN (Second slot)
2640 const Point secondPoint = centerPoint + Point(100, 100);
2641 mDevice->sendSlot(SECOND_SLOT);
2642 mDevice->sendTrackingId(SECOND_TRACKING_ID);
2643 mDevice->sendDown(secondPoint);
2644 mDevice->sendSync();
2645 assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
2646
2647 // ACTION_MOVE (First slot)
2648 mDevice->sendSlot(FIRST_SLOT);
2649 mDevice->sendMove(centerPoint + Point(5, 5));
2650 // ACTION_POINTER_UP (Second slot)
2651 mDevice->sendSlot(SECOND_SLOT);
2652 mDevice->sendPointerUp();
2653 // Send a single sync for the above 2 pointer updates
2654 mDevice->sendSync();
2655
2656 // First, we should get POINTER_UP for the second pointer
2657 assertReceivedMotion(ACTION_POINTER_1_UP,
2658 {/*first pointer */ centerPoint + Point(5, 5),
2659 /*second pointer*/ secondPoint});
2660
2661 // Next, the MOVE event for the first pointer
2662 assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
2663}
2664
2665/**
2666 * Similar scenario as above. The difference is that when the second pointer goes up, it will first
2667 * move, and then it will go up, all in the same frame.
2668 * In this scenario, the movement of the second pointer just prior to liftoff is ignored, and never
2669 * gets sent to the listener.
2670 */
2671TEST_F(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerMoveAndUp) {
2672 NotifyMotionArgs args;
2673 const Point centerPoint = mDevice->getCenterPoint();
2674
2675 // ACTION_DOWN
2676 mDevice->sendSlot(FIRST_SLOT);
2677 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2678 mDevice->sendDown(centerPoint);
2679 mDevice->sendSync();
2680 assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
2681
2682 // ACTION_POINTER_DOWN (Second slot)
2683 const Point secondPoint = centerPoint + Point(100, 100);
2684 mDevice->sendSlot(SECOND_SLOT);
2685 mDevice->sendTrackingId(SECOND_TRACKING_ID);
2686 mDevice->sendDown(secondPoint);
2687 mDevice->sendSync();
2688 assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
2689
2690 // ACTION_MOVE (First slot)
2691 mDevice->sendSlot(FIRST_SLOT);
2692 mDevice->sendMove(centerPoint + Point(5, 5));
2693 // ACTION_POINTER_UP (Second slot)
2694 mDevice->sendSlot(SECOND_SLOT);
2695 mDevice->sendMove(secondPoint + Point(6, 6));
2696 mDevice->sendPointerUp();
2697 // Send a single sync for the above 2 pointer updates
2698 mDevice->sendSync();
2699
2700 // First, we should get POINTER_UP for the second pointer
2701 // The movement of the second pointer during the liftoff frame is ignored.
2702 // The coordinates 'secondPoint + Point(6, 6)' are never sent to the listener.
2703 assertReceivedMotion(ACTION_POINTER_1_UP,
2704 {/*first pointer */ centerPoint + Point(5, 5),
2705 /*second pointer*/ secondPoint});
2706
2707 // Next, the MOVE event for the first pointer
2708 assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
2709}
2710
Arthur Hungaab25622020-01-16 11:22:11 +08002711TEST_F(TouchIntegrationTest, InputEvent_ProcessPalm) {
2712 NotifyMotionArgs args;
2713 const Point centerPoint = mDevice->getCenterPoint();
2714
2715 // ACTION_DOWN
arthurhungcc7f9802020-04-30 17:55:40 +08002716 mDevice->sendSlot(FIRST_SLOT);
2717 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08002718 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002719 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08002720 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2721 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
2722
arthurhungcc7f9802020-04-30 17:55:40 +08002723 // ACTION_POINTER_DOWN (second slot)
Arthur Hungaab25622020-01-16 11:22:11 +08002724 const Point secondPoint = centerPoint + Point(100, 100);
2725 mDevice->sendSlot(SECOND_SLOT);
2726 mDevice->sendTrackingId(SECOND_TRACKING_ID);
2727 mDevice->sendDown(secondPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002728 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08002729 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08002730 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08002731
arthurhungcc7f9802020-04-30 17:55:40 +08002732 // ACTION_MOVE (second slot)
Arthur Hungaab25622020-01-16 11:22:11 +08002733 mDevice->sendMove(secondPoint + Point(1, 1));
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002734 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08002735 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2736 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
2737
arthurhungcc7f9802020-04-30 17:55:40 +08002738 // Send MT_TOOL_PALM (second slot), which indicates that the touch IC has determined this to be
2739 // a palm event.
2740 // Expect to receive the ACTION_POINTER_UP with cancel flag.
Arthur Hungaab25622020-01-16 11:22:11 +08002741 mDevice->sendToolType(MT_TOOL_PALM);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002742 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08002743 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08002744 ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
arthurhungcc7f9802020-04-30 17:55:40 +08002745 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, args.flags);
Arthur Hungaab25622020-01-16 11:22:11 +08002746
arthurhungcc7f9802020-04-30 17:55:40 +08002747 // Send up to second slot, expect first slot send moving.
2748 mDevice->sendPointerUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002749 mDevice->sendSync();
arthurhungcc7f9802020-04-30 17:55:40 +08002750 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2751 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08002752
arthurhungcc7f9802020-04-30 17:55:40 +08002753 // Send ACTION_UP (first slot)
Arthur Hungaab25622020-01-16 11:22:11 +08002754 mDevice->sendSlot(FIRST_SLOT);
2755 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08002756 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08002757
arthurhungcc7f9802020-04-30 17:55:40 +08002758 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2759 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08002760}
2761
Prabir Pradhanda20b172022-09-26 17:01:18 +00002762TEST_F(TouchIntegrationTest, NotifiesPolicyWhenStylusGestureStarted) {
2763 const Point centerPoint = mDevice->getCenterPoint();
2764
2765 // Send down with the pen tool selected. The policy should be notified of the stylus presence.
2766 mDevice->sendSlot(FIRST_SLOT);
2767 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2768 mDevice->sendToolType(MT_TOOL_PEN);
2769 mDevice->sendDown(centerPoint);
2770 mDevice->sendSync();
2771 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2772 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2773 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
2774
2775 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
2776
2777 // Release the stylus touch.
2778 mDevice->sendUp();
2779 mDevice->sendSync();
2780 ASSERT_NO_FATAL_FAILURE(
2781 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
2782
2783 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
2784
2785 // Touch down with the finger, without the pen tool selected. The policy is not notified.
2786 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2787 mDevice->sendToolType(MT_TOOL_FINGER);
2788 mDevice->sendDown(centerPoint);
2789 mDevice->sendSync();
2790 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2791 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2792 WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))));
2793
2794 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
2795
2796 mDevice->sendUp();
2797 mDevice->sendSync();
2798 ASSERT_NO_FATAL_FAILURE(
2799 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
2800
2801 // Send a move event with the stylus tool without BTN_TOUCH to generate a hover enter.
2802 // The policy should be notified of the stylus presence.
2803 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2804 mDevice->sendToolType(MT_TOOL_PEN);
2805 mDevice->sendMove(centerPoint);
2806 mDevice->sendSync();
2807 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2808 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
2809 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
2810
2811 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
2812}
2813
Prabir Pradhane1a41a82022-10-14 18:06:50 +00002814TEST_F(TouchIntegrationTest, StylusButtonsGenerateKeyEvents) {
2815 mDevice->sendKey(BTN_STYLUS, 1);
2816 mDevice->sendSync();
2817 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
2818 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
2819 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
2820
2821 mDevice->sendKey(BTN_STYLUS, 0);
2822 mDevice->sendSync();
2823 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
2824 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
2825 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
2826}
2827
Michael Wrightd02c5b62014-02-10 15:10:22 -08002828// --- InputDeviceTest ---
Michael Wrightd02c5b62014-02-10 15:10:22 -08002829class InputDeviceTest : public testing::Test {
2830protected:
2831 static const char* DEVICE_NAME;
Arthur Hung2c9a3342019-07-23 14:18:59 +08002832 static const char* DEVICE_LOCATION;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002833 static const int32_t DEVICE_ID;
2834 static const int32_t DEVICE_GENERATION;
2835 static const int32_t DEVICE_CONTROLLER_NUMBER;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002836 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002837 static const int32_t EVENTHUB_ID;
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00002838 static const std::string DEVICE_BLUETOOTH_ADDRESS;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002839
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07002840 std::shared_ptr<FakeEventHub> mFakeEventHub;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002841 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002842 std::unique_ptr<TestInputListener> mFakeListener;
arthurhungdcef2dc2020-08-11 14:47:50 +08002843 std::unique_ptr<InstrumentedInputReader> mReader;
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +00002844 std::shared_ptr<InputDevice> mDevice;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002845
Chris Yea52ade12020-08-27 16:49:20 -07002846 void SetUp() override {
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07002847 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07002848 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002849 mFakeListener = std::make_unique<TestInputListener>();
arthurhungdcef2dc2020-08-11 14:47:50 +08002850 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002851 *mFakeListener);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002852 InputDeviceIdentifier identifier;
2853 identifier.name = DEVICE_NAME;
Arthur Hung2c9a3342019-07-23 14:18:59 +08002854 identifier.location = DEVICE_LOCATION;
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00002855 identifier.bluetoothAddress = DEVICE_BLUETOOTH_ADDRESS;
arthurhungdcef2dc2020-08-11 14:47:50 +08002856 mDevice = std::make_shared<InputDevice>(mReader->getContext(), DEVICE_ID, DEVICE_GENERATION,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002857 identifier);
arthurhungdcef2dc2020-08-11 14:47:50 +08002858 mReader->pushNextDevice(mDevice);
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002859 mFakeEventHub->addDevice(EVENTHUB_ID, DEVICE_NAME, ftl::Flags<InputDeviceClass>(0));
arthurhungdcef2dc2020-08-11 14:47:50 +08002860 mReader->loopOnce();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002861 }
2862
Chris Yea52ade12020-08-27 16:49:20 -07002863 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002864 mFakeListener.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002865 mFakePolicy.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002866 }
2867};
2868
2869const char* InputDeviceTest::DEVICE_NAME = "device";
Arthur Hung2c9a3342019-07-23 14:18:59 +08002870const char* InputDeviceTest::DEVICE_LOCATION = "USB1";
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002871const int32_t InputDeviceTest::DEVICE_ID = END_RESERVED_ID + 1000;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002872const int32_t InputDeviceTest::DEVICE_GENERATION = 2;
2873const int32_t InputDeviceTest::DEVICE_CONTROLLER_NUMBER = 0;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002874const ftl::Flags<InputDeviceClass> InputDeviceTest::DEVICE_CLASSES =
Chris Ye1b0c7342020-07-28 21:57:03 -07002875 InputDeviceClass::KEYBOARD | InputDeviceClass::TOUCH | InputDeviceClass::JOYSTICK;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002876const int32_t InputDeviceTest::EVENTHUB_ID = 1;
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00002877const std::string InputDeviceTest::DEVICE_BLUETOOTH_ADDRESS = "11:AA:22:BB:33:CC";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002878
2879TEST_F(InputDeviceTest, ImmutableProperties) {
2880 ASSERT_EQ(DEVICE_ID, mDevice->getId());
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01002881 ASSERT_STREQ(DEVICE_NAME, mDevice->getName().c_str());
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002882 ASSERT_EQ(ftl::Flags<InputDeviceClass>(0), mDevice->getClasses());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002883}
2884
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +00002885TEST_F(InputDeviceTest, CountryCodeCorrectlyMapped) {
2886 mFakeEventHub->setCountryCode(EVENTHUB_ID, InputDeviceCountryCode::INTERNATIONAL);
2887
2888 // Configuration
2889 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
2890 InputReaderConfiguration config;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002891 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +00002892
2893 ASSERT_EQ(InputDeviceCountryCode::INTERNATIONAL, mDevice->getDeviceInfo().getCountryCode());
2894}
2895
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002896TEST_F(InputDeviceTest, WhenDeviceCreated_EnabledIsFalse) {
2897 ASSERT_EQ(mDevice->isEnabled(), false);
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07002898}
2899
Michael Wrightd02c5b62014-02-10 15:10:22 -08002900TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
2901 // Configuration.
2902 InputReaderConfiguration config;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002903 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002904
2905 // Reset.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002906 unused += mDevice->reset(ARBITRARY_TIME);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002907
2908 NotifyDeviceResetArgs resetArgs;
2909 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2910 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
2911 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
2912
2913 // Metadata.
2914 ASSERT_TRUE(mDevice->isIgnored());
2915 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mDevice->getSources());
2916
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00002917 InputDeviceInfo info = mDevice->getDeviceInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002918 ASSERT_EQ(DEVICE_ID, info.getId());
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01002919 ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002920 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType());
2921 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources());
2922
2923 // State queries.
2924 ASSERT_EQ(0, mDevice->getMetaState());
2925
2926 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, 0))
2927 << "Ignored device should return unknown key code state.";
2928 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 0))
2929 << "Ignored device should return unknown scan code state.";
2930 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 0))
2931 << "Ignored device should return unknown switch state.";
2932
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002933 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B};
Michael Wrightd02c5b62014-02-10 15:10:22 -08002934 uint8_t flags[2] = { 0, 1 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002935 ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -08002936 << "Ignored device should never mark any key codes.";
2937 ASSERT_EQ(0, flags[0]) << "Flag for unsupported key should be unchanged.";
2938 ASSERT_EQ(1, flags[1]) << "Flag for unsupported key should be unchanged.";
2939}
2940
2941TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) {
2942 // Configuration.
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002943 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "key", "value");
Michael Wrightd02c5b62014-02-10 15:10:22 -08002944
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002945 FakeInputMapper& mapper1 =
2946 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002947 mapper1.setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC);
2948 mapper1.setMetaState(AMETA_ALT_ON);
2949 mapper1.addSupportedKeyCode(AKEYCODE_A);
2950 mapper1.addSupportedKeyCode(AKEYCODE_B);
2951 mapper1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
2952 mapper1.setKeyCodeState(AKEYCODE_B, AKEY_STATE_UP);
2953 mapper1.setScanCodeState(2, AKEY_STATE_DOWN);
2954 mapper1.setScanCodeState(3, AKEY_STATE_UP);
2955 mapper1.setSwitchState(4, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002956
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002957 FakeInputMapper& mapper2 =
2958 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_TOUCHSCREEN);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002959 mapper2.setMetaState(AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002960
2961 InputReaderConfiguration config;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002962 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002963
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002964 std::string propertyValue;
2965 ASSERT_TRUE(mDevice->getConfiguration().tryGetProperty("key", propertyValue))
Michael Wrightd02c5b62014-02-10 15:10:22 -08002966 << "Device should have read configuration during configuration phase.";
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002967 ASSERT_EQ("value", propertyValue);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002968
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002969 ASSERT_NO_FATAL_FAILURE(mapper1.assertConfigureWasCalled());
2970 ASSERT_NO_FATAL_FAILURE(mapper2.assertConfigureWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002971
2972 // Reset
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002973 unused += mDevice->reset(ARBITRARY_TIME);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002974 ASSERT_NO_FATAL_FAILURE(mapper1.assertResetWasCalled());
2975 ASSERT_NO_FATAL_FAILURE(mapper2.assertResetWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002976
2977 NotifyDeviceResetArgs resetArgs;
2978 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2979 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
2980 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
2981
2982 // Metadata.
2983 ASSERT_FALSE(mDevice->isIgnored());
2984 ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), mDevice->getSources());
2985
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00002986 InputDeviceInfo info = mDevice->getDeviceInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002987 ASSERT_EQ(DEVICE_ID, info.getId());
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01002988 ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002989 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType());
2990 ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources());
2991
2992 // State queries.
2993 ASSERT_EQ(AMETA_ALT_ON | AMETA_SHIFT_ON, mDevice->getMetaState())
2994 << "Should query mappers and combine meta states.";
2995
2996 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2997 << "Should return unknown key code state when source not supported.";
2998 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2999 << "Should return unknown scan code state when source not supported.";
3000 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
3001 << "Should return unknown switch state when source not supported.";
3002
3003 ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, AKEYCODE_A))
3004 << "Should query mapper when source is supported.";
3005 ASSERT_EQ(AKEY_STATE_UP, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 3))
3006 << "Should query mapper when source is supported.";
3007 ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 4))
3008 << "Should query mapper when source is supported.";
3009
Siarhei Vishniakou74007942022-06-13 13:57:47 -07003010 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2};
Michael Wrightd02c5b62014-02-10 15:10:22 -08003011 uint8_t flags[4] = { 0, 0, 0, 1 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07003012 ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -08003013 << "Should do nothing when source is unsupported.";
3014 ASSERT_EQ(0, flags[0]) << "Flag should be unchanged when source is unsupported.";
3015 ASSERT_EQ(0, flags[1]) << "Flag should be unchanged when source is unsupported.";
3016 ASSERT_EQ(0, flags[2]) << "Flag should be unchanged when source is unsupported.";
3017 ASSERT_EQ(1, flags[3]) << "Flag should be unchanged when source is unsupported.";
3018
Siarhei Vishniakou74007942022-06-13 13:57:47 -07003019 ASSERT_TRUE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -08003020 << "Should query mapper when source is supported.";
3021 ASSERT_EQ(1, flags[0]) << "Flag for supported key should be set.";
3022 ASSERT_EQ(1, flags[1]) << "Flag for supported key should be set.";
3023 ASSERT_EQ(0, flags[2]) << "Flag for unsupported key should be unchanged.";
3024 ASSERT_EQ(1, flags[3]) << "Flag for unsupported key should be unchanged.";
3025
3026 // Event handling.
3027 RawEvent event;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003028 event.deviceId = EVENTHUB_ID;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003029 unused += mDevice->process(&event, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003030
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003031 ASSERT_NO_FATAL_FAILURE(mapper1.assertProcessWasCalled());
3032 ASSERT_NO_FATAL_FAILURE(mapper2.assertProcessWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003033}
3034
Arthur Hung2c9a3342019-07-23 14:18:59 +08003035// A single input device is associated with a specific display. Check that:
3036// 1. Device is disabled if the viewport corresponding to the associated display is not found
3037// 2. Device is disabled when setEnabled API is called
3038TEST_F(InputDeviceTest, Configure_AssignsDisplayPort) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003039 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_TOUCHSCREEN);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003040
3041 // First Configuration.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003042 std::list<NotifyArgs> unused =
3043 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003044
3045 // Device should be enabled by default.
3046 ASSERT_TRUE(mDevice->isEnabled());
3047
3048 // Prepare associated info.
3049 constexpr uint8_t hdmi = 1;
3050 const std::string UNIQUE_ID = "local:1";
3051
3052 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003053 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3054 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003055 // Device should be disabled because it is associated with a specific display via
3056 // input port <-> display port association, but the corresponding display is not found
3057 ASSERT_FALSE(mDevice->isEnabled());
3058
3059 // Prepare displays.
3060 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00003061 DISPLAY_ORIENTATION_0, true /*isActive*/, UNIQUE_ID, hdmi,
3062 ViewportType::INTERNAL);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003063 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3064 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003065 ASSERT_TRUE(mDevice->isEnabled());
3066
3067 // Device should be disabled after set disable.
3068 mFakePolicy->addDisabledDevice(mDevice->getId());
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003069 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3070 InputReaderConfiguration::CHANGE_ENABLED_STATE);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003071 ASSERT_FALSE(mDevice->isEnabled());
3072
3073 // Device should still be disabled even found the associated display.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003074 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3075 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003076 ASSERT_FALSE(mDevice->isEnabled());
3077}
Michael Wrightd02c5b62014-02-10 15:10:22 -08003078
Christine Franks1ba71cc2021-04-07 14:37:42 -07003079TEST_F(InputDeviceTest, Configure_AssignsDisplayUniqueId) {
3080 // Device should be enabled by default.
3081 mFakePolicy->clearViewports();
3082 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003083 std::list<NotifyArgs> unused =
3084 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
Christine Franks1ba71cc2021-04-07 14:37:42 -07003085 ASSERT_TRUE(mDevice->isEnabled());
3086
3087 // Device should be disabled because it is associated with a specific display, but the
3088 // corresponding display is not found.
Christine Franks2a2293c2022-01-18 11:51:16 -08003089 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003090 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3091 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Christine Franks1ba71cc2021-04-07 14:37:42 -07003092 ASSERT_FALSE(mDevice->isEnabled());
3093
3094 // Device should be enabled when a display is found.
3095 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
3096 DISPLAY_ORIENTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID,
3097 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003098 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3099 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Christine Franks1ba71cc2021-04-07 14:37:42 -07003100 ASSERT_TRUE(mDevice->isEnabled());
3101
3102 // Device should be disabled after set disable.
3103 mFakePolicy->addDisabledDevice(mDevice->getId());
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003104 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3105 InputReaderConfiguration::CHANGE_ENABLED_STATE);
Christine Franks1ba71cc2021-04-07 14:37:42 -07003106 ASSERT_FALSE(mDevice->isEnabled());
3107
3108 // Device should still be disabled even found the associated display.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003109 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3110 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Christine Franks1ba71cc2021-04-07 14:37:42 -07003111 ASSERT_FALSE(mDevice->isEnabled());
3112}
3113
Christine Franks2a2293c2022-01-18 11:51:16 -08003114TEST_F(InputDeviceTest, Configure_UniqueId_CorrectlyMatches) {
3115 mFakePolicy->clearViewports();
3116 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003117 std::list<NotifyArgs> unused =
3118 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
Christine Franks2a2293c2022-01-18 11:51:16 -08003119
Christine Franks2a2293c2022-01-18 11:51:16 -08003120 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
3121 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
3122 DISPLAY_ORIENTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID,
3123 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003124 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3125 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Christine Franks2a2293c2022-01-18 11:51:16 -08003126 ASSERT_EQ(DISPLAY_UNIQUE_ID, mDevice->getAssociatedDisplayUniqueId());
3127}
3128
Siarhei Vishniakou30feb8c2022-09-28 10:48:29 -07003129/**
3130 * This test reproduces a crash caused by a dangling reference that remains after device is added
3131 * and removed. The reference is accessed in InputDevice::dump(..);
3132 */
3133TEST_F(InputDeviceTest, DumpDoesNotCrash) {
3134 constexpr int32_t TEST_EVENTHUB_ID = 10;
3135 mFakeEventHub->addDevice(TEST_EVENTHUB_ID, "Test EventHub device", InputDeviceClass::BATTERY);
3136
3137 InputDevice device(mReader->getContext(), 1 /*id*/, 2 /*generation*/, {} /*identifier*/);
3138 device.addEventHubDevice(TEST_EVENTHUB_ID, true /*populateMappers*/);
3139 device.removeEventHubDevice(TEST_EVENTHUB_ID);
3140 std::string dumpStr, eventHubDevStr;
3141 device.dump(dumpStr, eventHubDevStr);
3142}
3143
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00003144TEST_F(InputDeviceTest, GetBluetoothAddress) {
3145 const auto& address = mReader->getBluetoothAddress(DEVICE_ID);
3146 ASSERT_TRUE(address);
3147 ASSERT_EQ(DEVICE_BLUETOOTH_ADDRESS, *address);
3148}
3149
Michael Wrightd02c5b62014-02-10 15:10:22 -08003150// --- InputMapperTest ---
3151
3152class InputMapperTest : public testing::Test {
3153protected:
3154 static const char* DEVICE_NAME;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07003155 static const char* DEVICE_LOCATION;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003156 static const int32_t DEVICE_ID;
3157 static const int32_t DEVICE_GENERATION;
3158 static const int32_t DEVICE_CONTROLLER_NUMBER;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07003159 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003160 static const int32_t EVENTHUB_ID;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003161
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07003162 std::shared_ptr<FakeEventHub> mFakeEventHub;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003163 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -07003164 std::unique_ptr<TestInputListener> mFakeListener;
arthurhungdcef2dc2020-08-11 14:47:50 +08003165 std::unique_ptr<InstrumentedInputReader> mReader;
3166 std::shared_ptr<InputDevice> mDevice;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003167
Dominik Laskowski2f01d772022-03-23 16:01:29 -07003168 virtual void SetUp(ftl::Flags<InputDeviceClass> classes) {
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07003169 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07003170 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -07003171 mFakeListener = std::make_unique<TestInputListener>();
arthurhungdcef2dc2020-08-11 14:47:50 +08003172 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -07003173 *mFakeListener);
arthurhungdcef2dc2020-08-11 14:47:50 +08003174 mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes);
Prabir Pradhanb5174de2022-08-05 22:26:56 +00003175 // Consume the device reset notification generated when adding a new device.
3176 mFakeListener->assertNotifyDeviceResetWasCalled();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003177 }
3178
Prabir Pradhanc14266f2021-05-12 15:56:24 -07003179 void SetUp() override {
Prabir Pradhanc14266f2021-05-12 15:56:24 -07003180 SetUp(DEVICE_CLASSES);
3181 }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003182
Chris Yea52ade12020-08-27 16:49:20 -07003183 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -07003184 mFakeListener.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003185 mFakePolicy.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003186 }
3187
3188 void addConfigurationProperty(const char* key, const char* value) {
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07003189 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, key, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003190 }
3191
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003192 std::list<NotifyArgs> configureDevice(uint32_t changes) {
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00003193 if (!changes ||
3194 (changes &
3195 (InputReaderConfiguration::CHANGE_DISPLAY_INFO |
3196 InputReaderConfiguration::CHANGE_POINTER_CAPTURE))) {
arthurhungdcef2dc2020-08-11 14:47:50 +08003197 mReader->requestRefreshConfiguration(changes);
3198 mReader->loopOnce();
Prabir Pradhanc7ef27e2020-02-03 19:19:15 -08003199 }
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003200 std::list<NotifyArgs> out =
3201 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes);
Prabir Pradhanb5174de2022-08-05 22:26:56 +00003202 // Loop the reader to flush the input listener queue.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003203 for (const NotifyArgs& args : out) {
3204 mFakeListener->notify(args);
3205 }
Prabir Pradhanb5174de2022-08-05 22:26:56 +00003206 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003207 return out;
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08003208 }
3209
arthurhungdcef2dc2020-08-11 14:47:50 +08003210 std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
3211 const std::string& location, int32_t eventHubId,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07003212 ftl::Flags<InputDeviceClass> classes) {
arthurhungdcef2dc2020-08-11 14:47:50 +08003213 InputDeviceIdentifier identifier;
3214 identifier.name = name;
3215 identifier.location = location;
3216 std::shared_ptr<InputDevice> device =
3217 std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
3218 identifier);
3219 mReader->pushNextDevice(device);
3220 mFakeEventHub->addDevice(eventHubId, name, classes);
3221 mReader->loopOnce();
3222 return device;
3223 }
3224
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003225 template <class T, typename... Args>
3226 T& addMapperAndConfigure(Args... args) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003227 T& mapper = mDevice->addMapper<T>(EVENTHUB_ID, args...);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08003228 configureDevice(0);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003229 std::list<NotifyArgs> resetArgList = mDevice->reset(ARBITRARY_TIME);
3230 resetArgList += mapper.reset(ARBITRARY_TIME);
Prabir Pradhanb5174de2022-08-05 22:26:56 +00003231 // Loop the reader to flush the input listener queue.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003232 for (const NotifyArgs& loopArgs : resetArgList) {
3233 mFakeListener->notify(loopArgs);
3234 }
Prabir Pradhanb5174de2022-08-05 22:26:56 +00003235 mReader->loopOnce();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003236 return mapper;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003237 }
3238
3239 void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07003240 int32_t orientation, const std::string& uniqueId,
3241 std::optional<uint8_t> physicalPort, ViewportType viewportType) {
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00003242 mFakePolicy->addDisplayViewport(displayId, width, height, orientation, true /*isActive*/,
3243 uniqueId, physicalPort, viewportType);
Santos Cordonfa5cf462017-04-05 10:37:00 -07003244 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
3245 }
3246
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003247 void clearViewports() {
3248 mFakePolicy->clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003249 }
3250
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003251 std::list<NotifyArgs> process(InputMapper& mapper, nsecs_t when, nsecs_t readTime, int32_t type,
3252 int32_t code, int32_t value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003253 RawEvent event;
3254 event.when = when;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003255 event.readTime = readTime;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003256 event.deviceId = mapper.getDeviceContext().getEventHubId();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003257 event.type = type;
3258 event.code = code;
3259 event.value = value;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003260 std::list<NotifyArgs> processArgList = mapper.process(&event);
3261 for (const NotifyArgs& args : processArgList) {
3262 mFakeListener->notify(args);
3263 }
Prabir Pradhanb5174de2022-08-05 22:26:56 +00003264 // Loop the reader to flush the input listener queue.
arthurhungdcef2dc2020-08-11 14:47:50 +08003265 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003266 return processArgList;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003267 }
3268
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00003269 void resetMapper(InputMapper& mapper, nsecs_t when) {
3270 const auto resetArgs = mapper.reset(when);
3271 for (const auto args : resetArgs) {
3272 mFakeListener->notify(args);
3273 }
3274 // Loop the reader to flush the input listener queue.
3275 mReader->loopOnce();
3276 }
3277
Michael Wrightd02c5b62014-02-10 15:10:22 -08003278 static void assertMotionRange(const InputDeviceInfo& info,
3279 int32_t axis, uint32_t source, float min, float max, float flat, float fuzz) {
3280 const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source);
Yi Kong9b14ac62018-07-17 13:48:38 -07003281 ASSERT_TRUE(range != nullptr) << "Axis: " << axis << " Source: " << source;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003282 ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source;
3283 ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source;
3284 ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source;
3285 ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source;
3286 ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source;
3287 ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source;
3288 }
3289
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003290 static void assertPointerCoords(const PointerCoords& coords, float x, float y, float pressure,
3291 float size, float touchMajor, float touchMinor, float toolMajor,
3292 float toolMinor, float orientation, float distance,
3293 float scaledAxisEpsilon = 1.f) {
3294 ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), scaledAxisEpsilon);
3295 ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), scaledAxisEpsilon);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003296 ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON);
3297 ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003298 ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3299 scaledAxisEpsilon);
3300 ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3301 scaledAxisEpsilon);
3302 ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3303 scaledAxisEpsilon);
3304 ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3305 scaledAxisEpsilon);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003306 ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON);
3307 ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON);
3308 }
3309
Michael Wright17db18e2020-06-26 20:51:44 +01003310 static void assertPosition(const FakePointerController& controller, float x, float y) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003311 float actualX, actualY;
Michael Wright17db18e2020-06-26 20:51:44 +01003312 controller.getPosition(&actualX, &actualY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003313 ASSERT_NEAR(x, actualX, 1);
3314 ASSERT_NEAR(y, actualY, 1);
3315 }
3316};
3317
3318const char* InputMapperTest::DEVICE_NAME = "device";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07003319const char* InputMapperTest::DEVICE_LOCATION = "USB1";
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003320const int32_t InputMapperTest::DEVICE_ID = END_RESERVED_ID + 1000;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003321const int32_t InputMapperTest::DEVICE_GENERATION = 2;
3322const int32_t InputMapperTest::DEVICE_CONTROLLER_NUMBER = 0;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07003323const ftl::Flags<InputDeviceClass> InputMapperTest::DEVICE_CLASSES =
3324 ftl::Flags<InputDeviceClass>(0); // not needed for current tests
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003325const int32_t InputMapperTest::EVENTHUB_ID = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003326
3327// --- SwitchInputMapperTest ---
3328
3329class SwitchInputMapperTest : public InputMapperTest {
3330protected:
3331};
3332
3333TEST_F(SwitchInputMapperTest, GetSources) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003334 SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003335
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003336 ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003337}
3338
3339TEST_F(SwitchInputMapperTest, GetSwitchState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003340 SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003341
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003342 mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003343 ASSERT_EQ(1, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003344
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003345 mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003346 ASSERT_EQ(0, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003347}
3348
3349TEST_F(SwitchInputMapperTest, Process) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003350 SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003351 std::list<NotifyArgs> out;
3352 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_LID, 1);
3353 ASSERT_TRUE(out.empty());
3354 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_JACK_PHYSICAL_INSERT, 1);
3355 ASSERT_TRUE(out.empty());
3356 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_HEADPHONE_INSERT, 0);
3357 ASSERT_TRUE(out.empty());
3358 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003359
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003360 ASSERT_EQ(1u, out.size());
3361 const NotifySwitchArgs& args = std::get<NotifySwitchArgs>(*out.begin());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003362 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
Dan Albert1bd2fc02016-02-02 15:11:57 -08003363 ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT), args.switchValues);
3364 ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT) | (1 << SW_HEADPHONE_INSERT),
Michael Wrightd02c5b62014-02-10 15:10:22 -08003365 args.switchMask);
3366 ASSERT_EQ(uint32_t(0), args.policyFlags);
3367}
3368
Chris Ye87143712020-11-10 05:05:58 +00003369// --- VibratorInputMapperTest ---
3370class VibratorInputMapperTest : public InputMapperTest {
3371protected:
3372 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::VIBRATOR); }
3373};
3374
3375TEST_F(VibratorInputMapperTest, GetSources) {
3376 VibratorInputMapper& mapper = addMapperAndConfigure<VibratorInputMapper>();
3377
3378 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mapper.getSources());
3379}
3380
3381TEST_F(VibratorInputMapperTest, GetVibratorIds) {
3382 VibratorInputMapper& mapper = addMapperAndConfigure<VibratorInputMapper>();
3383
3384 ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
3385}
3386
3387TEST_F(VibratorInputMapperTest, Vibrate) {
3388 constexpr uint8_t DEFAULT_AMPLITUDE = 192;
Chris Yefb552902021-02-03 17:18:37 -08003389 constexpr int32_t VIBRATION_TOKEN = 100;
Chris Ye87143712020-11-10 05:05:58 +00003390 VibratorInputMapper& mapper = addMapperAndConfigure<VibratorInputMapper>();
3391
3392 VibrationElement pattern(2);
3393 VibrationSequence sequence(2);
3394 pattern.duration = std::chrono::milliseconds(200);
3395 pattern.channels = {{0 /* vibratorId */, DEFAULT_AMPLITUDE / 2},
3396 {1 /* vibratorId */, DEFAULT_AMPLITUDE}};
3397 sequence.addElement(pattern);
3398 pattern.duration = std::chrono::milliseconds(500);
3399 pattern.channels = {{0 /* vibratorId */, DEFAULT_AMPLITUDE / 4},
3400 {1 /* vibratorId */, DEFAULT_AMPLITUDE}};
3401 sequence.addElement(pattern);
3402
3403 std::vector<int64_t> timings = {0, 1};
3404 std::vector<uint8_t> amplitudes = {DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE / 2};
3405
3406 ASSERT_FALSE(mapper.isVibrating());
Chris Yefb552902021-02-03 17:18:37 -08003407 // Start vibrating
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003408 std::list<NotifyArgs> out = mapper.vibrate(sequence, -1 /* repeat */, VIBRATION_TOKEN);
Chris Ye87143712020-11-10 05:05:58 +00003409 ASSERT_TRUE(mapper.isVibrating());
Chris Yefb552902021-02-03 17:18:37 -08003410 // Verify vibrator state listener was notified.
3411 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003412 ASSERT_EQ(1u, out.size());
3413 const NotifyVibratorStateArgs& vibrateArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
3414 ASSERT_EQ(DEVICE_ID, vibrateArgs.deviceId);
3415 ASSERT_TRUE(vibrateArgs.isOn);
Chris Yefb552902021-02-03 17:18:37 -08003416 // Stop vibrating
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003417 out = mapper.cancelVibrate(VIBRATION_TOKEN);
Chris Yefb552902021-02-03 17:18:37 -08003418 ASSERT_FALSE(mapper.isVibrating());
3419 // Verify vibrator state listener was notified.
3420 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003421 ASSERT_EQ(1u, out.size());
3422 const NotifyVibratorStateArgs& cancelArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
3423 ASSERT_EQ(DEVICE_ID, cancelArgs.deviceId);
3424 ASSERT_FALSE(cancelArgs.isOn);
Chris Ye87143712020-11-10 05:05:58 +00003425}
Michael Wrightd02c5b62014-02-10 15:10:22 -08003426
Chris Yef59a2f42020-10-16 12:55:26 -07003427// --- SensorInputMapperTest ---
3428
3429class SensorInputMapperTest : public InputMapperTest {
3430protected:
3431 static const int32_t ACCEL_RAW_MIN;
3432 static const int32_t ACCEL_RAW_MAX;
3433 static const int32_t ACCEL_RAW_FUZZ;
3434 static const int32_t ACCEL_RAW_FLAT;
3435 static const int32_t ACCEL_RAW_RESOLUTION;
3436
3437 static const int32_t GYRO_RAW_MIN;
3438 static const int32_t GYRO_RAW_MAX;
3439 static const int32_t GYRO_RAW_FUZZ;
3440 static const int32_t GYRO_RAW_FLAT;
3441 static const int32_t GYRO_RAW_RESOLUTION;
3442
3443 static const float GRAVITY_MS2_UNIT;
3444 static const float DEGREE_RADIAN_UNIT;
3445
3446 void prepareAccelAxes();
3447 void prepareGyroAxes();
3448 void setAccelProperties();
3449 void setGyroProperties();
3450 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::SENSOR); }
3451};
3452
3453const int32_t SensorInputMapperTest::ACCEL_RAW_MIN = -32768;
3454const int32_t SensorInputMapperTest::ACCEL_RAW_MAX = 32768;
3455const int32_t SensorInputMapperTest::ACCEL_RAW_FUZZ = 16;
3456const int32_t SensorInputMapperTest::ACCEL_RAW_FLAT = 0;
3457const int32_t SensorInputMapperTest::ACCEL_RAW_RESOLUTION = 8192;
3458
3459const int32_t SensorInputMapperTest::GYRO_RAW_MIN = -2097152;
3460const int32_t SensorInputMapperTest::GYRO_RAW_MAX = 2097152;
3461const int32_t SensorInputMapperTest::GYRO_RAW_FUZZ = 16;
3462const int32_t SensorInputMapperTest::GYRO_RAW_FLAT = 0;
3463const int32_t SensorInputMapperTest::GYRO_RAW_RESOLUTION = 1024;
3464
3465const float SensorInputMapperTest::GRAVITY_MS2_UNIT = 9.80665f;
3466const float SensorInputMapperTest::DEGREE_RADIAN_UNIT = 0.0174533f;
3467
3468void SensorInputMapperTest::prepareAccelAxes() {
3469 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
3470 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
3471 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
3472 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
3473 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Z, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
3474 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
3475}
3476
3477void SensorInputMapperTest::prepareGyroAxes() {
3478 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RX, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
3479 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
3480 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RY, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
3481 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
3482 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RZ, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
3483 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
3484}
3485
3486void SensorInputMapperTest::setAccelProperties() {
3487 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 0, InputDeviceSensorType::ACCELEROMETER,
3488 /* sensorDataIndex */ 0);
3489 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 1, InputDeviceSensorType::ACCELEROMETER,
3490 /* sensorDataIndex */ 1);
3491 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 2, InputDeviceSensorType::ACCELEROMETER,
3492 /* sensorDataIndex */ 2);
3493 mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP);
3494 addConfigurationProperty("sensor.accelerometer.reportingMode", "0");
3495 addConfigurationProperty("sensor.accelerometer.maxDelay", "100000");
3496 addConfigurationProperty("sensor.accelerometer.minDelay", "5000");
3497 addConfigurationProperty("sensor.accelerometer.power", "1.5");
3498}
3499
3500void SensorInputMapperTest::setGyroProperties() {
3501 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 3, InputDeviceSensorType::GYROSCOPE,
3502 /* sensorDataIndex */ 0);
3503 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 4, InputDeviceSensorType::GYROSCOPE,
3504 /* sensorDataIndex */ 1);
3505 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 5, InputDeviceSensorType::GYROSCOPE,
3506 /* sensorDataIndex */ 2);
3507 mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP);
3508 addConfigurationProperty("sensor.gyroscope.reportingMode", "0");
3509 addConfigurationProperty("sensor.gyroscope.maxDelay", "100000");
3510 addConfigurationProperty("sensor.gyroscope.minDelay", "5000");
3511 addConfigurationProperty("sensor.gyroscope.power", "0.8");
3512}
3513
3514TEST_F(SensorInputMapperTest, GetSources) {
3515 SensorInputMapper& mapper = addMapperAndConfigure<SensorInputMapper>();
3516
3517 ASSERT_EQ(static_cast<uint32_t>(AINPUT_SOURCE_SENSOR), mapper.getSources());
3518}
3519
3520TEST_F(SensorInputMapperTest, ProcessAccelerometerSensor) {
3521 setAccelProperties();
3522 prepareAccelAxes();
3523 SensorInputMapper& mapper = addMapperAndConfigure<SensorInputMapper>();
3524
3525 ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::ACCELEROMETER,
3526 std::chrono::microseconds(10000),
3527 std::chrono::microseconds(0)));
Chris Yee14523a2020-12-19 13:46:00 -08003528 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003529 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, 20000);
3530 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, -20000);
3531 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Z, 40000);
3532 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
3533 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Chris Yef59a2f42020-10-16 12:55:26 -07003534
3535 NotifySensorArgs args;
3536 std::vector<float> values = {20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT,
3537 -20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT,
3538 40000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT};
3539
3540 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args));
3541 ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR);
3542 ASSERT_EQ(args.deviceId, DEVICE_ID);
3543 ASSERT_EQ(args.sensorType, InputDeviceSensorType::ACCELEROMETER);
3544 ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
3545 ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME);
3546 ASSERT_EQ(args.values, values);
3547 mapper.flushSensor(InputDeviceSensorType::ACCELEROMETER);
3548}
3549
3550TEST_F(SensorInputMapperTest, ProcessGyroscopeSensor) {
3551 setGyroProperties();
3552 prepareGyroAxes();
3553 SensorInputMapper& mapper = addMapperAndConfigure<SensorInputMapper>();
3554
3555 ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::GYROSCOPE,
3556 std::chrono::microseconds(10000),
3557 std::chrono::microseconds(0)));
Chris Yee14523a2020-12-19 13:46:00 -08003558 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003559 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RX, 20000);
3560 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RY, -20000);
3561 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RZ, 40000);
3562 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
3563 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Chris Yef59a2f42020-10-16 12:55:26 -07003564
3565 NotifySensorArgs args;
3566 std::vector<float> values = {20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT,
3567 -20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT,
3568 40000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT};
3569
3570 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args));
3571 ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR);
3572 ASSERT_EQ(args.deviceId, DEVICE_ID);
3573 ASSERT_EQ(args.sensorType, InputDeviceSensorType::GYROSCOPE);
3574 ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
3575 ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME);
3576 ASSERT_EQ(args.values, values);
3577 mapper.flushSensor(InputDeviceSensorType::GYROSCOPE);
3578}
3579
Michael Wrightd02c5b62014-02-10 15:10:22 -08003580// --- KeyboardInputMapperTest ---
3581
3582class KeyboardInputMapperTest : public InputMapperTest {
3583protected:
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003584 const std::string UNIQUE_ID = "local:0";
3585
3586 void prepareDisplay(int32_t orientation);
3587
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003588 void testDPadKeyRotation(KeyboardInputMapper& mapper, int32_t originalScanCode,
Arthur Hung2c9a3342019-07-23 14:18:59 +08003589 int32_t originalKeyCode, int32_t rotatedKeyCode,
3590 int32_t displayId = ADISPLAY_ID_NONE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003591};
3592
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003593/* Similar to setDisplayInfoAndReconfigure, but pre-populates all parameters except for the
3594 * orientation.
3595 */
3596void KeyboardInputMapperTest::prepareDisplay(int32_t orientation) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003597 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation, UNIQUE_ID,
3598 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003599}
3600
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003601void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper& mapper,
Arthur Hung2c9a3342019-07-23 14:18:59 +08003602 int32_t originalScanCode, int32_t originalKeyCode,
3603 int32_t rotatedKeyCode, int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003604 NotifyKeyArgs args;
3605
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003606 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003607 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3608 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3609 ASSERT_EQ(originalScanCode, args.scanCode);
3610 ASSERT_EQ(rotatedKeyCode, args.keyCode);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003611 ASSERT_EQ(displayId, args.displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003612
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003613 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003614 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3615 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3616 ASSERT_EQ(originalScanCode, args.scanCode);
3617 ASSERT_EQ(rotatedKeyCode, args.keyCode);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003618 ASSERT_EQ(displayId, args.displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003619}
3620
Michael Wrightd02c5b62014-02-10 15:10:22 -08003621TEST_F(KeyboardInputMapperTest, GetSources) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003622 KeyboardInputMapper& mapper =
3623 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3624 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003625
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003626 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003627}
3628
3629TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) {
3630 const int32_t USAGE_A = 0x070004;
3631 const int32_t USAGE_UNKNOWN = 0x07ffff;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003632 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3633 mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
Chris Yea52ade12020-08-27 16:49:20 -07003634 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, POLICY_FLAG_WAKE);
3635 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, POLICY_FLAG_WAKE);
3636 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, POLICY_FLAG_WAKE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003637
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003638 KeyboardInputMapper& mapper =
3639 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3640 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003641 // Initial metastate is AMETA_NONE.
3642 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003643
3644 // Key down by scan code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003645 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003646 NotifyKeyArgs args;
3647 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3648 ASSERT_EQ(DEVICE_ID, args.deviceId);
3649 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3650 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3651 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3652 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3653 ASSERT_EQ(KEY_HOME, args.scanCode);
3654 ASSERT_EQ(AMETA_NONE, args.metaState);
3655 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3656 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3657 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3658
3659 // Key up by scan code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003660 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003661 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3662 ASSERT_EQ(DEVICE_ID, args.deviceId);
3663 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3664 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3665 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3666 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3667 ASSERT_EQ(KEY_HOME, args.scanCode);
3668 ASSERT_EQ(AMETA_NONE, args.metaState);
3669 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3670 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3671 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3672
3673 // Key down by usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003674 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_A);
3675 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, 0, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003676 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3677 ASSERT_EQ(DEVICE_ID, args.deviceId);
3678 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3679 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3680 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3681 ASSERT_EQ(AKEYCODE_A, args.keyCode);
3682 ASSERT_EQ(0, args.scanCode);
3683 ASSERT_EQ(AMETA_NONE, args.metaState);
3684 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3685 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3686 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3687
3688 // Key up by usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003689 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_A);
3690 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003691 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3692 ASSERT_EQ(DEVICE_ID, args.deviceId);
3693 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3694 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3695 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3696 ASSERT_EQ(AKEYCODE_A, args.keyCode);
3697 ASSERT_EQ(0, args.scanCode);
3698 ASSERT_EQ(AMETA_NONE, args.metaState);
3699 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3700 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3701 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3702
3703 // Key down with unknown scan code or usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003704 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
3705 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UNKNOWN, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003706 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3707 ASSERT_EQ(DEVICE_ID, args.deviceId);
3708 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3709 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3710 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3711 ASSERT_EQ(0, args.keyCode);
3712 ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
3713 ASSERT_EQ(AMETA_NONE, args.metaState);
3714 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3715 ASSERT_EQ(0U, args.policyFlags);
3716 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3717
3718 // Key up with unknown scan code or usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003719 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
3720 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_UNKNOWN, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003721 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3722 ASSERT_EQ(DEVICE_ID, args.deviceId);
3723 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3724 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3725 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3726 ASSERT_EQ(0, args.keyCode);
3727 ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
3728 ASSERT_EQ(AMETA_NONE, args.metaState);
3729 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3730 ASSERT_EQ(0U, args.policyFlags);
3731 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3732}
3733
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003734/**
3735 * Ensure that the readTime is set to the time when the EV_KEY is received.
3736 */
3737TEST_F(KeyboardInputMapperTest, Process_SendsReadTime) {
3738 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3739
3740 KeyboardInputMapper& mapper =
3741 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3742 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3743 NotifyKeyArgs args;
3744
3745 // Key down
3746 process(mapper, ARBITRARY_TIME, 12 /*readTime*/, EV_KEY, KEY_HOME, 1);
3747 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3748 ASSERT_EQ(12, args.readTime);
3749
3750 // Key up
3751 process(mapper, ARBITRARY_TIME, 15 /*readTime*/, EV_KEY, KEY_HOME, 1);
3752 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3753 ASSERT_EQ(15, args.readTime);
3754}
3755
Michael Wrightd02c5b62014-02-10 15:10:22 -08003756TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003757 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFTSHIFT, 0, AKEYCODE_SHIFT_LEFT, 0);
3758 mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
Chris Yea52ade12020-08-27 16:49:20 -07003759 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, 0);
3760 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, 0);
3761 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003762
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003763 KeyboardInputMapper& mapper =
3764 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3765 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003766
Arthur Hung95f68612022-04-07 14:08:22 +08003767 // Initial metastate is AMETA_NONE.
3768 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003769
3770 // Metakey down.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003771 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_LEFTSHIFT, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003772 NotifyKeyArgs args;
3773 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3774 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003775 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
arthurhungdcef2dc2020-08-11 14:47:50 +08003776 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertUpdateGlobalMetaStateWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003777
3778 // Key down.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003779 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_A, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003780 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3781 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003782 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003783
3784 // Key up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003785 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, KEY_A, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003786 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3787 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003788 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003789
3790 // Metakey up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003791 process(mapper, ARBITRARY_TIME + 3, READ_TIME, EV_KEY, KEY_LEFTSHIFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003792 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3793 ASSERT_EQ(AMETA_NONE, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003794 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
arthurhungdcef2dc2020-08-11 14:47:50 +08003795 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertUpdateGlobalMetaStateWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003796}
3797
3798TEST_F(KeyboardInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateDPad) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003799 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3800 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3801 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3802 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003803
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003804 KeyboardInputMapper& mapper =
3805 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3806 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003807
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003808 prepareDisplay(DISPLAY_ORIENTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003809 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3810 KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP));
3811 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3812 KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT));
3813 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3814 KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN));
3815 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3816 KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT));
3817}
3818
3819TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003820 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3821 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3822 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3823 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003824
Michael Wrightd02c5b62014-02-10 15:10:22 -08003825 addConfigurationProperty("keyboard.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003826 KeyboardInputMapper& mapper =
3827 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3828 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003829
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003830 prepareDisplay(DISPLAY_ORIENTATION_0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003831 ASSERT_NO_FATAL_FAILURE(
3832 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID));
3833 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3834 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3835 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3836 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3837 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3838 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003839
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003840 clearViewports();
3841 prepareDisplay(DISPLAY_ORIENTATION_90);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003842 ASSERT_NO_FATAL_FAILURE(
3843 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3844 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3845 AKEYCODE_DPAD_UP, DISPLAY_ID));
3846 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3847 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3848 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3849 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003850
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003851 clearViewports();
3852 prepareDisplay(DISPLAY_ORIENTATION_180);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003853 ASSERT_NO_FATAL_FAILURE(
3854 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3855 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3856 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3857 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3858 AKEYCODE_DPAD_UP, DISPLAY_ID));
3859 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3860 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003861
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003862 clearViewports();
3863 prepareDisplay(DISPLAY_ORIENTATION_270);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003864 ASSERT_NO_FATAL_FAILURE(
3865 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3866 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3867 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3868 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3869 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3870 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3871 AKEYCODE_DPAD_UP, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003872
3873 // Special case: if orientation changes while key is down, we still emit the same keycode
3874 // in the key up as we did in the key down.
3875 NotifyKeyArgs args;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003876 clearViewports();
3877 prepareDisplay(DISPLAY_ORIENTATION_270);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003878 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003879 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3880 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3881 ASSERT_EQ(KEY_UP, args.scanCode);
3882 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
3883
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003884 clearViewports();
3885 prepareDisplay(DISPLAY_ORIENTATION_180);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003886 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003887 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3888 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3889 ASSERT_EQ(KEY_UP, args.scanCode);
3890 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
3891}
3892
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003893TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_NotOrientationAware) {
3894 // If the keyboard is not orientation aware,
3895 // key events should not be associated with a specific display id
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003896 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003897
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003898 KeyboardInputMapper& mapper =
3899 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3900 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003901 NotifyKeyArgs args;
3902
3903 // Display id should be ADISPLAY_ID_NONE without any display configuration.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003904 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003905 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003906 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003907 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3908 ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
3909
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003910 prepareDisplay(DISPLAY_ORIENTATION_0);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003911 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003912 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003913 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003914 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3915 ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
3916}
3917
3918TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_OrientationAware) {
3919 // If the keyboard is orientation aware,
3920 // key events should be associated with the internal viewport
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003921 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003922
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003923 addConfigurationProperty("keyboard.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003924 KeyboardInputMapper& mapper =
3925 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3926 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003927 NotifyKeyArgs args;
3928
3929 // Display id should be ADISPLAY_ID_NONE without any display configuration.
3930 // ^--- already checked by the previous test
3931
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003932 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003933 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003934 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003935 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003936 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003937 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3938 ASSERT_EQ(DISPLAY_ID, args.displayId);
3939
3940 constexpr int32_t newDisplayId = 2;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003941 clearViewports();
3942 setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003943 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003944 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003945 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003946 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003947 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3948 ASSERT_EQ(newDisplayId, args.displayId);
3949}
3950
Michael Wrightd02c5b62014-02-10 15:10:22 -08003951TEST_F(KeyboardInputMapperTest, GetKeyCodeState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003952 KeyboardInputMapper& mapper =
3953 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3954 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003955
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003956 mFakeEventHub->setKeyCodeState(EVENTHUB_ID, AKEYCODE_A, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003957 ASSERT_EQ(1, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003958
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003959 mFakeEventHub->setKeyCodeState(EVENTHUB_ID, AKEYCODE_A, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003960 ASSERT_EQ(0, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003961}
3962
Philip Junker4af3b3d2021-12-14 10:36:55 +01003963TEST_F(KeyboardInputMapperTest, GetKeyCodeForKeyLocation) {
3964 KeyboardInputMapper& mapper =
3965 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3966 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3967
3968 mFakeEventHub->addKeyCodeMapping(EVENTHUB_ID, AKEYCODE_Y, AKEYCODE_Z);
3969 ASSERT_EQ(AKEYCODE_Z, mapper.getKeyCodeForKeyLocation(AKEYCODE_Y))
3970 << "If a mapping is available, the result is equal to the mapping";
3971
3972 ASSERT_EQ(AKEYCODE_A, mapper.getKeyCodeForKeyLocation(AKEYCODE_A))
3973 << "If no mapping is available, the result is the key location";
3974}
3975
Michael Wrightd02c5b62014-02-10 15:10:22 -08003976TEST_F(KeyboardInputMapperTest, GetScanCodeState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003977 KeyboardInputMapper& mapper =
3978 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3979 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003980
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003981 mFakeEventHub->setScanCodeState(EVENTHUB_ID, KEY_A, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003982 ASSERT_EQ(1, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003983
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003984 mFakeEventHub->setScanCodeState(EVENTHUB_ID, KEY_A, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003985 ASSERT_EQ(0, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003986}
3987
3988TEST_F(KeyboardInputMapperTest, MarkSupportedKeyCodes) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003989 KeyboardInputMapper& mapper =
3990 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3991 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003992
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003993 mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003994
Michael Wrightd02c5b62014-02-10 15:10:22 -08003995 uint8_t flags[2] = { 0, 0 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07003996 ASSERT_TRUE(mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, {AKEYCODE_A, AKEYCODE_B}, flags));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003997 ASSERT_TRUE(flags[0]);
3998 ASSERT_FALSE(flags[1]);
3999}
4000
4001TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004002 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
4003 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
4004 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
4005 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
4006 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
4007 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004008
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004009 KeyboardInputMapper& mapper =
4010 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
4011 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08004012 // Initial metastate is AMETA_NONE.
4013 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004014
4015 // Initialization should have turned all of the lights off.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004016 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
4017 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
4018 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004019
4020 // Toggle caps lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004021 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
4022 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004023 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
4024 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
4025 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004026 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004027
4028 // Toggle num lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004029 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
4030 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004031 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
4032 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
4033 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004034 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004035
4036 // Toggle caps lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004037 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
4038 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004039 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
4040 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
4041 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004042 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004043
4044 // Toggle scroll lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004045 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
4046 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004047 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
4048 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
4049 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004050 ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004051
4052 // Toggle num lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004053 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
4054 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004055 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
4056 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
4057 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004058 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004059
4060 // Toggle scroll lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004061 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
4062 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004063 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
4064 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
4065 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004066 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004067}
4068
Chris Yea52ade12020-08-27 16:49:20 -07004069TEST_F(KeyboardInputMapperTest, NoMetaStateWhenMetaKeysNotPresent) {
4070 mFakeEventHub->addKey(EVENTHUB_ID, BTN_A, 0, AKEYCODE_BUTTON_A, 0);
4071 mFakeEventHub->addKey(EVENTHUB_ID, BTN_B, 0, AKEYCODE_BUTTON_B, 0);
4072 mFakeEventHub->addKey(EVENTHUB_ID, BTN_X, 0, AKEYCODE_BUTTON_X, 0);
4073 mFakeEventHub->addKey(EVENTHUB_ID, BTN_Y, 0, AKEYCODE_BUTTON_Y, 0);
4074
4075 KeyboardInputMapper& mapper =
4076 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
4077 AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
4078
Chris Yea52ade12020-08-27 16:49:20 -07004079 // Meta state should be AMETA_NONE after reset
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07004080 std::list<NotifyArgs> unused = mapper.reset(ARBITRARY_TIME);
Chris Yea52ade12020-08-27 16:49:20 -07004081 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
4082 // Meta state should be AMETA_NONE with update, as device doesn't have the keys.
4083 mapper.updateMetaState(AKEYCODE_NUM_LOCK);
4084 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
4085
4086 NotifyKeyArgs args;
4087 // Press button "A"
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004088 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_A, 1);
Chris Yea52ade12020-08-27 16:49:20 -07004089 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4090 ASSERT_EQ(AMETA_NONE, args.metaState);
4091 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
4092 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
4093 ASSERT_EQ(AKEYCODE_BUTTON_A, args.keyCode);
4094
4095 // Button up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004096 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, BTN_A, 0);
Chris Yea52ade12020-08-27 16:49:20 -07004097 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4098 ASSERT_EQ(AMETA_NONE, args.metaState);
4099 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
4100 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
4101 ASSERT_EQ(AKEYCODE_BUTTON_A, args.keyCode);
4102}
4103
Arthur Hung2c9a3342019-07-23 14:18:59 +08004104TEST_F(KeyboardInputMapperTest, Configure_AssignsDisplayPort) {
4105 // keyboard 1.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004106 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
4107 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
4108 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
4109 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08004110
4111 // keyboard 2.
4112 const std::string USB2 = "USB2";
arthurhungdcef2dc2020-08-11 14:47:50 +08004113 const std::string DEVICE_NAME2 = "KEYBOARD2";
Arthur Hung2c9a3342019-07-23 14:18:59 +08004114 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004115 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
arthurhungdcef2dc2020-08-11 14:47:50 +08004116 std::shared_ptr<InputDevice> device2 =
4117 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07004118 ftl::Flags<InputDeviceClass>(0));
arthurhungdcef2dc2020-08-11 14:47:50 +08004119
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004120 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
4121 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
4122 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
4123 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08004124
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004125 KeyboardInputMapper& mapper =
4126 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
4127 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung2c9a3342019-07-23 14:18:59 +08004128
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004129 KeyboardInputMapper& mapper2 =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004130 device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004131 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07004132 std::list<NotifyArgs> unused =
4133 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
4134 0 /*changes*/);
4135 unused += device2->reset(ARBITRARY_TIME);
Arthur Hung2c9a3342019-07-23 14:18:59 +08004136
4137 // Prepared displays and associated info.
4138 constexpr uint8_t hdmi1 = 0;
4139 constexpr uint8_t hdmi2 = 1;
4140 const std::string SECONDARY_UNIQUE_ID = "local:1";
4141
4142 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
4143 mFakePolicy->addInputPortAssociation(USB2, hdmi2);
4144
4145 // No associated display viewport found, should disable the device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07004146 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
4147 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08004148 ASSERT_FALSE(device2->isEnabled());
4149
4150 // Prepare second display.
4151 constexpr int32_t newDisplayId = 2;
4152 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01004153 UNIQUE_ID, hdmi1, ViewportType::INTERNAL);
Arthur Hung2c9a3342019-07-23 14:18:59 +08004154 setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01004155 SECONDARY_UNIQUE_ID, hdmi2, ViewportType::EXTERNAL);
Arthur Hung2c9a3342019-07-23 14:18:59 +08004156 // Default device will reconfigure above, need additional reconfiguration for another device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07004157 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
4158 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08004159
4160 // Device should be enabled after the associated display is found.
4161 ASSERT_TRUE(mDevice->isEnabled());
4162 ASSERT_TRUE(device2->isEnabled());
4163
4164 // Test pad key events
4165 ASSERT_NO_FATAL_FAILURE(
4166 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID));
4167 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
4168 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
4169 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
4170 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
4171 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
4172 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
4173
4174 ASSERT_NO_FATAL_FAILURE(
4175 testDPadKeyRotation(mapper2, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, newDisplayId));
4176 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
4177 AKEYCODE_DPAD_RIGHT, newDisplayId));
4178 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_DOWN, AKEYCODE_DPAD_DOWN,
4179 AKEYCODE_DPAD_DOWN, newDisplayId));
4180 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_LEFT, AKEYCODE_DPAD_LEFT,
4181 AKEYCODE_DPAD_LEFT, newDisplayId));
4182}
Michael Wrightd02c5b62014-02-10 15:10:22 -08004183
arthurhungc903df12020-08-11 15:08:42 +08004184TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleAfterReattach) {
4185 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
4186 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
4187 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
4188 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
4189 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
4190 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
4191
4192 KeyboardInputMapper& mapper =
4193 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
4194 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08004195 // Initial metastate is AMETA_NONE.
4196 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
arthurhungc903df12020-08-11 15:08:42 +08004197
4198 // Initialization should have turned all of the lights off.
4199 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
4200 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
4201 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
4202
4203 // Toggle caps lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004204 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
4205 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08004206 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
4207 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
4208
4209 // Toggle num lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004210 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
4211 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08004212 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
4213 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState());
4214
4215 // Toggle scroll lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004216 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
4217 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08004218 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
4219 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
4220
4221 mFakeEventHub->removeDevice(EVENTHUB_ID);
4222 mReader->loopOnce();
4223
4224 // keyboard 2 should default toggle keys.
4225 const std::string USB2 = "USB2";
4226 const std::string DEVICE_NAME2 = "KEYBOARD2";
4227 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
4228 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
4229 std::shared_ptr<InputDevice> device2 =
4230 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07004231 ftl::Flags<InputDeviceClass>(0));
arthurhungc903df12020-08-11 15:08:42 +08004232 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
4233 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/);
4234 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
4235 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
4236 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
4237 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
4238
arthurhung6fe95782020-10-05 22:41:16 +08004239 KeyboardInputMapper& mapper2 =
4240 device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
4241 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07004242 std::list<NotifyArgs> unused =
4243 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
4244 0 /*changes*/);
4245 unused += device2->reset(ARBITRARY_TIME);
arthurhungc903df12020-08-11 15:08:42 +08004246
4247 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_CAPSL));
4248 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_NUML));
4249 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_SCROLLL));
arthurhung6fe95782020-10-05 22:41:16 +08004250 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON,
4251 mapper2.getMetaState());
arthurhungc903df12020-08-11 15:08:42 +08004252}
4253
Arthur Hungcb40a002021-08-03 14:31:01 +00004254TEST_F(KeyboardInputMapperTest, Process_toggleCapsLockState) {
4255 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
4256 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
4257 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
4258
4259 // Suppose we have two mappers. (DPAD + KEYBOARD)
4260 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_DPAD,
4261 AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
4262 KeyboardInputMapper& mapper =
4263 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
4264 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08004265 // Initial metastate is AMETA_NONE.
4266 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Arthur Hungcb40a002021-08-03 14:31:01 +00004267
4268 mReader->toggleCapsLockState(DEVICE_ID);
4269 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
4270}
4271
Arthur Hungfb3cc112022-04-13 07:39:50 +00004272TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleInMultiDevices) {
4273 // keyboard 1.
4274 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
4275 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
4276 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
4277 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
4278 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
4279 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
4280
4281 KeyboardInputMapper& mapper1 =
4282 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
4283 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
4284
4285 // keyboard 2.
4286 const std::string USB2 = "USB2";
4287 const std::string DEVICE_NAME2 = "KEYBOARD2";
4288 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
4289 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
4290 std::shared_ptr<InputDevice> device2 =
4291 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
4292 ftl::Flags<InputDeviceClass>(0));
4293 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
4294 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/);
4295 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
4296 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
4297 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
4298 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
4299
4300 KeyboardInputMapper& mapper2 =
4301 device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
4302 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07004303 std::list<NotifyArgs> unused =
4304 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
4305 0 /*changes*/);
4306 unused += device2->reset(ARBITRARY_TIME);
Arthur Hungfb3cc112022-04-13 07:39:50 +00004307
Arthur Hung95f68612022-04-07 14:08:22 +08004308 // Initial metastate is AMETA_NONE.
4309 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
4310 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
4311
4312 // Toggle num lock on and off.
4313 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
4314 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Arthur Hungfb3cc112022-04-13 07:39:50 +00004315 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
4316 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper1.getMetaState());
4317 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper2.getMetaState());
4318
4319 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
4320 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
4321 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
4322 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
4323 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
4324
4325 // Toggle caps lock on and off.
4326 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
4327 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
4328 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
4329 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper1.getMetaState());
4330 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper2.getMetaState());
4331
4332 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
4333 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
4334 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
4335 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
4336 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
4337
4338 // Toggle scroll lock on and off.
4339 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
4340 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
4341 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
4342 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper1.getMetaState());
4343 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper2.getMetaState());
4344
4345 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
4346 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
4347 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
4348 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
4349 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
4350}
4351
Arthur Hung2141d542022-08-23 07:45:21 +00004352TEST_F(KeyboardInputMapperTest, Process_DisabledDevice) {
4353 const int32_t USAGE_A = 0x070004;
4354 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
4355 mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
4356
4357 KeyboardInputMapper& mapper =
4358 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
4359 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
4360 // Key down by scan code.
4361 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
4362 NotifyKeyArgs args;
4363 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4364 ASSERT_EQ(DEVICE_ID, args.deviceId);
4365 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
4366 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
4367 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
4368 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
4369 ASSERT_EQ(KEY_HOME, args.scanCode);
4370 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
4371
4372 // Disable device, it should synthesize cancellation events for down events.
4373 mFakePolicy->addDisabledDevice(DEVICE_ID);
4374 configureDevice(InputReaderConfiguration::CHANGE_ENABLED_STATE);
4375
4376 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4377 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
4378 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
4379 ASSERT_EQ(KEY_HOME, args.scanCode);
4380 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED, args.flags);
4381}
4382
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004383// --- KeyboardInputMapperTest_ExternalDevice ---
4384
4385class KeyboardInputMapperTest_ExternalDevice : public InputMapperTest {
4386protected:
Chris Yea52ade12020-08-27 16:49:20 -07004387 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004388};
4389
4390TEST_F(KeyboardInputMapperTest_ExternalDevice, WakeBehavior) {
Powei Fengd041c5d2019-05-03 17:11:33 -07004391 // For external devices, non-media keys will trigger wake on key down. Media keys need to be
4392 // marked as WAKE in the keylayout file to trigger wake.
Powei Fengd041c5d2019-05-03 17:11:33 -07004393
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004394 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, 0);
4395 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, 0);
4396 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAYPAUSE, 0, AKEYCODE_MEDIA_PLAY_PAUSE,
4397 POLICY_FLAG_WAKE);
Powei Fengd041c5d2019-05-03 17:11:33 -07004398
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004399 KeyboardInputMapper& mapper =
4400 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
4401 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Powei Fengd041c5d2019-05-03 17:11:33 -07004402
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004403 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004404 NotifyKeyArgs args;
4405 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4406 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4407
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004408 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004409 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4410 ASSERT_EQ(uint32_t(0), args.policyFlags);
4411
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004412 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAY, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004413 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4414 ASSERT_EQ(uint32_t(0), args.policyFlags);
4415
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004416 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAY, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004417 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4418 ASSERT_EQ(uint32_t(0), args.policyFlags);
4419
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004420 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAYPAUSE, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004421 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4422 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4423
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004424 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAYPAUSE, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004425 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4426 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4427}
4428
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004429TEST_F(KeyboardInputMapperTest_ExternalDevice, DoNotWakeByDefaultBehavior) {
Powei Fengd041c5d2019-05-03 17:11:33 -07004430 // Tv Remote key's wake behavior is prescribed by the keylayout file.
Powei Fengd041c5d2019-05-03 17:11:33 -07004431
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004432 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
4433 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
4434 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, POLICY_FLAG_WAKE);
Powei Fengd041c5d2019-05-03 17:11:33 -07004435
Powei Fengd041c5d2019-05-03 17:11:33 -07004436 addConfigurationProperty("keyboard.doNotWakeByDefault", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004437 KeyboardInputMapper& mapper =
4438 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
4439 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Powei Fengd041c5d2019-05-03 17:11:33 -07004440
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004441 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004442 NotifyKeyArgs args;
4443 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4444 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4445
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004446 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004447 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4448 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4449
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004450 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_DOWN, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004451 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4452 ASSERT_EQ(uint32_t(0), args.policyFlags);
4453
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004454 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_DOWN, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004455 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4456 ASSERT_EQ(uint32_t(0), args.policyFlags);
4457
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004458 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAY, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004459 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4460 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4461
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004462 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAY, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004463 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4464 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4465}
4466
Michael Wrightd02c5b62014-02-10 15:10:22 -08004467// --- CursorInputMapperTest ---
4468
4469class CursorInputMapperTest : public InputMapperTest {
4470protected:
4471 static const int32_t TRACKBALL_MOVEMENT_THRESHOLD;
4472
Michael Wright17db18e2020-06-26 20:51:44 +01004473 std::shared_ptr<FakePointerController> mFakePointerController;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004474
Chris Yea52ade12020-08-27 16:49:20 -07004475 void SetUp() override {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004476 InputMapperTest::SetUp();
4477
Michael Wright17db18e2020-06-26 20:51:44 +01004478 mFakePointerController = std::make_shared<FakePointerController>();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00004479 mFakePolicy->setPointerController(mFakePointerController);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004480 }
4481
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004482 void testMotionRotation(CursorInputMapper& mapper, int32_t originalX, int32_t originalY,
4483 int32_t rotatedX, int32_t rotatedY);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004484
4485 void prepareDisplay(int32_t orientation) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004486 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation,
4487 DISPLAY_UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
4488 }
4489
4490 void prepareSecondaryDisplay() {
4491 setDisplayInfoAndReconfigure(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
4492 DISPLAY_ORIENTATION_0, SECONDARY_DISPLAY_UNIQUE_ID, NO_PORT,
4493 ViewportType::EXTERNAL);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004494 }
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004495
4496 static void assertCursorPointerCoords(const PointerCoords& coords, float x, float y,
4497 float pressure) {
4498 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(coords, x, y, pressure, 0.0f, 0.0f, 0.0f, 0.0f,
4499 0.0f, 0.0f, 0.0f, EPSILON));
4500 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004501};
4502
4503const int32_t CursorInputMapperTest::TRACKBALL_MOVEMENT_THRESHOLD = 6;
4504
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004505void CursorInputMapperTest::testMotionRotation(CursorInputMapper& mapper, int32_t originalX,
4506 int32_t originalY, int32_t rotatedX,
4507 int32_t rotatedY) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004508 NotifyMotionArgs args;
4509
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004510 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, originalX);
4511 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, originalY);
4512 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004513 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4514 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004515 ASSERT_NO_FATAL_FAILURE(
4516 assertCursorPointerCoords(args.pointerCoords[0],
4517 float(rotatedX) / TRACKBALL_MOVEMENT_THRESHOLD,
4518 float(rotatedY) / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004519}
4520
4521TEST_F(CursorInputMapperTest, WhenModeIsPointer_GetSources_ReturnsMouse) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004522 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004523 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004524
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004525 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004526}
4527
4528TEST_F(CursorInputMapperTest, WhenModeIsNavigation_GetSources_ReturnsTrackball) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004529 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004530 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004531
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004532 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004533}
4534
4535TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeFromPointerController) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004536 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004537 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004538
4539 InputDeviceInfo info;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004540 mapper.populateDeviceInfo(&info);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004541
4542 // Initially there may not be a valid motion range.
Yi Kong9b14ac62018-07-17 13:48:38 -07004543 ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE));
4544 ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004545 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
4546 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE, 0.0f, 1.0f, 0.0f, 0.0f));
4547
4548 // When the bounds are set, then there should be a valid motion range.
4549 mFakePointerController->setBounds(1, 2, 800 - 1, 480 - 1);
4550
4551 InputDeviceInfo info2;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004552 mapper.populateDeviceInfo(&info2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004553
4554 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
4555 AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE,
4556 1, 800 - 1, 0.0f, 0.0f));
4557 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
4558 AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE,
4559 2, 480 - 1, 0.0f, 0.0f));
4560 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
4561 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE,
4562 0.0f, 1.0f, 0.0f, 0.0f));
4563}
4564
4565TEST_F(CursorInputMapperTest, WhenModeIsNavigation_PopulateDeviceInfo_ReturnsScaledRange) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004566 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004567 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004568
4569 InputDeviceInfo info;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004570 mapper.populateDeviceInfo(&info);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004571
4572 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
4573 AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_TRACKBALL,
4574 -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
4575 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
4576 AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_TRACKBALL,
4577 -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
4578 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
4579 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TRACKBALL,
4580 0.0f, 1.0f, 0.0f, 0.0f));
4581}
4582
4583TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004584 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004585 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004586
arthurhungdcef2dc2020-08-11 14:47:50 +08004587 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004588
4589 NotifyMotionArgs args;
4590
4591 // Button press.
4592 // Mostly testing non x/y behavior here so we don't need to check again elsewhere.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004593 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4594 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004595 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4596 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
4597 ASSERT_EQ(DEVICE_ID, args.deviceId);
4598 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4599 ASSERT_EQ(uint32_t(0), args.policyFlags);
4600 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
4601 ASSERT_EQ(0, args.flags);
4602 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4603 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
4604 ASSERT_EQ(0, args.edgeFlags);
4605 ASSERT_EQ(uint32_t(1), args.pointerCount);
4606 ASSERT_EQ(0, args.pointerProperties[0].id);
4607 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004608 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004609 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4610 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4611 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4612
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004613 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4614 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
4615 ASSERT_EQ(DEVICE_ID, args.deviceId);
4616 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4617 ASSERT_EQ(uint32_t(0), args.policyFlags);
4618 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
4619 ASSERT_EQ(0, args.flags);
4620 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4621 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
4622 ASSERT_EQ(0, args.edgeFlags);
4623 ASSERT_EQ(uint32_t(1), args.pointerCount);
4624 ASSERT_EQ(0, args.pointerProperties[0].id);
4625 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004626 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004627 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4628 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4629 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4630
Michael Wrightd02c5b62014-02-10 15:10:22 -08004631 // Button release. Should have same down time.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004632 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4633 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004634 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4635 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
4636 ASSERT_EQ(DEVICE_ID, args.deviceId);
4637 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4638 ASSERT_EQ(uint32_t(0), args.policyFlags);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004639 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
4640 ASSERT_EQ(0, args.flags);
4641 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4642 ASSERT_EQ(0, args.buttonState);
4643 ASSERT_EQ(0, args.edgeFlags);
4644 ASSERT_EQ(uint32_t(1), args.pointerCount);
4645 ASSERT_EQ(0, args.pointerProperties[0].id);
4646 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004647 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004648 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4649 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4650 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4651
4652 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4653 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
4654 ASSERT_EQ(DEVICE_ID, args.deviceId);
4655 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4656 ASSERT_EQ(uint32_t(0), args.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004657 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
4658 ASSERT_EQ(0, args.flags);
4659 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4660 ASSERT_EQ(0, args.buttonState);
4661 ASSERT_EQ(0, args.edgeFlags);
4662 ASSERT_EQ(uint32_t(1), args.pointerCount);
4663 ASSERT_EQ(0, args.pointerProperties[0].id);
4664 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004665 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004666 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4667 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4668 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4669}
4670
4671TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentXYUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004672 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004673 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004674
4675 NotifyMotionArgs args;
4676
4677 // Motion in X but not Y.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004678 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4679 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004680 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4681 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004682 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4683 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f,
4684 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004685
4686 // Motion in Y but not X.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004687 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, -2);
4688 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004689 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4690 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004691 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f,
4692 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004693}
4694
4695TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004696 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004697 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004698
4699 NotifyMotionArgs args;
4700
4701 // Button press.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004702 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4703 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004704 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4705 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004706 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004707
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004708 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4709 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004710 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004711
Michael Wrightd02c5b62014-02-10 15:10:22 -08004712 // Button release.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004713 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4714 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004715 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004716 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004717 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004718
4719 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004720 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004721 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004722}
4723
4724TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004725 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004726 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004727
4728 NotifyMotionArgs args;
4729
4730 // Combined X, Y and Button.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004731 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4732 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, -2);
4733 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4734 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004735 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4736 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004737 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4738 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4739 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004740
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004741 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4742 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004743 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4744 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4745 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004746
Michael Wrightd02c5b62014-02-10 15:10:22 -08004747 // Move X, Y a bit while pressed.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004748 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 2);
4749 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 1);
4750 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004751 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4752 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004753 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4754 2.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4755 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004756
4757 // Release Button.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004758 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4759 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004760 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004761 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004762 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004763
4764 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004765 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004766 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004767}
4768
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004769TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldNotRotateMotions) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004770 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004771 addConfigurationProperty("cursor.mode", "navigation");
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004772 // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
4773 // need to be rotated.
4774 addConfigurationProperty("cursor.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004775 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004776
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004777 prepareDisplay(DISPLAY_ORIENTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004778 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1));
4779 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1));
4780 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0));
4781 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, -1));
4782 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1));
4783 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
4784 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0));
4785 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1));
4786}
4787
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004788TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldRotateMotions) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004789 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004790 addConfigurationProperty("cursor.mode", "navigation");
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004791 // Since InputReader works in the un-rotated coordinate space, only devices that are not
4792 // orientation-aware are affected by display rotation.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004793 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004794
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004795 clearViewports();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004796 prepareDisplay(DISPLAY_ORIENTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004797 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1));
4798 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1));
4799 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0));
4800 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, -1));
4801 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1));
4802 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
4803 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0));
4804 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1));
4805
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004806 clearViewports();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004807 prepareDisplay(DISPLAY_ORIENTATION_90);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004808 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, -1, 0));
4809 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, -1, 1));
4810 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 0, 1));
4811 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, 1));
4812 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 1, 0));
4813 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, -1));
4814 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, -1));
4815 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, -1));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004816
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004817 clearViewports();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004818 prepareDisplay(DISPLAY_ORIENTATION_180);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004819 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, -1));
4820 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, -1, -1));
4821 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, -1, 0));
4822 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, -1, 1));
4823 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, 1));
4824 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, 1));
4825 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 1, 0));
4826 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, -1));
4827
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004828 clearViewports();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004829 prepareDisplay(DISPLAY_ORIENTATION_270);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004830 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 1, 0));
4831 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, -1));
4832 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 0, -1));
4833 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, -1, -1));
4834 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, -1, 0));
4835 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, 1));
4836 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, 1));
4837 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, 1));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004838}
4839
4840TEST_F(CursorInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004841 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004842 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004843
4844 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
4845 mFakePointerController->setPosition(100, 200);
4846 mFakePointerController->setButtonState(0);
4847
4848 NotifyMotionArgs motionArgs;
4849 NotifyKeyArgs keyArgs;
4850
4851 // press BTN_LEFT, release BTN_LEFT
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004852 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_LEFT, 1);
4853 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004854 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4855 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4856 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
4857 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004858 ASSERT_NO_FATAL_FAILURE(
4859 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004860
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004861 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4862 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4863 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
4864 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004865 ASSERT_NO_FATAL_FAILURE(
4866 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004867
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004868 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_LEFT, 0);
4869 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004870 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004871 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004872 ASSERT_EQ(0, motionArgs.buttonState);
4873 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004874 ASSERT_NO_FATAL_FAILURE(
4875 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004876
4877 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004878 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004879 ASSERT_EQ(0, motionArgs.buttonState);
4880 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004881 ASSERT_NO_FATAL_FAILURE(
4882 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004883
4884 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004885 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004886 ASSERT_EQ(0, motionArgs.buttonState);
4887 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004888 ASSERT_NO_FATAL_FAILURE(
4889 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004890
4891 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004892 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_RIGHT, 1);
4893 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 1);
4894 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004895 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4896 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4897 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4898 motionArgs.buttonState);
4899 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4900 mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004901 ASSERT_NO_FATAL_FAILURE(
4902 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004903
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004904 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4905 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4906 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4907 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4908 mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004909 ASSERT_NO_FATAL_FAILURE(
4910 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004911
4912 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4913 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4914 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4915 motionArgs.buttonState);
4916 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4917 mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004918 ASSERT_NO_FATAL_FAILURE(
4919 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004920
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004921 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_RIGHT, 0);
4922 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004923 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004924 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004925 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4926 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004927 ASSERT_NO_FATAL_FAILURE(
4928 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004929
4930 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004931 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004932 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4933 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004934 ASSERT_NO_FATAL_FAILURE(
4935 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004936
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004937 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
4938 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004939 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004940 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4941 ASSERT_EQ(0, motionArgs.buttonState);
4942 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004943 ASSERT_NO_FATAL_FAILURE(
4944 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004945 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
4946 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004947
4948 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004949 ASSERT_EQ(0, motionArgs.buttonState);
4950 ASSERT_EQ(0, mFakePointerController->getButtonState());
4951 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004952 ASSERT_NO_FATAL_FAILURE(
4953 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004954
Michael Wrightd02c5b62014-02-10 15:10:22 -08004955 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4956 ASSERT_EQ(0, motionArgs.buttonState);
4957 ASSERT_EQ(0, mFakePointerController->getButtonState());
4958 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004959 ASSERT_NO_FATAL_FAILURE(
4960 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004961
4962 // press BTN_BACK, release BTN_BACK
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004963 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_BACK, 1);
4964 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004965 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4966 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4967 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004968
Michael Wrightd02c5b62014-02-10 15:10:22 -08004969 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004970 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004971 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4972 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004973 ASSERT_NO_FATAL_FAILURE(
4974 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004975
4976 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4977 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4978 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4979 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004980 ASSERT_NO_FATAL_FAILURE(
4981 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004982
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004983 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_BACK, 0);
4984 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004985 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004986 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004987 ASSERT_EQ(0, motionArgs.buttonState);
4988 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004989 ASSERT_NO_FATAL_FAILURE(
4990 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004991
4992 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004993 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004994 ASSERT_EQ(0, motionArgs.buttonState);
4995 ASSERT_EQ(0, mFakePointerController->getButtonState());
4996
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004997 ASSERT_NO_FATAL_FAILURE(
4998 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004999 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5000 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5001 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
5002
5003 // press BTN_SIDE, release BTN_SIDE
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005004 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_SIDE, 1);
5005 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005006 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5007 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5008 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005009
Michael Wrightd02c5b62014-02-10 15:10:22 -08005010 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005011 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005012 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
5013 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07005014 ASSERT_NO_FATAL_FAILURE(
5015 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005016
5017 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5018 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5019 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
5020 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07005021 ASSERT_NO_FATAL_FAILURE(
5022 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005023
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005024 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_SIDE, 0);
5025 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005026 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005027 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005028 ASSERT_EQ(0, motionArgs.buttonState);
5029 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07005030 ASSERT_NO_FATAL_FAILURE(
5031 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005032
5033 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5034 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
5035 ASSERT_EQ(0, motionArgs.buttonState);
5036 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07005037 ASSERT_NO_FATAL_FAILURE(
5038 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005039
Michael Wrightd02c5b62014-02-10 15:10:22 -08005040 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5041 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5042 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
5043
5044 // press BTN_FORWARD, release BTN_FORWARD
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005045 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_FORWARD, 1);
5046 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005047 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5048 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5049 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005050
Michael Wrightd02c5b62014-02-10 15:10:22 -08005051 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005052 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005053 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
5054 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07005055 ASSERT_NO_FATAL_FAILURE(
5056 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005057
5058 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5059 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5060 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
5061 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07005062 ASSERT_NO_FATAL_FAILURE(
5063 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005064
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005065 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_FORWARD, 0);
5066 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005067 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005068 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005069 ASSERT_EQ(0, motionArgs.buttonState);
5070 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07005071 ASSERT_NO_FATAL_FAILURE(
5072 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005073
5074 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5075 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
5076 ASSERT_EQ(0, motionArgs.buttonState);
5077 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07005078 ASSERT_NO_FATAL_FAILURE(
5079 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005080
Michael Wrightd02c5b62014-02-10 15:10:22 -08005081 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5082 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5083 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
5084
5085 // press BTN_EXTRA, release BTN_EXTRA
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005086 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_EXTRA, 1);
5087 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005088 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5089 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5090 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005091
Michael Wrightd02c5b62014-02-10 15:10:22 -08005092 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005093 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005094 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
5095 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07005096 ASSERT_NO_FATAL_FAILURE(
5097 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005098
5099 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5100 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5101 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
5102 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07005103 ASSERT_NO_FATAL_FAILURE(
5104 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005105
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005106 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_EXTRA, 0);
5107 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005108 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005109 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005110 ASSERT_EQ(0, motionArgs.buttonState);
5111 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07005112 ASSERT_NO_FATAL_FAILURE(
5113 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005114
5115 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5116 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
5117 ASSERT_EQ(0, motionArgs.buttonState);
5118 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07005119 ASSERT_NO_FATAL_FAILURE(
5120 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005121
Michael Wrightd02c5b62014-02-10 15:10:22 -08005122 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5123 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5124 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
5125}
5126
5127TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerAround) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005128 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005129 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005130
5131 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
5132 mFakePointerController->setPosition(100, 200);
5133 mFakePointerController->setButtonState(0);
5134
5135 NotifyMotionArgs args;
5136
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005137 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5138 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5139 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005140 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08005141 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
5142 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
5143 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
5144 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
Michael Wright17db18e2020-06-26 20:51:44 +01005145 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08005146}
5147
5148TEST_F(CursorInputMapperTest, Process_PointerCapture) {
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08005149 addConfigurationProperty("cursor.mode", "pointer");
5150 mFakePolicy->setPointerCapture(true);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005151 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08005152
5153 NotifyDeviceResetArgs resetArgs;
5154 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
5155 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
5156 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
5157
5158 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
5159 mFakePointerController->setPosition(100, 200);
5160 mFakePointerController->setButtonState(0);
5161
5162 NotifyMotionArgs args;
5163
5164 // Move.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005165 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5166 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5167 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08005168 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5169 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
5170 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
5171 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
5172 10.0f, 20.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
Michael Wright17db18e2020-06-26 20:51:44 +01005173 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 100.0f, 200.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08005174
5175 // Button press.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005176 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
5177 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08005178 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5179 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
5180 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
5181 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
5182 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
5183 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5184 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
5185 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
5186 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
5187 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
5188
5189 // Button release.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005190 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, BTN_MOUSE, 0);
5191 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08005192 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5193 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
5194 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
5195 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
5196 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
5197 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5198 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
5199 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
5200 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
5201 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
5202
5203 // Another move.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005204 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 30);
5205 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 40);
5206 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08005207 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5208 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
5209 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
5210 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
5211 30.0f, 40.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
Michael Wright17db18e2020-06-26 20:51:44 +01005212 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 100.0f, 200.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08005213
5214 // Disable pointer capture and check that the device generation got bumped
5215 // and events are generated the usual way.
arthurhungdcef2dc2020-08-11 14:47:50 +08005216 const uint32_t generation = mReader->getContext()->getGeneration();
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08005217 mFakePolicy->setPointerCapture(false);
5218 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
arthurhungdcef2dc2020-08-11 14:47:50 +08005219 ASSERT_TRUE(mReader->getContext()->getGeneration() != generation);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08005220
5221 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08005222 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
5223
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005224 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5225 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5226 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08005227 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5228 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005229 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
5230 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
5231 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
Michael Wright17db18e2020-06-26 20:51:44 +01005232 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005233}
5234
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00005235/**
5236 * When Pointer Capture is enabled, we expect to report unprocessed relative movements, so any
5237 * pointer acceleration or speed processing should not be applied.
5238 */
5239TEST_F(CursorInputMapperTest, PointerCaptureDisablesVelocityProcessing) {
5240 addConfigurationProperty("cursor.mode", "pointer");
5241 const VelocityControlParameters testParams(5.f /*scale*/, 0.f /*low threshold*/,
5242 100.f /*high threshold*/, 10.f /*acceleration*/);
5243 mFakePolicy->setVelocityControlParams(testParams);
5244 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
5245
5246 NotifyDeviceResetArgs resetArgs;
5247 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
5248 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
5249 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
5250
5251 NotifyMotionArgs args;
5252
5253 // Move and verify scale is applied.
5254 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5255 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5256 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5257 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5258 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
5259 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
5260 const float relX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
5261 const float relY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
5262 ASSERT_GT(relX, 10);
5263 ASSERT_GT(relY, 20);
5264
5265 // Enable Pointer Capture
5266 mFakePolicy->setPointerCapture(true);
5267 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
5268 NotifyPointerCaptureChangedArgs captureArgs;
5269 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
5270 ASSERT_TRUE(captureArgs.request.enable);
5271
5272 // Move and verify scale is not applied.
5273 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5274 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5275 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5276 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5277 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
5278 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
5279 ASSERT_EQ(10, args.pointerCoords[0].getX());
5280 ASSERT_EQ(20, args.pointerCoords[0].getY());
5281}
5282
Prabir Pradhan208360b2022-06-24 18:37:04 +00005283TEST_F(CursorInputMapperTest, PointerCaptureDisablesOrientationChanges) {
5284 addConfigurationProperty("cursor.mode", "pointer");
5285 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
5286
5287 NotifyDeviceResetArgs resetArgs;
5288 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
5289 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
5290 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
5291
5292 // Ensure the display is rotated.
5293 prepareDisplay(DISPLAY_ORIENTATION_90);
5294
5295 NotifyMotionArgs args;
5296
5297 // Verify that the coordinates are rotated.
5298 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5299 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5300 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5301 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5302 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
5303 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
5304 ASSERT_EQ(-20, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X));
5305 ASSERT_EQ(10, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
5306
5307 // Enable Pointer Capture.
5308 mFakePolicy->setPointerCapture(true);
5309 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
5310 NotifyPointerCaptureChangedArgs captureArgs;
5311 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
5312 ASSERT_TRUE(captureArgs.request.enable);
5313
5314 // Move and verify rotation is not applied.
5315 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5316 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5317 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5318 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5319 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
5320 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
5321 ASSERT_EQ(10, args.pointerCoords[0].getX());
5322 ASSERT_EQ(20, args.pointerCoords[0].getY());
5323}
5324
Prabir Pradhanc13ff082022-09-08 22:03:30 +00005325TEST_F(CursorInputMapperTest, ConfigureDisplayId_NoAssociatedViewport) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005326 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Arthur Hungc7ad2d02018-12-18 17:41:29 +08005327
Prabir Pradhanc13ff082022-09-08 22:03:30 +00005328 // Set up the default display.
5329 prepareDisplay(DISPLAY_ORIENTATION_90);
5330
5331 // Set up the secondary display as the display on which the pointer should be shown.
5332 // The InputDevice is not associated with any display.
5333 prepareSecondaryDisplay();
5334 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
Garfield Tan888a6a42020-01-09 11:39:16 -08005335 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
5336
Prabir Pradhanc13ff082022-09-08 22:03:30 +00005337 mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08005338 mFakePointerController->setPosition(100, 200);
5339 mFakePointerController->setButtonState(0);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08005340
Prabir Pradhanc13ff082022-09-08 22:03:30 +00005341 // Ensure input events are generated for the secondary display.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005342 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5343 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5344 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00005345 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan739dca42022-09-09 20:12:01 +00005346 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5347 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(SECONDARY_DISPLAY_ID),
5348 WithCoords(110.0f, 220.0f))));
Michael Wright17db18e2020-06-26 20:51:44 +01005349 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
Prabir Pradhanc13ff082022-09-08 22:03:30 +00005350}
5351
5352TEST_F(CursorInputMapperTest, ConfigureDisplayId_WithAssociatedViewport) {
5353 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
5354
5355 // Set up the default display.
5356 prepareDisplay(DISPLAY_ORIENTATION_90);
5357
5358 // Set up the secondary display as the display on which the pointer should be shown,
5359 // and associate the InputDevice with the secondary display.
5360 prepareSecondaryDisplay();
5361 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
5362 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, SECONDARY_DISPLAY_UNIQUE_ID);
5363 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
5364
5365 mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
5366 mFakePointerController->setPosition(100, 200);
5367 mFakePointerController->setButtonState(0);
5368
5369 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5370 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5371 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5372 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan739dca42022-09-09 20:12:01 +00005373 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5374 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(SECONDARY_DISPLAY_ID),
5375 WithCoords(110.0f, 220.0f))));
Prabir Pradhanc13ff082022-09-08 22:03:30 +00005376 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
5377}
5378
5379TEST_F(CursorInputMapperTest, ConfigureDisplayId_IgnoresEventsForMismatchedPointerDisplay) {
5380 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
5381
5382 // Set up the default display as the display on which the pointer should be shown.
5383 prepareDisplay(DISPLAY_ORIENTATION_90);
5384 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
5385
5386 // Associate the InputDevice with the secondary display.
5387 prepareSecondaryDisplay();
5388 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, SECONDARY_DISPLAY_UNIQUE_ID);
5389 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
5390
5391 // The mapper should not generate any events because it is associated with a display that is
5392 // different from the pointer display.
5393 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5394 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5395 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5396 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
Arthur Hungc7ad2d02018-12-18 17:41:29 +08005397}
5398
Michael Wrightd02c5b62014-02-10 15:10:22 -08005399// --- TouchInputMapperTest ---
5400
5401class TouchInputMapperTest : public InputMapperTest {
5402protected:
5403 static const int32_t RAW_X_MIN;
5404 static const int32_t RAW_X_MAX;
5405 static const int32_t RAW_Y_MIN;
5406 static const int32_t RAW_Y_MAX;
5407 static const int32_t RAW_TOUCH_MIN;
5408 static const int32_t RAW_TOUCH_MAX;
5409 static const int32_t RAW_TOOL_MIN;
5410 static const int32_t RAW_TOOL_MAX;
5411 static const int32_t RAW_PRESSURE_MIN;
5412 static const int32_t RAW_PRESSURE_MAX;
5413 static const int32_t RAW_ORIENTATION_MIN;
5414 static const int32_t RAW_ORIENTATION_MAX;
5415 static const int32_t RAW_DISTANCE_MIN;
5416 static const int32_t RAW_DISTANCE_MAX;
5417 static const int32_t RAW_TILT_MIN;
5418 static const int32_t RAW_TILT_MAX;
5419 static const int32_t RAW_ID_MIN;
5420 static const int32_t RAW_ID_MAX;
5421 static const int32_t RAW_SLOT_MIN;
5422 static const int32_t RAW_SLOT_MAX;
5423 static const float X_PRECISION;
5424 static const float Y_PRECISION;
Santos Cordonfa5cf462017-04-05 10:37:00 -07005425 static const float X_PRECISION_VIRTUAL;
5426 static const float Y_PRECISION_VIRTUAL;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005427
5428 static const float GEOMETRIC_SCALE;
Jason Gerecke489fda82012-09-07 17:19:40 -07005429 static const TouchAffineTransformation AFFINE_TRANSFORM;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005430
5431 static const VirtualKeyDefinition VIRTUAL_KEYS[2];
5432
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005433 const std::string UNIQUE_ID = "local:0";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07005434 const std::string SECONDARY_UNIQUE_ID = "local:1";
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005435
Michael Wrightd02c5b62014-02-10 15:10:22 -08005436 enum Axes {
5437 POSITION = 1 << 0,
5438 TOUCH = 1 << 1,
5439 TOOL = 1 << 2,
5440 PRESSURE = 1 << 3,
5441 ORIENTATION = 1 << 4,
5442 MINOR = 1 << 5,
5443 ID = 1 << 6,
5444 DISTANCE = 1 << 7,
5445 TILT = 1 << 8,
5446 SLOT = 1 << 9,
5447 TOOL_TYPE = 1 << 10,
5448 };
5449
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07005450 void prepareDisplay(int32_t orientation, std::optional<uint8_t> port = NO_PORT);
5451 void prepareSecondaryDisplay(ViewportType type, std::optional<uint8_t> port = NO_PORT);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005452 void prepareVirtualDisplay(int32_t orientation);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005453 void prepareVirtualKeys();
Jason Gerecke489fda82012-09-07 17:19:40 -07005454 void prepareLocationCalibration();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005455 int32_t toRawX(float displayX);
5456 int32_t toRawY(float displayY);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005457 int32_t toRotatedRawX(float displayX);
5458 int32_t toRotatedRawY(float displayY);
Jason Gerecke489fda82012-09-07 17:19:40 -07005459 float toCookedX(float rawX, float rawY);
5460 float toCookedY(float rawX, float rawY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005461 float toDisplayX(int32_t rawX);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005462 float toDisplayX(int32_t rawX, int32_t displayWidth);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005463 float toDisplayY(int32_t rawY);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005464 float toDisplayY(int32_t rawY, int32_t displayHeight);
5465
Michael Wrightd02c5b62014-02-10 15:10:22 -08005466};
5467
5468const int32_t TouchInputMapperTest::RAW_X_MIN = 25;
5469const int32_t TouchInputMapperTest::RAW_X_MAX = 1019;
5470const int32_t TouchInputMapperTest::RAW_Y_MIN = 30;
5471const int32_t TouchInputMapperTest::RAW_Y_MAX = 1009;
5472const int32_t TouchInputMapperTest::RAW_TOUCH_MIN = 0;
5473const int32_t TouchInputMapperTest::RAW_TOUCH_MAX = 31;
5474const int32_t TouchInputMapperTest::RAW_TOOL_MIN = 0;
5475const int32_t TouchInputMapperTest::RAW_TOOL_MAX = 15;
Michael Wrightaa449c92017-12-13 21:21:43 +00005476const int32_t TouchInputMapperTest::RAW_PRESSURE_MIN = 0;
5477const int32_t TouchInputMapperTest::RAW_PRESSURE_MAX = 255;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005478const int32_t TouchInputMapperTest::RAW_ORIENTATION_MIN = -7;
5479const int32_t TouchInputMapperTest::RAW_ORIENTATION_MAX = 7;
5480const int32_t TouchInputMapperTest::RAW_DISTANCE_MIN = 0;
5481const int32_t TouchInputMapperTest::RAW_DISTANCE_MAX = 7;
5482const int32_t TouchInputMapperTest::RAW_TILT_MIN = 0;
5483const int32_t TouchInputMapperTest::RAW_TILT_MAX = 150;
5484const int32_t TouchInputMapperTest::RAW_ID_MIN = 0;
5485const int32_t TouchInputMapperTest::RAW_ID_MAX = 9;
5486const int32_t TouchInputMapperTest::RAW_SLOT_MIN = 0;
5487const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9;
5488const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH;
5489const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT;
Santos Cordonfa5cf462017-04-05 10:37:00 -07005490const float TouchInputMapperTest::X_PRECISION_VIRTUAL =
5491 float(RAW_X_MAX - RAW_X_MIN + 1) / VIRTUAL_DISPLAY_WIDTH;
5492const float TouchInputMapperTest::Y_PRECISION_VIRTUAL =
5493 float(RAW_Y_MAX - RAW_Y_MIN + 1) / VIRTUAL_DISPLAY_HEIGHT;
Jason Gerecke489fda82012-09-07 17:19:40 -07005494const TouchAffineTransformation TouchInputMapperTest::AFFINE_TRANSFORM =
5495 TouchAffineTransformation(1, -2, 3, -4, 5, -6);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005496
5497const float TouchInputMapperTest::GEOMETRIC_SCALE =
5498 avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN + 1),
5499 float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN + 1));
5500
5501const VirtualKeyDefinition TouchInputMapperTest::VIRTUAL_KEYS[2] = {
5502 { KEY_HOME, 60, DISPLAY_HEIGHT + 15, 20, 20 },
5503 { KEY_MENU, DISPLAY_HEIGHT - 60, DISPLAY_WIDTH + 15, 20, 20 },
5504};
5505
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07005506void TouchInputMapperTest::prepareDisplay(int32_t orientation, std::optional<uint8_t> port) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01005507 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation, UNIQUE_ID,
5508 port, ViewportType::INTERNAL);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07005509}
5510
5511void TouchInputMapperTest::prepareSecondaryDisplay(ViewportType type, std::optional<uint8_t> port) {
5512 setDisplayInfoAndReconfigure(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
5513 DISPLAY_ORIENTATION_0, SECONDARY_UNIQUE_ID, port, type);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005514}
5515
Santos Cordonfa5cf462017-04-05 10:37:00 -07005516void TouchInputMapperTest::prepareVirtualDisplay(int32_t orientation) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01005517 setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH, VIRTUAL_DISPLAY_HEIGHT,
5518 orientation, VIRTUAL_DISPLAY_UNIQUE_ID, NO_PORT,
5519 ViewportType::VIRTUAL);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005520}
5521
Michael Wrightd02c5b62014-02-10 15:10:22 -08005522void TouchInputMapperTest::prepareVirtualKeys() {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005523 mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[0]);
5524 mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[1]);
5525 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
5526 mFakeEventHub->addKey(EVENTHUB_ID, KEY_MENU, 0, AKEYCODE_MENU, POLICY_FLAG_WAKE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005527}
5528
Jason Gerecke489fda82012-09-07 17:19:40 -07005529void TouchInputMapperTest::prepareLocationCalibration() {
5530 mFakePolicy->setTouchAffineTransformation(AFFINE_TRANSFORM);
5531}
5532
Michael Wrightd02c5b62014-02-10 15:10:22 -08005533int32_t TouchInputMapperTest::toRawX(float displayX) {
5534 return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH + RAW_X_MIN);
5535}
5536
5537int32_t TouchInputMapperTest::toRawY(float displayY) {
5538 return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT + RAW_Y_MIN);
5539}
5540
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005541int32_t TouchInputMapperTest::toRotatedRawX(float displayX) {
5542 return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_HEIGHT + RAW_X_MIN);
5543}
5544
5545int32_t TouchInputMapperTest::toRotatedRawY(float displayY) {
5546 return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_WIDTH + RAW_Y_MIN);
5547}
5548
Jason Gerecke489fda82012-09-07 17:19:40 -07005549float TouchInputMapperTest::toCookedX(float rawX, float rawY) {
5550 AFFINE_TRANSFORM.applyTo(rawX, rawY);
5551 return rawX;
5552}
5553
5554float TouchInputMapperTest::toCookedY(float rawX, float rawY) {
5555 AFFINE_TRANSFORM.applyTo(rawX, rawY);
5556 return rawY;
5557}
5558
Michael Wrightd02c5b62014-02-10 15:10:22 -08005559float TouchInputMapperTest::toDisplayX(int32_t rawX) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005560 return toDisplayX(rawX, DISPLAY_WIDTH);
5561}
5562
5563float TouchInputMapperTest::toDisplayX(int32_t rawX, int32_t displayWidth) {
5564 return float(rawX - RAW_X_MIN) * displayWidth / (RAW_X_MAX - RAW_X_MIN + 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005565}
5566
5567float TouchInputMapperTest::toDisplayY(int32_t rawY) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005568 return toDisplayY(rawY, DISPLAY_HEIGHT);
5569}
5570
5571float TouchInputMapperTest::toDisplayY(int32_t rawY, int32_t displayHeight) {
5572 return float(rawY - RAW_Y_MIN) * displayHeight / (RAW_Y_MAX - RAW_Y_MIN + 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005573}
5574
5575
5576// --- SingleTouchInputMapperTest ---
5577
5578class SingleTouchInputMapperTest : public TouchInputMapperTest {
5579protected:
5580 void prepareButtons();
5581 void prepareAxes(int axes);
5582
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005583 void processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
5584 void processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
5585 void processUp(SingleTouchInputMapper& mappery);
5586 void processPressure(SingleTouchInputMapper& mapper, int32_t pressure);
5587 void processToolMajor(SingleTouchInputMapper& mapper, int32_t toolMajor);
5588 void processDistance(SingleTouchInputMapper& mapper, int32_t distance);
5589 void processTilt(SingleTouchInputMapper& mapper, int32_t tiltX, int32_t tiltY);
5590 void processKey(SingleTouchInputMapper& mapper, int32_t code, int32_t value);
5591 void processSync(SingleTouchInputMapper& mapper);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005592};
5593
5594void SingleTouchInputMapperTest::prepareButtons() {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005595 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005596}
5597
5598void SingleTouchInputMapperTest::prepareAxes(int axes) {
5599 if (axes & POSITION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005600 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
5601 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005602 }
5603 if (axes & PRESSURE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005604 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MIN,
5605 RAW_PRESSURE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005606 }
5607 if (axes & TOOL) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005608 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TOOL_WIDTH, RAW_TOOL_MIN, RAW_TOOL_MAX, 0,
5609 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005610 }
5611 if (axes & DISTANCE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005612 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_DISTANCE, RAW_DISTANCE_MIN,
5613 RAW_DISTANCE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005614 }
5615 if (axes & TILT) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005616 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_X, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
5617 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_Y, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005618 }
5619}
5620
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005621void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005622 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
5623 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
5624 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005625}
5626
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005627void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005628 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
5629 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005630}
5631
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005632void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005633 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005634}
5635
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005636void SingleTouchInputMapperTest::processPressure(SingleTouchInputMapper& mapper, int32_t pressure) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005637 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_PRESSURE, pressure);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005638}
5639
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005640void SingleTouchInputMapperTest::processToolMajor(SingleTouchInputMapper& mapper,
5641 int32_t toolMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005642 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TOOL_WIDTH, toolMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005643}
5644
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005645void SingleTouchInputMapperTest::processDistance(SingleTouchInputMapper& mapper, int32_t distance) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005646 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_DISTANCE, distance);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005647}
5648
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005649void SingleTouchInputMapperTest::processTilt(SingleTouchInputMapper& mapper, int32_t tiltX,
5650 int32_t tiltY) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005651 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_X, tiltX);
5652 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_Y, tiltY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005653}
5654
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005655void SingleTouchInputMapperTest::processKey(SingleTouchInputMapper& mapper, int32_t code,
5656 int32_t value) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005657 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005658}
5659
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005660void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005661 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005662}
5663
Michael Wrightd02c5b62014-02-10 15:10:22 -08005664TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndNotACursor_ReturnsPointer) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005665 prepareButtons();
5666 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005667 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005668
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005669 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005670}
5671
Michael Wrightd02c5b62014-02-10 15:10:22 -08005672TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005673 prepareButtons();
5674 prepareAxes(POSITION);
5675 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005676 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005677
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005678 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005679}
5680
5681TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005682 addConfigurationProperty("touch.deviceType", "touchScreen");
5683 prepareDisplay(DISPLAY_ORIENTATION_0);
5684 prepareButtons();
5685 prepareAxes(POSITION);
5686 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005687 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005688
5689 // Unknown key.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005690 ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005691
5692 // Virtual key is down.
5693 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5694 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5695 processDown(mapper, x, y);
5696 processSync(mapper);
5697 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5698
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005699 ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005700
5701 // Virtual key is up.
5702 processUp(mapper);
5703 processSync(mapper);
5704 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5705
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005706 ASSERT_EQ(AKEY_STATE_UP, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005707}
5708
5709TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005710 addConfigurationProperty("touch.deviceType", "touchScreen");
5711 prepareDisplay(DISPLAY_ORIENTATION_0);
5712 prepareButtons();
5713 prepareAxes(POSITION);
5714 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005715 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005716
5717 // Unknown key.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005718 ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005719
5720 // Virtual key is down.
5721 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5722 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5723 processDown(mapper, x, y);
5724 processSync(mapper);
5725 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5726
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005727 ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005728
5729 // Virtual key is up.
5730 processUp(mapper);
5731 processSync(mapper);
5732 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5733
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005734 ASSERT_EQ(AKEY_STATE_UP, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005735}
5736
5737TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005738 addConfigurationProperty("touch.deviceType", "touchScreen");
5739 prepareDisplay(DISPLAY_ORIENTATION_0);
5740 prepareButtons();
5741 prepareAxes(POSITION);
5742 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005743 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005744
Michael Wrightd02c5b62014-02-10 15:10:22 -08005745 uint8_t flags[2] = { 0, 0 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07005746 ASSERT_TRUE(
5747 mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, {AKEYCODE_HOME, AKEYCODE_A}, flags));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005748 ASSERT_TRUE(flags[0]);
5749 ASSERT_FALSE(flags[1]);
5750}
5751
5752TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005753 addConfigurationProperty("touch.deviceType", "touchScreen");
5754 prepareDisplay(DISPLAY_ORIENTATION_0);
5755 prepareButtons();
5756 prepareAxes(POSITION);
5757 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005758 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005759
arthurhungdcef2dc2020-08-11 14:47:50 +08005760 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005761
5762 NotifyKeyArgs args;
5763
5764 // Press virtual key.
5765 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5766 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5767 processDown(mapper, x, y);
5768 processSync(mapper);
5769
5770 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
5771 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
5772 ASSERT_EQ(DEVICE_ID, args.deviceId);
5773 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
5774 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
5775 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
5776 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
5777 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
5778 ASSERT_EQ(KEY_HOME, args.scanCode);
5779 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
5780 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
5781
5782 // Release virtual key.
5783 processUp(mapper);
5784 processSync(mapper);
5785
5786 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
5787 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
5788 ASSERT_EQ(DEVICE_ID, args.deviceId);
5789 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
5790 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
5791 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
5792 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
5793 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
5794 ASSERT_EQ(KEY_HOME, args.scanCode);
5795 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
5796 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
5797
5798 // Should not have sent any motions.
5799 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5800}
5801
5802TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005803 addConfigurationProperty("touch.deviceType", "touchScreen");
5804 prepareDisplay(DISPLAY_ORIENTATION_0);
5805 prepareButtons();
5806 prepareAxes(POSITION);
5807 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005808 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005809
arthurhungdcef2dc2020-08-11 14:47:50 +08005810 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005811
5812 NotifyKeyArgs keyArgs;
5813
5814 // Press virtual key.
5815 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5816 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5817 processDown(mapper, x, y);
5818 processSync(mapper);
5819
5820 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5821 ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
5822 ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
5823 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
5824 ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
5825 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5826 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, keyArgs.flags);
5827 ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
5828 ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
5829 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
5830 ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
5831
5832 // Move out of bounds. This should generate a cancel and a pointer down since we moved
5833 // into the display area.
5834 y -= 100;
5835 processMove(mapper, x, y);
5836 processSync(mapper);
5837
5838 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5839 ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
5840 ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
5841 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
5842 ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
5843 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5844 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
5845 | AKEY_EVENT_FLAG_CANCELED, keyArgs.flags);
5846 ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
5847 ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
5848 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
5849 ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
5850
5851 NotifyMotionArgs motionArgs;
5852 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5853 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5854 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5855 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5856 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5857 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5858 ASSERT_EQ(0, motionArgs.flags);
5859 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5860 ASSERT_EQ(0, motionArgs.buttonState);
5861 ASSERT_EQ(0, motionArgs.edgeFlags);
5862 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5863 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5864 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5865 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5866 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5867 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5868 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5869 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5870
5871 // Keep moving out of bounds. Should generate a pointer move.
5872 y -= 50;
5873 processMove(mapper, x, y);
5874 processSync(mapper);
5875
5876 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5877 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5878 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5879 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5880 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5881 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5882 ASSERT_EQ(0, motionArgs.flags);
5883 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5884 ASSERT_EQ(0, motionArgs.buttonState);
5885 ASSERT_EQ(0, motionArgs.edgeFlags);
5886 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5887 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5888 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5889 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5890 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5891 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5892 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5893 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5894
5895 // Release out of bounds. Should generate a pointer up.
5896 processUp(mapper);
5897 processSync(mapper);
5898
5899 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5900 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5901 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5902 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5903 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5904 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5905 ASSERT_EQ(0, motionArgs.flags);
5906 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5907 ASSERT_EQ(0, motionArgs.buttonState);
5908 ASSERT_EQ(0, motionArgs.edgeFlags);
5909 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5910 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5911 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5912 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5913 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5914 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5915 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5916 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5917
5918 // Should not have sent any more keys or motions.
5919 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5920 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5921}
5922
5923TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005924 addConfigurationProperty("touch.deviceType", "touchScreen");
5925 prepareDisplay(DISPLAY_ORIENTATION_0);
5926 prepareButtons();
5927 prepareAxes(POSITION);
5928 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005929 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005930
arthurhungdcef2dc2020-08-11 14:47:50 +08005931 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005932
5933 NotifyMotionArgs motionArgs;
5934
5935 // Initially go down out of bounds.
5936 int32_t x = -10;
5937 int32_t y = -10;
5938 processDown(mapper, x, y);
5939 processSync(mapper);
5940
5941 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5942
5943 // Move into the display area. Should generate a pointer down.
5944 x = 50;
5945 y = 75;
5946 processMove(mapper, x, y);
5947 processSync(mapper);
5948
5949 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5950 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5951 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5952 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5953 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5954 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5955 ASSERT_EQ(0, motionArgs.flags);
5956 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5957 ASSERT_EQ(0, motionArgs.buttonState);
5958 ASSERT_EQ(0, motionArgs.edgeFlags);
5959 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5960 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5961 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5962 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5963 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5964 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5965 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5966 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5967
5968 // Release. Should generate a pointer up.
5969 processUp(mapper);
5970 processSync(mapper);
5971
5972 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5973 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5974 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5975 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5976 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5977 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5978 ASSERT_EQ(0, motionArgs.flags);
5979 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5980 ASSERT_EQ(0, motionArgs.buttonState);
5981 ASSERT_EQ(0, motionArgs.edgeFlags);
5982 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5983 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5984 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5985 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5986 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5987 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5988 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5989 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5990
5991 // Should not have sent any more keys or motions.
5992 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5993 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5994}
5995
Santos Cordonfa5cf462017-04-05 10:37:00 -07005996TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture_VirtualDisplay) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005997 addConfigurationProperty("touch.deviceType", "touchScreen");
5998 addConfigurationProperty("touch.displayId", VIRTUAL_DISPLAY_UNIQUE_ID);
5999
6000 prepareVirtualDisplay(DISPLAY_ORIENTATION_0);
6001 prepareButtons();
6002 prepareAxes(POSITION);
6003 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006004 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Santos Cordonfa5cf462017-04-05 10:37:00 -07006005
arthurhungdcef2dc2020-08-11 14:47:50 +08006006 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Santos Cordonfa5cf462017-04-05 10:37:00 -07006007
6008 NotifyMotionArgs motionArgs;
6009
6010 // Down.
6011 int32_t x = 100;
6012 int32_t y = 125;
6013 processDown(mapper, x, y);
6014 processSync(mapper);
6015
6016 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6017 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6018 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6019 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
6020 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6021 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6022 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6023 ASSERT_EQ(0, motionArgs.flags);
6024 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6025 ASSERT_EQ(0, motionArgs.buttonState);
6026 ASSERT_EQ(0, motionArgs.edgeFlags);
6027 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6028 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6029 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6030 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6031 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
6032 1, 0, 0, 0, 0, 0, 0, 0));
6033 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
6034 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
6035 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6036
6037 // Move.
6038 x += 50;
6039 y += 75;
6040 processMove(mapper, x, y);
6041 processSync(mapper);
6042
6043 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6044 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6045 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6046 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
6047 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6048 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6049 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6050 ASSERT_EQ(0, motionArgs.flags);
6051 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6052 ASSERT_EQ(0, motionArgs.buttonState);
6053 ASSERT_EQ(0, motionArgs.edgeFlags);
6054 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6055 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6056 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6057 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6058 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
6059 1, 0, 0, 0, 0, 0, 0, 0));
6060 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
6061 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
6062 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6063
6064 // Up.
6065 processUp(mapper);
6066 processSync(mapper);
6067
6068 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6069 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6070 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6071 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
6072 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6073 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6074 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6075 ASSERT_EQ(0, motionArgs.flags);
6076 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6077 ASSERT_EQ(0, motionArgs.buttonState);
6078 ASSERT_EQ(0, motionArgs.edgeFlags);
6079 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6080 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6081 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6082 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6083 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
6084 1, 0, 0, 0, 0, 0, 0, 0));
6085 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
6086 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
6087 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6088
6089 // Should not have sent any more keys or motions.
6090 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6091 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6092}
6093
Michael Wrightd02c5b62014-02-10 15:10:22 -08006094TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006095 addConfigurationProperty("touch.deviceType", "touchScreen");
6096 prepareDisplay(DISPLAY_ORIENTATION_0);
6097 prepareButtons();
6098 prepareAxes(POSITION);
6099 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006100 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006101
arthurhungdcef2dc2020-08-11 14:47:50 +08006102 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006103
6104 NotifyMotionArgs motionArgs;
6105
6106 // Down.
6107 int32_t x = 100;
6108 int32_t y = 125;
6109 processDown(mapper, x, y);
6110 processSync(mapper);
6111
6112 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6113 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6114 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6115 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6116 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6117 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6118 ASSERT_EQ(0, motionArgs.flags);
6119 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6120 ASSERT_EQ(0, motionArgs.buttonState);
6121 ASSERT_EQ(0, motionArgs.edgeFlags);
6122 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6123 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6124 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6125 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6126 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
6127 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6128 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6129 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6130
6131 // Move.
6132 x += 50;
6133 y += 75;
6134 processMove(mapper, x, y);
6135 processSync(mapper);
6136
6137 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6138 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6139 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6140 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6141 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6142 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6143 ASSERT_EQ(0, motionArgs.flags);
6144 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6145 ASSERT_EQ(0, motionArgs.buttonState);
6146 ASSERT_EQ(0, motionArgs.edgeFlags);
6147 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6148 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6149 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6150 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6151 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
6152 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6153 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6154 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6155
6156 // Up.
6157 processUp(mapper);
6158 processSync(mapper);
6159
6160 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6161 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6162 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6163 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6164 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6165 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6166 ASSERT_EQ(0, motionArgs.flags);
6167 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6168 ASSERT_EQ(0, motionArgs.buttonState);
6169 ASSERT_EQ(0, motionArgs.edgeFlags);
6170 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6171 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6172 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6173 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6174 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
6175 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6176 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6177 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6178
6179 // Should not have sent any more keys or motions.
6180 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6181 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6182}
6183
Prabir Pradhanc14266f2021-05-12 15:56:24 -07006184TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_DoesNotRotateMotions) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006185 addConfigurationProperty("touch.deviceType", "touchScreen");
6186 prepareButtons();
6187 prepareAxes(POSITION);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07006188 // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
6189 // need to be rotated. Touchscreens are orientation-aware by default.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006190 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006191
6192 NotifyMotionArgs args;
6193
6194 // Rotation 90.
6195 prepareDisplay(DISPLAY_ORIENTATION_90);
6196 processDown(mapper, toRawX(50), toRawY(75));
6197 processSync(mapper);
6198
6199 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6200 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6201 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6202
6203 processUp(mapper);
6204 processSync(mapper);
6205 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6206}
6207
Prabir Pradhanc14266f2021-05-12 15:56:24 -07006208TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_RotatesMotions) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006209 addConfigurationProperty("touch.deviceType", "touchScreen");
6210 prepareButtons();
6211 prepareAxes(POSITION);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07006212 // Since InputReader works in the un-rotated coordinate space, only devices that are not
6213 // orientation-aware are affected by display rotation.
6214 addConfigurationProperty("touch.orientationAware", "0");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006215 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006216
6217 NotifyMotionArgs args;
6218
6219 // Rotation 0.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07006220 clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006221 prepareDisplay(DISPLAY_ORIENTATION_0);
6222 processDown(mapper, toRawX(50), toRawY(75));
6223 processSync(mapper);
6224
6225 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6226 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6227 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6228
6229 processUp(mapper);
6230 processSync(mapper);
6231 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6232
6233 // Rotation 90.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07006234 clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006235 prepareDisplay(DISPLAY_ORIENTATION_90);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07006236 processDown(mapper, toRawX(75), RAW_Y_MAX - toRawY(50) + RAW_Y_MIN);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006237 processSync(mapper);
6238
6239 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6240 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6241 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6242
6243 processUp(mapper);
6244 processSync(mapper);
6245 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6246
6247 // Rotation 180.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07006248 clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006249 prepareDisplay(DISPLAY_ORIENTATION_180);
6250 processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
6251 processSync(mapper);
6252
6253 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6254 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6255 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6256
6257 processUp(mapper);
6258 processSync(mapper);
6259 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6260
6261 // Rotation 270.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07006262 clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006263 prepareDisplay(DISPLAY_ORIENTATION_270);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07006264 processDown(mapper, RAW_X_MAX - toRawX(75) + RAW_X_MIN, toRawY(50));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006265 processSync(mapper);
6266
6267 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6268 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6269 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6270
6271 processUp(mapper);
6272 processSync(mapper);
6273 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6274}
6275
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006276TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation0_RotatesMotions) {
6277 addConfigurationProperty("touch.deviceType", "touchScreen");
6278 prepareButtons();
6279 prepareAxes(POSITION);
6280 addConfigurationProperty("touch.orientationAware", "1");
6281 addConfigurationProperty("touch.orientation", "ORIENTATION_0");
6282 clearViewports();
6283 prepareDisplay(DISPLAY_ORIENTATION_0);
6284 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6285 NotifyMotionArgs args;
6286
6287 // Orientation 0.
6288 processDown(mapper, toRawX(50), toRawY(75));
6289 processSync(mapper);
6290
6291 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6292 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6293 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6294
6295 processUp(mapper);
6296 processSync(mapper);
6297 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6298}
6299
6300TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation90_RotatesMotions) {
6301 addConfigurationProperty("touch.deviceType", "touchScreen");
6302 prepareButtons();
6303 prepareAxes(POSITION);
6304 addConfigurationProperty("touch.orientationAware", "1");
6305 addConfigurationProperty("touch.orientation", "ORIENTATION_90");
6306 clearViewports();
6307 prepareDisplay(DISPLAY_ORIENTATION_0);
6308 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6309 NotifyMotionArgs args;
6310
6311 // Orientation 90.
6312 processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
6313 processSync(mapper);
6314
6315 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6316 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6317 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6318
6319 processUp(mapper);
6320 processSync(mapper);
6321 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6322}
6323
6324TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation180_RotatesMotions) {
6325 addConfigurationProperty("touch.deviceType", "touchScreen");
6326 prepareButtons();
6327 prepareAxes(POSITION);
6328 addConfigurationProperty("touch.orientationAware", "1");
6329 addConfigurationProperty("touch.orientation", "ORIENTATION_180");
6330 clearViewports();
6331 prepareDisplay(DISPLAY_ORIENTATION_0);
6332 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6333 NotifyMotionArgs args;
6334
6335 // Orientation 180.
6336 processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
6337 processSync(mapper);
6338
6339 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6340 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6341 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6342
6343 processUp(mapper);
6344 processSync(mapper);
6345 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6346}
6347
6348TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation270_RotatesMotions) {
6349 addConfigurationProperty("touch.deviceType", "touchScreen");
6350 prepareButtons();
6351 prepareAxes(POSITION);
6352 addConfigurationProperty("touch.orientationAware", "1");
6353 addConfigurationProperty("touch.orientation", "ORIENTATION_270");
6354 clearViewports();
6355 prepareDisplay(DISPLAY_ORIENTATION_0);
6356 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6357 NotifyMotionArgs args;
6358
6359 // Orientation 270.
6360 processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
6361 processSync(mapper);
6362
6363 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6364 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6365 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6366
6367 processUp(mapper);
6368 processSync(mapper);
6369 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6370}
6371
6372TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationSpecified_RotatesMotionWithDisplay) {
6373 addConfigurationProperty("touch.deviceType", "touchScreen");
6374 prepareButtons();
6375 prepareAxes(POSITION);
6376 // Since InputReader works in the un-rotated coordinate space, only devices that are not
6377 // orientation-aware are affected by display rotation.
6378 addConfigurationProperty("touch.orientationAware", "0");
6379 addConfigurationProperty("touch.orientation", "ORIENTATION_90");
6380 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6381
6382 NotifyMotionArgs args;
6383
6384 // Orientation 90, Rotation 0.
6385 clearViewports();
6386 prepareDisplay(DISPLAY_ORIENTATION_0);
6387 processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
6388 processSync(mapper);
6389
6390 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6391 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6392 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6393
6394 processUp(mapper);
6395 processSync(mapper);
6396 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6397
6398 // Orientation 90, Rotation 90.
6399 clearViewports();
6400 prepareDisplay(DISPLAY_ORIENTATION_90);
6401 processDown(mapper, toRotatedRawX(50), toRotatedRawY(75));
6402 processSync(mapper);
6403
6404 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6405 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6406 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6407
6408 processUp(mapper);
6409 processSync(mapper);
6410 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6411
6412 // Orientation 90, Rotation 180.
6413 clearViewports();
6414 prepareDisplay(DISPLAY_ORIENTATION_180);
6415 processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
6416 processSync(mapper);
6417
6418 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6419 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6420 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6421
6422 processUp(mapper);
6423 processSync(mapper);
6424 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6425
6426 // Orientation 90, Rotation 270.
6427 clearViewports();
6428 prepareDisplay(DISPLAY_ORIENTATION_270);
6429 processDown(mapper, RAW_X_MAX - toRotatedRawX(50) + RAW_X_MIN,
6430 RAW_Y_MAX - toRotatedRawY(75) + RAW_Y_MIN);
6431 processSync(mapper);
6432
6433 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6434 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6435 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6436
6437 processUp(mapper);
6438 processSync(mapper);
6439 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6440}
6441
Michael Wrightd02c5b62014-02-10 15:10:22 -08006442TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006443 addConfigurationProperty("touch.deviceType", "touchScreen");
6444 prepareDisplay(DISPLAY_ORIENTATION_0);
6445 prepareButtons();
6446 prepareAxes(POSITION | PRESSURE | TOOL | DISTANCE | TILT);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006447 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006448
6449 // These calculations are based on the input device calibration documentation.
6450 int32_t rawX = 100;
6451 int32_t rawY = 200;
6452 int32_t rawPressure = 10;
6453 int32_t rawToolMajor = 12;
6454 int32_t rawDistance = 2;
6455 int32_t rawTiltX = 30;
6456 int32_t rawTiltY = 110;
6457
6458 float x = toDisplayX(rawX);
6459 float y = toDisplayY(rawY);
6460 float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
6461 float size = float(rawToolMajor) / RAW_TOOL_MAX;
6462 float tool = float(rawToolMajor) * GEOMETRIC_SCALE;
6463 float distance = float(rawDistance);
6464
6465 float tiltCenter = (RAW_TILT_MAX + RAW_TILT_MIN) * 0.5f;
6466 float tiltScale = M_PI / 180;
6467 float tiltXAngle = (rawTiltX - tiltCenter) * tiltScale;
6468 float tiltYAngle = (rawTiltY - tiltCenter) * tiltScale;
6469 float orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
6470 float tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
6471
6472 processDown(mapper, rawX, rawY);
6473 processPressure(mapper, rawPressure);
6474 processToolMajor(mapper, rawToolMajor);
6475 processDistance(mapper, rawDistance);
6476 processTilt(mapper, rawTiltX, rawTiltY);
6477 processSync(mapper);
6478
6479 NotifyMotionArgs args;
6480 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6481 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
6482 x, y, pressure, size, tool, tool, tool, tool, orientation, distance));
6483 ASSERT_EQ(tilt, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TILT));
6484}
6485
Jason Gerecke489fda82012-09-07 17:19:40 -07006486TEST_F(SingleTouchInputMapperTest, Process_XYAxes_AffineCalibration) {
Jason Gerecke489fda82012-09-07 17:19:40 -07006487 addConfigurationProperty("touch.deviceType", "touchScreen");
6488 prepareDisplay(DISPLAY_ORIENTATION_0);
6489 prepareLocationCalibration();
6490 prepareButtons();
6491 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006492 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Jason Gerecke489fda82012-09-07 17:19:40 -07006493
6494 int32_t rawX = 100;
6495 int32_t rawY = 200;
6496
6497 float x = toDisplayX(toCookedX(rawX, rawY));
6498 float y = toDisplayY(toCookedY(rawX, rawY));
6499
6500 processDown(mapper, rawX, rawY);
6501 processSync(mapper);
6502
6503 NotifyMotionArgs args;
6504 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6505 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
6506 x, y, 1, 0, 0, 0, 0, 0, 0, 0));
6507}
6508
Michael Wrightd02c5b62014-02-10 15:10:22 -08006509TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006510 addConfigurationProperty("touch.deviceType", "touchScreen");
6511 prepareDisplay(DISPLAY_ORIENTATION_0);
6512 prepareButtons();
6513 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006514 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006515
6516 NotifyMotionArgs motionArgs;
6517 NotifyKeyArgs keyArgs;
6518
6519 processDown(mapper, 100, 200);
6520 processSync(mapper);
6521 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6522 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6523 ASSERT_EQ(0, motionArgs.buttonState);
6524
6525 // press BTN_LEFT, release BTN_LEFT
6526 processKey(mapper, BTN_LEFT, 1);
6527 processSync(mapper);
6528 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6529 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6530 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
6531
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006532 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6533 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6534 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
6535
Michael Wrightd02c5b62014-02-10 15:10:22 -08006536 processKey(mapper, BTN_LEFT, 0);
6537 processSync(mapper);
6538 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006539 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006540 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006541
6542 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006543 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006544 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006545
6546 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
6547 processKey(mapper, BTN_RIGHT, 1);
6548 processKey(mapper, BTN_MIDDLE, 1);
6549 processSync(mapper);
6550 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6551 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6552 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
6553 motionArgs.buttonState);
6554
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006555 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6556 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6557 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
6558
6559 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6560 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6561 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
6562 motionArgs.buttonState);
6563
Michael Wrightd02c5b62014-02-10 15:10:22 -08006564 processKey(mapper, BTN_RIGHT, 0);
6565 processSync(mapper);
6566 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006567 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006568 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006569
6570 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006571 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006572 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006573
6574 processKey(mapper, BTN_MIDDLE, 0);
6575 processSync(mapper);
6576 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006577 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006578 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006579
6580 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006581 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006582 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006583
6584 // press BTN_BACK, release BTN_BACK
6585 processKey(mapper, BTN_BACK, 1);
6586 processSync(mapper);
6587 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6588 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6589 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006590
Michael Wrightd02c5b62014-02-10 15:10:22 -08006591 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006592 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006593 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
6594
6595 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6596 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6597 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006598
6599 processKey(mapper, BTN_BACK, 0);
6600 processSync(mapper);
6601 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006602 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006603 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006604
6605 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006606 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006607 ASSERT_EQ(0, motionArgs.buttonState);
6608
Michael Wrightd02c5b62014-02-10 15:10:22 -08006609 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6610 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6611 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
6612
6613 // press BTN_SIDE, release BTN_SIDE
6614 processKey(mapper, BTN_SIDE, 1);
6615 processSync(mapper);
6616 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6617 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6618 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006619
Michael Wrightd02c5b62014-02-10 15:10:22 -08006620 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006621 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006622 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
6623
6624 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6625 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6626 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006627
6628 processKey(mapper, BTN_SIDE, 0);
6629 processSync(mapper);
6630 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006631 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006632 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006633
6634 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006635 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006636 ASSERT_EQ(0, motionArgs.buttonState);
6637
Michael Wrightd02c5b62014-02-10 15:10:22 -08006638 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6639 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6640 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
6641
6642 // press BTN_FORWARD, release BTN_FORWARD
6643 processKey(mapper, BTN_FORWARD, 1);
6644 processSync(mapper);
6645 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6646 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6647 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006648
Michael Wrightd02c5b62014-02-10 15:10:22 -08006649 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006650 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006651 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
6652
6653 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6654 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6655 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006656
6657 processKey(mapper, BTN_FORWARD, 0);
6658 processSync(mapper);
6659 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006660 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006661 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006662
6663 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006664 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006665 ASSERT_EQ(0, motionArgs.buttonState);
6666
Michael Wrightd02c5b62014-02-10 15:10:22 -08006667 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6668 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6669 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
6670
6671 // press BTN_EXTRA, release BTN_EXTRA
6672 processKey(mapper, BTN_EXTRA, 1);
6673 processSync(mapper);
6674 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6675 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6676 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006677
Michael Wrightd02c5b62014-02-10 15:10:22 -08006678 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006679 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006680 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
6681
6682 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6683 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6684 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006685
6686 processKey(mapper, BTN_EXTRA, 0);
6687 processSync(mapper);
6688 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006689 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006690 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006691
6692 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006693 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006694 ASSERT_EQ(0, motionArgs.buttonState);
6695
Michael Wrightd02c5b62014-02-10 15:10:22 -08006696 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6697 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6698 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
6699
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006700 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6701
Michael Wrightd02c5b62014-02-10 15:10:22 -08006702 // press BTN_STYLUS, release BTN_STYLUS
6703 processKey(mapper, BTN_STYLUS, 1);
6704 processSync(mapper);
6705 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6706 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006707 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
6708
6709 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6710 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6711 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006712
6713 processKey(mapper, BTN_STYLUS, 0);
6714 processSync(mapper);
6715 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006716 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006717 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006718
6719 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006720 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006721 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006722
6723 // press BTN_STYLUS2, release BTN_STYLUS2
6724 processKey(mapper, BTN_STYLUS2, 1);
6725 processSync(mapper);
6726 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6727 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006728 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
6729
6730 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6731 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6732 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006733
6734 processKey(mapper, BTN_STYLUS2, 0);
6735 processSync(mapper);
6736 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006737 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006738 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006739
6740 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006741 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006742 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006743
6744 // release touch
6745 processUp(mapper);
6746 processSync(mapper);
6747 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6748 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6749 ASSERT_EQ(0, motionArgs.buttonState);
6750}
6751
6752TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006753 addConfigurationProperty("touch.deviceType", "touchScreen");
6754 prepareDisplay(DISPLAY_ORIENTATION_0);
6755 prepareButtons();
6756 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006757 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006758
6759 NotifyMotionArgs motionArgs;
6760
6761 // default tool type is finger
6762 processDown(mapper, 100, 200);
6763 processSync(mapper);
6764 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6765 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6766 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6767
6768 // eraser
6769 processKey(mapper, BTN_TOOL_RUBBER, 1);
6770 processSync(mapper);
6771 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6772 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6773 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
6774
6775 // stylus
6776 processKey(mapper, BTN_TOOL_RUBBER, 0);
6777 processKey(mapper, BTN_TOOL_PEN, 1);
6778 processSync(mapper);
6779 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6780 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6781 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6782
6783 // brush
6784 processKey(mapper, BTN_TOOL_PEN, 0);
6785 processKey(mapper, BTN_TOOL_BRUSH, 1);
6786 processSync(mapper);
6787 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6788 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6789 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6790
6791 // pencil
6792 processKey(mapper, BTN_TOOL_BRUSH, 0);
6793 processKey(mapper, BTN_TOOL_PENCIL, 1);
6794 processSync(mapper);
6795 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6796 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6797 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6798
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08006799 // air-brush
Michael Wrightd02c5b62014-02-10 15:10:22 -08006800 processKey(mapper, BTN_TOOL_PENCIL, 0);
6801 processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
6802 processSync(mapper);
6803 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6804 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6805 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6806
6807 // mouse
6808 processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
6809 processKey(mapper, BTN_TOOL_MOUSE, 1);
6810 processSync(mapper);
6811 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6812 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6813 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
6814
6815 // lens
6816 processKey(mapper, BTN_TOOL_MOUSE, 0);
6817 processKey(mapper, BTN_TOOL_LENS, 1);
6818 processSync(mapper);
6819 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6820 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6821 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
6822
6823 // double-tap
6824 processKey(mapper, BTN_TOOL_LENS, 0);
6825 processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
6826 processSync(mapper);
6827 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6828 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6829 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6830
6831 // triple-tap
6832 processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
6833 processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
6834 processSync(mapper);
6835 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6836 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6837 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6838
6839 // quad-tap
6840 processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
6841 processKey(mapper, BTN_TOOL_QUADTAP, 1);
6842 processSync(mapper);
6843 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6844 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6845 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6846
6847 // finger
6848 processKey(mapper, BTN_TOOL_QUADTAP, 0);
6849 processKey(mapper, BTN_TOOL_FINGER, 1);
6850 processSync(mapper);
6851 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6852 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6853 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6854
6855 // stylus trumps finger
6856 processKey(mapper, BTN_TOOL_PEN, 1);
6857 processSync(mapper);
6858 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6859 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6860 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6861
6862 // eraser trumps stylus
6863 processKey(mapper, BTN_TOOL_RUBBER, 1);
6864 processSync(mapper);
6865 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6866 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6867 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
6868
6869 // mouse trumps eraser
6870 processKey(mapper, BTN_TOOL_MOUSE, 1);
6871 processSync(mapper);
6872 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6873 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6874 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
6875
6876 // back to default tool type
6877 processKey(mapper, BTN_TOOL_MOUSE, 0);
6878 processKey(mapper, BTN_TOOL_RUBBER, 0);
6879 processKey(mapper, BTN_TOOL_PEN, 0);
6880 processKey(mapper, BTN_TOOL_FINGER, 0);
6881 processSync(mapper);
6882 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6883 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6884 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6885}
6886
6887TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006888 addConfigurationProperty("touch.deviceType", "touchScreen");
6889 prepareDisplay(DISPLAY_ORIENTATION_0);
6890 prepareButtons();
6891 prepareAxes(POSITION);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006892 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_FINGER, 0, AKEYCODE_UNKNOWN, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006893 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006894
6895 NotifyMotionArgs motionArgs;
6896
6897 // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
6898 processKey(mapper, BTN_TOOL_FINGER, 1);
6899 processMove(mapper, 100, 200);
6900 processSync(mapper);
6901 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6902 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6903 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6904 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6905
6906 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6907 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6908 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6909 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6910
6911 // move a little
6912 processMove(mapper, 150, 250);
6913 processSync(mapper);
6914 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6915 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6916 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6917 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6918
6919 // down when BTN_TOUCH is pressed, pressure defaults to 1
6920 processKey(mapper, BTN_TOUCH, 1);
6921 processSync(mapper);
6922 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6923 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6924 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6925 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6926
6927 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6928 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6929 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6930 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6931
6932 // up when BTN_TOUCH is released, hover restored
6933 processKey(mapper, BTN_TOUCH, 0);
6934 processSync(mapper);
6935 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6936 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6937 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6938 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6939
6940 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6941 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6942 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6943 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6944
6945 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6946 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6947 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6948 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6949
6950 // exit hover when pointer goes away
6951 processKey(mapper, BTN_TOOL_FINGER, 0);
6952 processSync(mapper);
6953 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6954 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6955 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6956 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6957}
6958
6959TEST_F(SingleTouchInputMapperTest, Process_WhenAbsPressureIsPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006960 addConfigurationProperty("touch.deviceType", "touchScreen");
6961 prepareDisplay(DISPLAY_ORIENTATION_0);
6962 prepareButtons();
6963 prepareAxes(POSITION | PRESSURE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006964 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006965
6966 NotifyMotionArgs motionArgs;
6967
6968 // initially hovering because pressure is 0
6969 processDown(mapper, 100, 200);
6970 processPressure(mapper, 0);
6971 processSync(mapper);
6972 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6973 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6974 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6975 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6976
6977 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6978 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6979 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6980 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6981
6982 // move a little
6983 processMove(mapper, 150, 250);
6984 processSync(mapper);
6985 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6986 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6987 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6988 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6989
6990 // down when pressure is non-zero
6991 processPressure(mapper, RAW_PRESSURE_MAX);
6992 processSync(mapper);
6993 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6994 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6995 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6996 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6997
6998 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6999 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7000 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7001 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
7002
7003 // up when pressure becomes 0, hover restored
7004 processPressure(mapper, 0);
7005 processSync(mapper);
7006 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7007 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7008 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7009 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
7010
7011 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7012 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
7013 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7014 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7015
7016 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7017 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
7018 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7019 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7020
7021 // exit hover when pointer goes away
7022 processUp(mapper);
7023 processSync(mapper);
7024 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7025 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
7026 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7027 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7028}
7029
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00007030TEST_F(SingleTouchInputMapperTest, Reset_CancelsOngoingGesture) {
7031 addConfigurationProperty("touch.deviceType", "touchScreen");
7032 prepareDisplay(DISPLAY_ORIENTATION_0);
7033 prepareButtons();
7034 prepareAxes(POSITION | PRESSURE);
7035 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
7036
7037 // Touch down.
7038 processDown(mapper, 100, 200);
7039 processPressure(mapper, 1);
7040 processSync(mapper);
7041 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7042 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
7043
7044 // Reset the mapper. This should cancel the ongoing gesture.
7045 resetMapper(mapper, ARBITRARY_TIME);
7046 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7047 WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
7048
7049 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7050}
7051
Prabir Pradhanafabcde2022-09-27 19:32:43 +00007052TEST_F(SingleTouchInputMapperTest, Reset_RecreatesTouchState) {
7053 addConfigurationProperty("touch.deviceType", "touchScreen");
7054 prepareDisplay(DISPLAY_ORIENTATION_0);
7055 prepareButtons();
7056 prepareAxes(POSITION | PRESSURE);
7057 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
7058
7059 // Set the initial state for the touch pointer.
7060 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_X, 100);
7061 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_Y, 200);
7062 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MAX);
7063 mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1);
7064
7065 // Reset the mapper. When the mapper is reset, we expect it to attempt to recreate the touch
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00007066 // state by reading the current axis values. Since there was no ongoing gesture, calling reset
7067 // does not generate any events.
7068 resetMapper(mapper, ARBITRARY_TIME);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00007069
7070 // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
7071 // the recreated touch state to generate a down event.
7072 processSync(mapper);
7073 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7074 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
7075
7076 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7077}
7078
lilinnan687e58f2022-07-19 16:00:50 +08007079TEST_F(SingleTouchInputMapperTest,
7080 Process_WhenViewportDisplayIdChanged_TouchIsCanceledAndDeviceIsReset) {
7081 addConfigurationProperty("touch.deviceType", "touchScreen");
7082 prepareDisplay(DISPLAY_ORIENTATION_0);
7083 prepareButtons();
7084 prepareAxes(POSITION);
7085 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
7086 NotifyMotionArgs motionArgs;
7087
7088 // Down.
Prabir Pradhan3e5ec702022-07-29 16:26:24 +00007089 processDown(mapper, 100, 200);
lilinnan687e58f2022-07-19 16:00:50 +08007090 processSync(mapper);
7091
7092 // We should receive a down event
7093 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7094 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7095
7096 // Change display id
7097 clearViewports();
7098 prepareSecondaryDisplay(ViewportType::INTERNAL);
7099
7100 // We should receive a cancel event
7101 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7102 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
7103 // Then receive reset called
7104 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
7105}
7106
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00007107TEST_F(SingleTouchInputMapperTest,
7108 Process_WhenViewportActiveStatusChanged_TouchIsCanceledAndDeviceIsReset) {
7109 addConfigurationProperty("touch.deviceType", "touchScreen");
7110 prepareDisplay(DISPLAY_ORIENTATION_0);
7111 prepareButtons();
7112 prepareAxes(POSITION);
7113 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
7114 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
7115 NotifyMotionArgs motionArgs;
7116
7117 // Start a new gesture.
7118 processDown(mapper, 100, 200);
7119 processSync(mapper);
7120 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7121 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7122
7123 // Make the viewport inactive. This will put the device in disabled mode.
7124 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
7125 viewport->isActive = false;
7126 mFakePolicy->updateViewport(*viewport);
7127 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
7128
7129 // We should receive a cancel event for the ongoing gesture.
7130 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7131 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
7132 // Then we should be notified that the device was reset.
7133 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
7134
7135 // No events are generated while the viewport is inactive.
7136 processMove(mapper, 101, 201);
7137 processSync(mapper);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00007138 processUp(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00007139 processSync(mapper);
7140 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7141
Prabir Pradhanafabcde2022-09-27 19:32:43 +00007142 // Start a new gesture while the viewport is still inactive.
7143 processDown(mapper, 300, 400);
7144 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_X, 300);
7145 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_Y, 400);
7146 mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1);
7147 processSync(mapper);
7148
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00007149 // Make the viewport active again. The device should resume processing events.
7150 viewport->isActive = true;
7151 mFakePolicy->updateViewport(*viewport);
7152 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
7153
7154 // The device is reset because it changes back to direct mode, without generating any events.
7155 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
7156 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7157
Prabir Pradhanafabcde2022-09-27 19:32:43 +00007158 // In the next sync, the touch state that was recreated when the device was reset is reported.
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00007159 processSync(mapper);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00007160 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7161 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00007162
7163 // No more events.
7164 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7165 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
7166}
7167
Prabir Pradhan211ba622022-10-31 21:09:21 +00007168TEST_F(SingleTouchInputMapperTest, ButtonIsReleasedOnTouchUp) {
7169 addConfigurationProperty("touch.deviceType", "touchScreen");
7170 prepareDisplay(DISPLAY_ORIENTATION_0);
7171 prepareButtons();
7172 prepareAxes(POSITION);
7173 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
7174 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
7175
7176 // Press a stylus button.
7177 processKey(mapper, BTN_STYLUS, 1);
7178 processSync(mapper);
7179
7180 // Start a touch gesture and ensure the BUTTON_PRESS event is generated.
7181 processDown(mapper, 100, 200);
7182 processSync(mapper);
7183 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7184 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
7185 WithCoords(toDisplayX(100), toDisplayY(200)),
7186 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
7187 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7188 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
7189 WithCoords(toDisplayX(100), toDisplayY(200)),
7190 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
7191
7192 // Release the touch gesture. Ensure that the BUTTON_RELEASE event is generated even though
7193 // the button has not actually been released, since there will be no pointers through which the
7194 // button state can be reported. The event is generated at the location of the pointer before
7195 // it went up.
7196 processUp(mapper);
7197 processSync(mapper);
7198 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7199 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
7200 WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
7201 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7202 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
7203 WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
7204}
7205
Prabir Pradhan5632d622021-09-06 07:57:20 -07007206// --- TouchDisplayProjectionTest ---
7207
7208class TouchDisplayProjectionTest : public SingleTouchInputMapperTest {
7209public:
7210 // The values inside DisplayViewport are expected to be pre-rotated. This updates the current
7211 // DisplayViewport to pre-rotate the values. The viewport's physical display will be set to the
7212 // rotated equivalent of the given un-rotated physical display bounds.
7213 void configurePhysicalDisplay(int32_t orientation, Rect naturalPhysicalDisplay) {
7214 uint32_t inverseRotationFlags;
7215 auto width = DISPLAY_WIDTH;
7216 auto height = DISPLAY_HEIGHT;
7217 switch (orientation) {
7218 case DISPLAY_ORIENTATION_90:
7219 inverseRotationFlags = ui::Transform::ROT_270;
7220 std::swap(width, height);
7221 break;
7222 case DISPLAY_ORIENTATION_180:
7223 inverseRotationFlags = ui::Transform::ROT_180;
7224 break;
7225 case DISPLAY_ORIENTATION_270:
7226 inverseRotationFlags = ui::Transform::ROT_90;
7227 std::swap(width, height);
7228 break;
7229 case DISPLAY_ORIENTATION_0:
7230 inverseRotationFlags = ui::Transform::ROT_0;
7231 break;
7232 default:
7233 FAIL() << "Invalid orientation: " << orientation;
7234 }
7235
7236 const ui::Transform rotation(inverseRotationFlags, width, height);
7237 const Rect rotatedPhysicalDisplay = rotation.transform(naturalPhysicalDisplay);
7238
7239 std::optional<DisplayViewport> internalViewport =
7240 *mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
7241 DisplayViewport& v = *internalViewport;
7242 v.displayId = DISPLAY_ID;
7243 v.orientation = orientation;
7244
7245 v.logicalLeft = 0;
7246 v.logicalTop = 0;
7247 v.logicalRight = 100;
7248 v.logicalBottom = 100;
7249
7250 v.physicalLeft = rotatedPhysicalDisplay.left;
7251 v.physicalTop = rotatedPhysicalDisplay.top;
7252 v.physicalRight = rotatedPhysicalDisplay.right;
7253 v.physicalBottom = rotatedPhysicalDisplay.bottom;
7254
7255 v.deviceWidth = width;
7256 v.deviceHeight = height;
7257
7258 v.isActive = true;
7259 v.uniqueId = UNIQUE_ID;
7260 v.type = ViewportType::INTERNAL;
7261 mFakePolicy->updateViewport(v);
7262 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
7263 }
7264
7265 void assertReceivedMove(const Point& point) {
7266 NotifyMotionArgs motionArgs;
7267 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7268 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7269 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7270 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], point.x, point.y,
7271 1, 0, 0, 0, 0, 0, 0, 0));
7272 }
7273};
7274
7275TEST_F(TouchDisplayProjectionTest, IgnoresTouchesOutsidePhysicalDisplay) {
7276 addConfigurationProperty("touch.deviceType", "touchScreen");
7277 prepareDisplay(DISPLAY_ORIENTATION_0);
7278
7279 prepareButtons();
7280 prepareAxes(POSITION);
7281 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
7282
7283 NotifyMotionArgs motionArgs;
7284
7285 // Configure the DisplayViewport such that the logical display maps to a subsection of
7286 // the display panel called the physical display. Here, the physical display is bounded by the
7287 // points (10, 20) and (70, 160) inside the display space, which is of the size 400 x 800.
7288 static const Rect kPhysicalDisplay{10, 20, 70, 160};
7289 static const std::array<Point, 6> kPointsOutsidePhysicalDisplay{
7290 {{-10, -10}, {0, 0}, {5, 100}, {50, 15}, {75, 100}, {50, 165}}};
7291
7292 for (auto orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90, DISPLAY_ORIENTATION_180,
7293 DISPLAY_ORIENTATION_270}) {
7294 configurePhysicalDisplay(orientation, kPhysicalDisplay);
7295
7296 // Touches outside the physical display should be ignored, and should not generate any
7297 // events. Ensure touches at the following points that lie outside of the physical display
7298 // area do not generate any events.
7299 for (const auto& point : kPointsOutsidePhysicalDisplay) {
7300 processDown(mapper, toRawX(point.x), toRawY(point.y));
7301 processSync(mapper);
7302 processUp(mapper);
7303 processSync(mapper);
7304 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled())
7305 << "Unexpected event generated for touch outside physical display at point: "
7306 << point.x << ", " << point.y;
7307 }
7308 }
7309}
7310
7311TEST_F(TouchDisplayProjectionTest, EmitsTouchDownAfterEnteringPhysicalDisplay) {
7312 addConfigurationProperty("touch.deviceType", "touchScreen");
7313 prepareDisplay(DISPLAY_ORIENTATION_0);
7314
7315 prepareButtons();
7316 prepareAxes(POSITION);
7317 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
7318
7319 NotifyMotionArgs motionArgs;
7320
7321 // Configure the DisplayViewport such that the logical display maps to a subsection of
7322 // the display panel called the physical display. Here, the physical display is bounded by the
7323 // points (10, 20) and (70, 160) inside the display space, which is of the size 400 x 800.
7324 static const Rect kPhysicalDisplay{10, 20, 70, 160};
7325
7326 for (auto orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90, DISPLAY_ORIENTATION_180,
7327 DISPLAY_ORIENTATION_270}) {
7328 configurePhysicalDisplay(orientation, kPhysicalDisplay);
7329
7330 // Touches that start outside the physical display should be ignored until it enters the
7331 // physical display bounds, at which point it should generate a down event. Start a touch at
7332 // the point (5, 100), which is outside the physical display bounds.
7333 static const Point kOutsidePoint{5, 100};
7334 processDown(mapper, toRawX(kOutsidePoint.x), toRawY(kOutsidePoint.y));
7335 processSync(mapper);
7336 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7337
7338 // Move the touch into the physical display area. This should generate a pointer down.
7339 processMove(mapper, toRawX(11), toRawY(21));
7340 processSync(mapper);
7341 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7342 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7343 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7344 ASSERT_NO_FATAL_FAILURE(
7345 assertPointerCoords(motionArgs.pointerCoords[0], 11, 21, 1, 0, 0, 0, 0, 0, 0, 0));
7346
7347 // Move the touch inside the physical display area. This should generate a pointer move.
7348 processMove(mapper, toRawX(69), toRawY(159));
7349 processSync(mapper);
7350 assertReceivedMove({69, 159});
7351
7352 // Move outside the physical display area. Since the pointer is already down, this should
7353 // now continue generating events.
7354 processMove(mapper, toRawX(kOutsidePoint.x), toRawY(kOutsidePoint.y));
7355 processSync(mapper);
7356 assertReceivedMove(kOutsidePoint);
7357
7358 // Release. This should generate a pointer up.
7359 processUp(mapper);
7360 processSync(mapper);
7361 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7362 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7363 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], kOutsidePoint.x,
7364 kOutsidePoint.y, 1, 0, 0, 0, 0, 0, 0, 0));
7365
7366 // Ensure no more events were generated.
7367 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7368 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7369 }
7370}
7371
Michael Wrightd02c5b62014-02-10 15:10:22 -08007372// --- MultiTouchInputMapperTest ---
7373
7374class MultiTouchInputMapperTest : public TouchInputMapperTest {
7375protected:
7376 void prepareAxes(int axes);
7377
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007378 void processPosition(MultiTouchInputMapper& mapper, int32_t x, int32_t y);
7379 void processTouchMajor(MultiTouchInputMapper& mapper, int32_t touchMajor);
7380 void processTouchMinor(MultiTouchInputMapper& mapper, int32_t touchMinor);
7381 void processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor);
7382 void processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor);
7383 void processOrientation(MultiTouchInputMapper& mapper, int32_t orientation);
7384 void processPressure(MultiTouchInputMapper& mapper, int32_t pressure);
7385 void processDistance(MultiTouchInputMapper& mapper, int32_t distance);
7386 void processId(MultiTouchInputMapper& mapper, int32_t id);
7387 void processSlot(MultiTouchInputMapper& mapper, int32_t slot);
7388 void processToolType(MultiTouchInputMapper& mapper, int32_t toolType);
7389 void processKey(MultiTouchInputMapper& mapper, int32_t code, int32_t value);
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00007390 void processHidUsage(MultiTouchInputMapper& mapper, int32_t usageCode, int32_t value);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007391 void processMTSync(MultiTouchInputMapper& mapper);
7392 void processSync(MultiTouchInputMapper& mapper);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007393};
7394
7395void MultiTouchInputMapperTest::prepareAxes(int axes) {
7396 if (axes & POSITION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007397 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
7398 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007399 }
7400 if (axes & TOUCH) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007401 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN,
7402 RAW_TOUCH_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007403 if (axes & MINOR) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007404 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN,
7405 RAW_TOUCH_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007406 }
7407 }
7408 if (axes & TOOL) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007409 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
7410 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007411 if (axes & MINOR) {
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08007412 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007413 RAW_TOOL_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007414 }
7415 }
7416 if (axes & ORIENTATION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007417 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_ORIENTATION, RAW_ORIENTATION_MIN,
7418 RAW_ORIENTATION_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007419 }
7420 if (axes & PRESSURE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007421 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_PRESSURE, RAW_PRESSURE_MIN,
7422 RAW_PRESSURE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007423 }
7424 if (axes & DISTANCE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007425 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_DISTANCE, RAW_DISTANCE_MIN,
7426 RAW_DISTANCE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007427 }
7428 if (axes & ID) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007429 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX, 0,
7430 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007431 }
7432 if (axes & SLOT) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007433 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX, 0, 0);
7434 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007435 }
7436 if (axes & TOOL_TYPE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007437 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOOL_TYPE, 0, MT_TOOL_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007438 }
7439}
7440
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007441void MultiTouchInputMapperTest::processPosition(MultiTouchInputMapper& mapper, int32_t x,
7442 int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007443 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_X, x);
7444 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007445}
7446
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007447void MultiTouchInputMapperTest::processTouchMajor(MultiTouchInputMapper& mapper,
7448 int32_t touchMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007449 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, touchMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007450}
7451
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007452void MultiTouchInputMapperTest::processTouchMinor(MultiTouchInputMapper& mapper,
7453 int32_t touchMinor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007454 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, touchMinor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007455}
7456
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007457void MultiTouchInputMapperTest::processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007458 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_WIDTH_MAJOR, toolMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007459}
7460
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007461void MultiTouchInputMapperTest::processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007462 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_WIDTH_MINOR, toolMinor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007463}
7464
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007465void MultiTouchInputMapperTest::processOrientation(MultiTouchInputMapper& mapper,
7466 int32_t orientation) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007467 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_ORIENTATION, orientation);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007468}
7469
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007470void MultiTouchInputMapperTest::processPressure(MultiTouchInputMapper& mapper, int32_t pressure) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007471 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_PRESSURE, pressure);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007472}
7473
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007474void MultiTouchInputMapperTest::processDistance(MultiTouchInputMapper& mapper, int32_t distance) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007475 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_DISTANCE, distance);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007476}
7477
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007478void MultiTouchInputMapperTest::processId(MultiTouchInputMapper& mapper, int32_t id) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007479 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TRACKING_ID, id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007480}
7481
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007482void MultiTouchInputMapperTest::processSlot(MultiTouchInputMapper& mapper, int32_t slot) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007483 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_SLOT, slot);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007484}
7485
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007486void MultiTouchInputMapperTest::processToolType(MultiTouchInputMapper& mapper, int32_t toolType) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007487 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOOL_TYPE, toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007488}
7489
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007490void MultiTouchInputMapperTest::processKey(MultiTouchInputMapper& mapper, int32_t code,
7491 int32_t value) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007492 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007493}
7494
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00007495void MultiTouchInputMapperTest::processHidUsage(MultiTouchInputMapper& mapper, int32_t usageCode,
7496 int32_t value) {
7497 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, usageCode);
7498 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UNKNOWN, value);
7499}
7500
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007501void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007502 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_MT_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007503}
7504
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007505void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007506 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007507}
7508
Michael Wrightd02c5b62014-02-10 15:10:22 -08007509TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007510 addConfigurationProperty("touch.deviceType", "touchScreen");
7511 prepareDisplay(DISPLAY_ORIENTATION_0);
7512 prepareAxes(POSITION);
7513 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007514 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007515
arthurhungdcef2dc2020-08-11 14:47:50 +08007516 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007517
7518 NotifyMotionArgs motionArgs;
7519
7520 // Two fingers down at once.
7521 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
7522 processPosition(mapper, x1, y1);
7523 processMTSync(mapper);
7524 processPosition(mapper, x2, y2);
7525 processMTSync(mapper);
7526 processSync(mapper);
7527
7528 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7529 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7530 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7531 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7532 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7533 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7534 ASSERT_EQ(0, motionArgs.flags);
7535 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7536 ASSERT_EQ(0, motionArgs.buttonState);
7537 ASSERT_EQ(0, motionArgs.edgeFlags);
7538 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7539 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7540 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7541 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7542 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7543 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7544 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7545 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7546
7547 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7548 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7549 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7550 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7551 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007552 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007553 ASSERT_EQ(0, motionArgs.flags);
7554 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7555 ASSERT_EQ(0, motionArgs.buttonState);
7556 ASSERT_EQ(0, motionArgs.edgeFlags);
7557 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7558 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7559 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7560 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7561 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7562 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7563 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7564 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7565 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7566 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7567 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7568 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7569
7570 // Move.
7571 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
7572 processPosition(mapper, x1, y1);
7573 processMTSync(mapper);
7574 processPosition(mapper, x2, y2);
7575 processMTSync(mapper);
7576 processSync(mapper);
7577
7578 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7579 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7580 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7581 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7582 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7583 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7584 ASSERT_EQ(0, motionArgs.flags);
7585 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7586 ASSERT_EQ(0, motionArgs.buttonState);
7587 ASSERT_EQ(0, motionArgs.edgeFlags);
7588 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7589 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7590 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7591 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7592 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7593 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7594 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7595 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7596 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7597 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7598 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7599 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7600
7601 // First finger up.
7602 x2 += 15; y2 -= 20;
7603 processPosition(mapper, x2, y2);
7604 processMTSync(mapper);
7605 processSync(mapper);
7606
7607 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7608 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7609 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7610 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7611 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007612 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007613 ASSERT_EQ(0, motionArgs.flags);
7614 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7615 ASSERT_EQ(0, motionArgs.buttonState);
7616 ASSERT_EQ(0, motionArgs.edgeFlags);
7617 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7618 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7619 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7620 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7621 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7622 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7623 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7624 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7625 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7626 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7627 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7628 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7629
7630 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7631 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7632 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7633 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7634 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7635 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7636 ASSERT_EQ(0, motionArgs.flags);
7637 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7638 ASSERT_EQ(0, motionArgs.buttonState);
7639 ASSERT_EQ(0, motionArgs.edgeFlags);
7640 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7641 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7642 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7643 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7644 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7645 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7646 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7647 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7648
7649 // Move.
7650 x2 += 20; y2 -= 25;
7651 processPosition(mapper, x2, y2);
7652 processMTSync(mapper);
7653 processSync(mapper);
7654
7655 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7656 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7657 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7658 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7659 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7660 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7661 ASSERT_EQ(0, motionArgs.flags);
7662 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7663 ASSERT_EQ(0, motionArgs.buttonState);
7664 ASSERT_EQ(0, motionArgs.edgeFlags);
7665 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7666 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7667 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7668 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7669 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7670 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7671 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7672 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7673
7674 // New finger down.
7675 int32_t x3 = 700, y3 = 300;
7676 processPosition(mapper, x2, y2);
7677 processMTSync(mapper);
7678 processPosition(mapper, x3, y3);
7679 processMTSync(mapper);
7680 processSync(mapper);
7681
7682 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7683 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7684 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7685 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7686 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007687 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007688 ASSERT_EQ(0, motionArgs.flags);
7689 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7690 ASSERT_EQ(0, motionArgs.buttonState);
7691 ASSERT_EQ(0, motionArgs.edgeFlags);
7692 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7693 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7694 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7695 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7696 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7697 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7698 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7699 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7700 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7701 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7702 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7703 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7704
7705 // Second finger up.
7706 x3 += 30; y3 -= 20;
7707 processPosition(mapper, x3, y3);
7708 processMTSync(mapper);
7709 processSync(mapper);
7710
7711 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7712 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7713 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7714 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7715 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007716 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007717 ASSERT_EQ(0, motionArgs.flags);
7718 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7719 ASSERT_EQ(0, motionArgs.buttonState);
7720 ASSERT_EQ(0, motionArgs.edgeFlags);
7721 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7722 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7723 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7724 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7725 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7726 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7727 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7728 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7729 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7730 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7731 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7732 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7733
7734 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7735 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7736 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7737 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7738 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7739 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7740 ASSERT_EQ(0, motionArgs.flags);
7741 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7742 ASSERT_EQ(0, motionArgs.buttonState);
7743 ASSERT_EQ(0, motionArgs.edgeFlags);
7744 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7745 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7746 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7747 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7748 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7749 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7750 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7751 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7752
7753 // Last finger up.
7754 processMTSync(mapper);
7755 processSync(mapper);
7756
7757 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7758 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7759 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7760 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7761 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7762 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7763 ASSERT_EQ(0, motionArgs.flags);
7764 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7765 ASSERT_EQ(0, motionArgs.buttonState);
7766 ASSERT_EQ(0, motionArgs.edgeFlags);
7767 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7768 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7769 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7770 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7771 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7772 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7773 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7774 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7775
7776 // Should not have sent any more keys or motions.
7777 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7778 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7779}
7780
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08007781TEST_F(MultiTouchInputMapperTest, AxisResolution_IsPopulated) {
7782 addConfigurationProperty("touch.deviceType", "touchScreen");
7783 prepareDisplay(DISPLAY_ORIENTATION_0);
7784
7785 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
7786 /*fuzz*/ 0, /*resolution*/ 10);
7787 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
7788 /*fuzz*/ 0, /*resolution*/ 11);
7789 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
7790 /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 12);
7791 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
7792 /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 13);
7793 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
7794 /*flat*/ 0, /*flat*/ 0, /*resolution*/ 14);
7795 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
7796 /*flat*/ 0, /*flat*/ 0, /*resolution*/ 15);
7797
7798 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
7799
7800 // X and Y axes
7801 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_X, 10 / X_PRECISION);
7802 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_Y, 11 / Y_PRECISION);
7803 // Touch major and minor
7804 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR, 12 * GEOMETRIC_SCALE);
7805 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR, 13 * GEOMETRIC_SCALE);
7806 // Tool major and minor
7807 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR, 14 * GEOMETRIC_SCALE);
7808 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR, 15 * GEOMETRIC_SCALE);
7809}
7810
7811TEST_F(MultiTouchInputMapperTest, TouchMajorAndMinorAxes_DoNotAppearIfNotSupported) {
7812 addConfigurationProperty("touch.deviceType", "touchScreen");
7813 prepareDisplay(DISPLAY_ORIENTATION_0);
7814
7815 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
7816 /*fuzz*/ 0, /*resolution*/ 10);
7817 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
7818 /*fuzz*/ 0, /*resolution*/ 11);
7819
7820 // We do not add ABS_MT_TOUCH_MAJOR / MINOR or ABS_MT_WIDTH_MAJOR / MINOR axes
7821
7822 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
7823
7824 // Touch major and minor
7825 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR);
7826 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR);
7827 // Tool major and minor
7828 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR);
7829 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR);
7830}
7831
Michael Wrightd02c5b62014-02-10 15:10:22 -08007832TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007833 addConfigurationProperty("touch.deviceType", "touchScreen");
7834 prepareDisplay(DISPLAY_ORIENTATION_0);
7835 prepareAxes(POSITION | ID);
7836 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007837 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007838
arthurhungdcef2dc2020-08-11 14:47:50 +08007839 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007840
7841 NotifyMotionArgs motionArgs;
7842
7843 // Two fingers down at once.
7844 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
7845 processPosition(mapper, x1, y1);
7846 processId(mapper, 1);
7847 processMTSync(mapper);
7848 processPosition(mapper, x2, y2);
7849 processId(mapper, 2);
7850 processMTSync(mapper);
7851 processSync(mapper);
7852
7853 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7854 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7855 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7856 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7857 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7858 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7859 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7860
7861 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007862 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007863 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7864 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7865 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7866 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7867 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7868 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7869 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7870 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7871 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7872
7873 // Move.
7874 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
7875 processPosition(mapper, x1, y1);
7876 processId(mapper, 1);
7877 processMTSync(mapper);
7878 processPosition(mapper, x2, y2);
7879 processId(mapper, 2);
7880 processMTSync(mapper);
7881 processSync(mapper);
7882
7883 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7884 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7885 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7886 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7887 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7888 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7889 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7890 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7891 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7892 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7893 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7894
7895 // First finger up.
7896 x2 += 15; y2 -= 20;
7897 processPosition(mapper, x2, y2);
7898 processId(mapper, 2);
7899 processMTSync(mapper);
7900 processSync(mapper);
7901
7902 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007903 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007904 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7905 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7906 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7907 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7908 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7909 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7910 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7911 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7912 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7913
7914 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7915 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7916 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7917 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7918 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7919 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7920 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7921
7922 // Move.
7923 x2 += 20; y2 -= 25;
7924 processPosition(mapper, x2, y2);
7925 processId(mapper, 2);
7926 processMTSync(mapper);
7927 processSync(mapper);
7928
7929 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7930 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7931 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7932 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7933 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7934 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7935 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7936
7937 // New finger down.
7938 int32_t x3 = 700, y3 = 300;
7939 processPosition(mapper, x2, y2);
7940 processId(mapper, 2);
7941 processMTSync(mapper);
7942 processPosition(mapper, x3, y3);
7943 processId(mapper, 3);
7944 processMTSync(mapper);
7945 processSync(mapper);
7946
7947 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007948 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007949 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7950 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7951 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7952 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7953 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7954 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7955 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7956 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7957 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7958
7959 // Second finger up.
7960 x3 += 30; y3 -= 20;
7961 processPosition(mapper, x3, y3);
7962 processId(mapper, 3);
7963 processMTSync(mapper);
7964 processSync(mapper);
7965
7966 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007967 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007968 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7969 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7970 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7971 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7972 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7973 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7974 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7975 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7976 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7977
7978 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7979 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7980 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7981 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7982 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7983 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7984 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7985
7986 // Last finger up.
7987 processMTSync(mapper);
7988 processSync(mapper);
7989
7990 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7991 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7992 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7993 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7994 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7995 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7996 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7997
7998 // Should not have sent any more keys or motions.
7999 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
8000 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8001}
8002
8003TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithSlots) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008004 addConfigurationProperty("touch.deviceType", "touchScreen");
8005 prepareDisplay(DISPLAY_ORIENTATION_0);
8006 prepareAxes(POSITION | ID | SLOT);
8007 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008008 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008009
arthurhungdcef2dc2020-08-11 14:47:50 +08008010 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008011
8012 NotifyMotionArgs motionArgs;
8013
8014 // Two fingers down at once.
8015 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
8016 processPosition(mapper, x1, y1);
8017 processId(mapper, 1);
8018 processSlot(mapper, 1);
8019 processPosition(mapper, x2, y2);
8020 processId(mapper, 2);
8021 processSync(mapper);
8022
8023 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8024 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8025 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
8026 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
8027 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8028 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8029 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8030
8031 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008032 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008033 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
8034 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
8035 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8036 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
8037 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
8038 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8039 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8040 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8041 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8042
8043 // Move.
8044 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
8045 processSlot(mapper, 0);
8046 processPosition(mapper, x1, y1);
8047 processSlot(mapper, 1);
8048 processPosition(mapper, x2, y2);
8049 processSync(mapper);
8050
8051 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8052 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8053 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
8054 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
8055 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8056 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
8057 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
8058 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8059 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8060 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8061 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8062
8063 // First finger up.
8064 x2 += 15; y2 -= 20;
8065 processSlot(mapper, 0);
8066 processId(mapper, -1);
8067 processSlot(mapper, 1);
8068 processPosition(mapper, x2, y2);
8069 processSync(mapper);
8070
8071 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008072 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008073 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
8074 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
8075 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8076 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
8077 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
8078 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8079 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8080 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8081 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8082
8083 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8084 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8085 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
8086 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
8087 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8088 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8089 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8090
8091 // Move.
8092 x2 += 20; y2 -= 25;
8093 processPosition(mapper, x2, y2);
8094 processSync(mapper);
8095
8096 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8097 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8098 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
8099 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
8100 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8101 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8102 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8103
8104 // New finger down.
8105 int32_t x3 = 700, y3 = 300;
8106 processPosition(mapper, x2, y2);
8107 processSlot(mapper, 0);
8108 processId(mapper, 3);
8109 processPosition(mapper, x3, y3);
8110 processSync(mapper);
8111
8112 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008113 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008114 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
8115 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
8116 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8117 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
8118 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
8119 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8120 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8121 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8122 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8123
8124 // Second finger up.
8125 x3 += 30; y3 -= 20;
8126 processSlot(mapper, 1);
8127 processId(mapper, -1);
8128 processSlot(mapper, 0);
8129 processPosition(mapper, x3, y3);
8130 processSync(mapper);
8131
8132 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008133 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008134 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
8135 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
8136 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8137 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
8138 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
8139 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8140 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8141 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8142 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8143
8144 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8145 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8146 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
8147 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
8148 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8149 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8150 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8151
8152 // Last finger up.
8153 processId(mapper, -1);
8154 processSync(mapper);
8155
8156 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8157 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8158 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
8159 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
8160 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8161 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8162 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8163
8164 // Should not have sent any more keys or motions.
8165 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
8166 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8167}
8168
8169TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008170 addConfigurationProperty("touch.deviceType", "touchScreen");
8171 prepareDisplay(DISPLAY_ORIENTATION_0);
8172 prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR | DISTANCE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008173 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008174
8175 // These calculations are based on the input device calibration documentation.
8176 int32_t rawX = 100;
8177 int32_t rawY = 200;
8178 int32_t rawTouchMajor = 7;
8179 int32_t rawTouchMinor = 6;
8180 int32_t rawToolMajor = 9;
8181 int32_t rawToolMinor = 8;
8182 int32_t rawPressure = 11;
8183 int32_t rawDistance = 0;
8184 int32_t rawOrientation = 3;
8185 int32_t id = 5;
8186
8187 float x = toDisplayX(rawX);
8188 float y = toDisplayY(rawY);
8189 float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
8190 float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
8191 float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
8192 float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
8193 float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
8194 float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
8195 float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2;
8196 float distance = float(rawDistance);
8197
8198 processPosition(mapper, rawX, rawY);
8199 processTouchMajor(mapper, rawTouchMajor);
8200 processTouchMinor(mapper, rawTouchMinor);
8201 processToolMajor(mapper, rawToolMajor);
8202 processToolMinor(mapper, rawToolMinor);
8203 processPressure(mapper, rawPressure);
8204 processOrientation(mapper, rawOrientation);
8205 processDistance(mapper, rawDistance);
8206 processId(mapper, id);
8207 processMTSync(mapper);
8208 processSync(mapper);
8209
8210 NotifyMotionArgs args;
8211 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8212 ASSERT_EQ(0, args.pointerProperties[0].id);
8213 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8214 x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor,
8215 orientation, distance));
8216}
8217
8218TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008219 addConfigurationProperty("touch.deviceType", "touchScreen");
8220 prepareDisplay(DISPLAY_ORIENTATION_0);
8221 prepareAxes(POSITION | TOUCH | TOOL | MINOR);
8222 addConfigurationProperty("touch.size.calibration", "geometric");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008223 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008224
8225 // These calculations are based on the input device calibration documentation.
8226 int32_t rawX = 100;
8227 int32_t rawY = 200;
8228 int32_t rawTouchMajor = 140;
8229 int32_t rawTouchMinor = 120;
8230 int32_t rawToolMajor = 180;
8231 int32_t rawToolMinor = 160;
8232
8233 float x = toDisplayX(rawX);
8234 float y = toDisplayY(rawY);
8235 float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
8236 float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
8237 float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
8238 float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
8239 float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
8240
8241 processPosition(mapper, rawX, rawY);
8242 processTouchMajor(mapper, rawTouchMajor);
8243 processTouchMinor(mapper, rawTouchMinor);
8244 processToolMajor(mapper, rawToolMajor);
8245 processToolMinor(mapper, rawToolMinor);
8246 processMTSync(mapper);
8247 processSync(mapper);
8248
8249 NotifyMotionArgs args;
8250 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8251 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8252 x, y, 1.0f, size, touchMajor, touchMinor, toolMajor, toolMinor, 0, 0));
8253}
8254
8255TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_SummedLinearCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008256 addConfigurationProperty("touch.deviceType", "touchScreen");
8257 prepareDisplay(DISPLAY_ORIENTATION_0);
8258 prepareAxes(POSITION | TOUCH | TOOL);
8259 addConfigurationProperty("touch.size.calibration", "diameter");
8260 addConfigurationProperty("touch.size.scale", "10");
8261 addConfigurationProperty("touch.size.bias", "160");
8262 addConfigurationProperty("touch.size.isSummed", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008263 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008264
8265 // These calculations are based on the input device calibration documentation.
8266 // Note: We only provide a single common touch/tool value because the device is assumed
8267 // not to emit separate values for each pointer (isSummed = 1).
8268 int32_t rawX = 100;
8269 int32_t rawY = 200;
8270 int32_t rawX2 = 150;
8271 int32_t rawY2 = 250;
8272 int32_t rawTouchMajor = 5;
8273 int32_t rawToolMajor = 8;
8274
8275 float x = toDisplayX(rawX);
8276 float y = toDisplayY(rawY);
8277 float x2 = toDisplayX(rawX2);
8278 float y2 = toDisplayY(rawY2);
8279 float size = float(rawTouchMajor) / 2 / RAW_TOUCH_MAX;
8280 float touch = float(rawTouchMajor) / 2 * 10.0f + 160.0f;
8281 float tool = float(rawToolMajor) / 2 * 10.0f + 160.0f;
8282
8283 processPosition(mapper, rawX, rawY);
8284 processTouchMajor(mapper, rawTouchMajor);
8285 processToolMajor(mapper, rawToolMajor);
8286 processMTSync(mapper);
8287 processPosition(mapper, rawX2, rawY2);
8288 processTouchMajor(mapper, rawTouchMajor);
8289 processToolMajor(mapper, rawToolMajor);
8290 processMTSync(mapper);
8291 processSync(mapper);
8292
8293 NotifyMotionArgs args;
8294 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8295 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
8296
8297 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008298 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008299 ASSERT_EQ(size_t(2), args.pointerCount);
8300 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8301 x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
8302 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1],
8303 x2, y2, 1.0f, size, touch, touch, tool, tool, 0, 0));
8304}
8305
8306TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_AreaCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008307 addConfigurationProperty("touch.deviceType", "touchScreen");
8308 prepareDisplay(DISPLAY_ORIENTATION_0);
8309 prepareAxes(POSITION | TOUCH | TOOL);
8310 addConfigurationProperty("touch.size.calibration", "area");
8311 addConfigurationProperty("touch.size.scale", "43");
8312 addConfigurationProperty("touch.size.bias", "3");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008313 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008314
8315 // These calculations are based on the input device calibration documentation.
8316 int32_t rawX = 100;
8317 int32_t rawY = 200;
8318 int32_t rawTouchMajor = 5;
8319 int32_t rawToolMajor = 8;
8320
8321 float x = toDisplayX(rawX);
8322 float y = toDisplayY(rawY);
8323 float size = float(rawTouchMajor) / RAW_TOUCH_MAX;
8324 float touch = sqrtf(rawTouchMajor) * 43.0f + 3.0f;
8325 float tool = sqrtf(rawToolMajor) * 43.0f + 3.0f;
8326
8327 processPosition(mapper, rawX, rawY);
8328 processTouchMajor(mapper, rawTouchMajor);
8329 processToolMajor(mapper, rawToolMajor);
8330 processMTSync(mapper);
8331 processSync(mapper);
8332
8333 NotifyMotionArgs args;
8334 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8335 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8336 x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
8337}
8338
8339TEST_F(MultiTouchInputMapperTest, Process_PressureAxis_AmplitudeCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008340 addConfigurationProperty("touch.deviceType", "touchScreen");
8341 prepareDisplay(DISPLAY_ORIENTATION_0);
8342 prepareAxes(POSITION | PRESSURE);
8343 addConfigurationProperty("touch.pressure.calibration", "amplitude");
8344 addConfigurationProperty("touch.pressure.scale", "0.01");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008345 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008346
Michael Wrightaa449c92017-12-13 21:21:43 +00008347 InputDeviceInfo info;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008348 mapper.populateDeviceInfo(&info);
Michael Wrightaa449c92017-12-13 21:21:43 +00008349 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
8350 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TOUCHSCREEN,
8351 0.0f, RAW_PRESSURE_MAX * 0.01, 0.0f, 0.0f));
8352
Michael Wrightd02c5b62014-02-10 15:10:22 -08008353 // These calculations are based on the input device calibration documentation.
8354 int32_t rawX = 100;
8355 int32_t rawY = 200;
8356 int32_t rawPressure = 60;
8357
8358 float x = toDisplayX(rawX);
8359 float y = toDisplayY(rawY);
8360 float pressure = float(rawPressure) * 0.01f;
8361
8362 processPosition(mapper, rawX, rawY);
8363 processPressure(mapper, rawPressure);
8364 processMTSync(mapper);
8365 processSync(mapper);
8366
8367 NotifyMotionArgs args;
8368 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8369 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8370 x, y, pressure, 0, 0, 0, 0, 0, 0, 0));
8371}
8372
8373TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008374 addConfigurationProperty("touch.deviceType", "touchScreen");
8375 prepareDisplay(DISPLAY_ORIENTATION_0);
8376 prepareAxes(POSITION | ID | SLOT);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008377 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008378
8379 NotifyMotionArgs motionArgs;
8380 NotifyKeyArgs keyArgs;
8381
8382 processId(mapper, 1);
8383 processPosition(mapper, 100, 200);
8384 processSync(mapper);
8385 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8386 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8387 ASSERT_EQ(0, motionArgs.buttonState);
8388
8389 // press BTN_LEFT, release BTN_LEFT
8390 processKey(mapper, BTN_LEFT, 1);
8391 processSync(mapper);
8392 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8393 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8394 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
8395
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008396 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8397 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8398 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
8399
Michael Wrightd02c5b62014-02-10 15:10:22 -08008400 processKey(mapper, BTN_LEFT, 0);
8401 processSync(mapper);
8402 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008403 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008404 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008405
8406 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008407 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008408 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008409
8410 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
8411 processKey(mapper, BTN_RIGHT, 1);
8412 processKey(mapper, BTN_MIDDLE, 1);
8413 processSync(mapper);
8414 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8415 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8416 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
8417 motionArgs.buttonState);
8418
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008419 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8420 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8421 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
8422
8423 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8424 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8425 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
8426 motionArgs.buttonState);
8427
Michael Wrightd02c5b62014-02-10 15:10:22 -08008428 processKey(mapper, BTN_RIGHT, 0);
8429 processSync(mapper);
8430 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008431 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008432 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008433
8434 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008435 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008436 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008437
8438 processKey(mapper, BTN_MIDDLE, 0);
8439 processSync(mapper);
8440 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008441 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008442 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008443
8444 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008445 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008446 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008447
8448 // press BTN_BACK, release BTN_BACK
8449 processKey(mapper, BTN_BACK, 1);
8450 processSync(mapper);
8451 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8452 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
8453 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008454
Michael Wrightd02c5b62014-02-10 15:10:22 -08008455 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008456 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008457 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
8458
8459 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8460 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8461 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008462
8463 processKey(mapper, BTN_BACK, 0);
8464 processSync(mapper);
8465 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008466 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008467 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008468
8469 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008470 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008471 ASSERT_EQ(0, motionArgs.buttonState);
8472
Michael Wrightd02c5b62014-02-10 15:10:22 -08008473 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8474 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
8475 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
8476
8477 // press BTN_SIDE, release BTN_SIDE
8478 processKey(mapper, BTN_SIDE, 1);
8479 processSync(mapper);
8480 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8481 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
8482 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008483
Michael Wrightd02c5b62014-02-10 15:10:22 -08008484 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008485 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008486 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
8487
8488 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8489 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8490 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008491
8492 processKey(mapper, BTN_SIDE, 0);
8493 processSync(mapper);
8494 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008495 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008496 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008497
8498 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008499 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008500 ASSERT_EQ(0, motionArgs.buttonState);
8501
Michael Wrightd02c5b62014-02-10 15:10:22 -08008502 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8503 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
8504 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
8505
8506 // press BTN_FORWARD, release BTN_FORWARD
8507 processKey(mapper, BTN_FORWARD, 1);
8508 processSync(mapper);
8509 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8510 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
8511 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008512
Michael Wrightd02c5b62014-02-10 15:10:22 -08008513 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008514 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008515 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
8516
8517 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8518 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8519 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008520
8521 processKey(mapper, BTN_FORWARD, 0);
8522 processSync(mapper);
8523 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008524 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008525 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008526
8527 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008528 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008529 ASSERT_EQ(0, motionArgs.buttonState);
8530
Michael Wrightd02c5b62014-02-10 15:10:22 -08008531 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8532 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
8533 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
8534
8535 // press BTN_EXTRA, release BTN_EXTRA
8536 processKey(mapper, BTN_EXTRA, 1);
8537 processSync(mapper);
8538 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8539 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
8540 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008541
Michael Wrightd02c5b62014-02-10 15:10:22 -08008542 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008543 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008544 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
8545
8546 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8547 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8548 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008549
8550 processKey(mapper, BTN_EXTRA, 0);
8551 processSync(mapper);
8552 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008553 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008554 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008555
8556 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008557 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008558 ASSERT_EQ(0, motionArgs.buttonState);
8559
Michael Wrightd02c5b62014-02-10 15:10:22 -08008560 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8561 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
8562 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
8563
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008564 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
8565
Michael Wrightd02c5b62014-02-10 15:10:22 -08008566 // press BTN_STYLUS, release BTN_STYLUS
8567 processKey(mapper, BTN_STYLUS, 1);
8568 processSync(mapper);
8569 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8570 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008571 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
8572
8573 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8574 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8575 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008576
8577 processKey(mapper, BTN_STYLUS, 0);
8578 processSync(mapper);
8579 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008580 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008581 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008582
8583 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008584 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008585 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008586
8587 // press BTN_STYLUS2, release BTN_STYLUS2
8588 processKey(mapper, BTN_STYLUS2, 1);
8589 processSync(mapper);
8590 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8591 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008592 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
8593
8594 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8595 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8596 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008597
8598 processKey(mapper, BTN_STYLUS2, 0);
8599 processSync(mapper);
8600 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008601 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008602 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008603
8604 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008605 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008606 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008607
8608 // release touch
8609 processId(mapper, -1);
8610 processSync(mapper);
8611 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8612 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8613 ASSERT_EQ(0, motionArgs.buttonState);
8614}
8615
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00008616TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleMappedStylusButtons) {
8617 addConfigurationProperty("touch.deviceType", "touchScreen");
8618 prepareDisplay(DISPLAY_ORIENTATION_0);
8619 prepareAxes(POSITION | ID | SLOT);
8620 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8621
8622 mFakeEventHub->addKey(EVENTHUB_ID, BTN_A, 0, AKEYCODE_STYLUS_BUTTON_PRIMARY, 0);
8623 mFakeEventHub->addKey(EVENTHUB_ID, 0, 0xabcd, AKEYCODE_STYLUS_BUTTON_SECONDARY, 0);
8624
8625 // Touch down.
8626 processId(mapper, 1);
8627 processPosition(mapper, 100, 200);
8628 processSync(mapper);
8629 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8630 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithButtonState(0))));
8631
8632 // Press and release button mapped to the primary stylus button.
8633 processKey(mapper, BTN_A, 1);
8634 processSync(mapper);
8635 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8636 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
8637 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
8638 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8639 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
8640 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
8641
8642 processKey(mapper, BTN_A, 0);
8643 processSync(mapper);
8644 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8645 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithButtonState(0))));
8646 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8647 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
8648
8649 // Press and release the HID usage mapped to the secondary stylus button.
8650 processHidUsage(mapper, 0xabcd, 1);
8651 processSync(mapper);
8652 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8653 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
8654 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY))));
8655 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8656 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
8657 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY))));
8658
8659 processHidUsage(mapper, 0xabcd, 0);
8660 processSync(mapper);
8661 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8662 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithButtonState(0))));
8663 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8664 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
8665
8666 // Release touch.
8667 processId(mapper, -1);
8668 processSync(mapper);
8669 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8670 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
8671}
8672
Michael Wrightd02c5b62014-02-10 15:10:22 -08008673TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008674 addConfigurationProperty("touch.deviceType", "touchScreen");
8675 prepareDisplay(DISPLAY_ORIENTATION_0);
8676 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008677 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008678
8679 NotifyMotionArgs motionArgs;
8680
8681 // default tool type is finger
8682 processId(mapper, 1);
8683 processPosition(mapper, 100, 200);
8684 processSync(mapper);
8685 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8686 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8687 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8688
8689 // eraser
8690 processKey(mapper, BTN_TOOL_RUBBER, 1);
8691 processSync(mapper);
8692 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8693 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8694 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
8695
8696 // stylus
8697 processKey(mapper, BTN_TOOL_RUBBER, 0);
8698 processKey(mapper, BTN_TOOL_PEN, 1);
8699 processSync(mapper);
8700 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8701 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8702 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8703
8704 // brush
8705 processKey(mapper, BTN_TOOL_PEN, 0);
8706 processKey(mapper, BTN_TOOL_BRUSH, 1);
8707 processSync(mapper);
8708 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8709 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8710 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8711
8712 // pencil
8713 processKey(mapper, BTN_TOOL_BRUSH, 0);
8714 processKey(mapper, BTN_TOOL_PENCIL, 1);
8715 processSync(mapper);
8716 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8717 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8718 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8719
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08008720 // air-brush
Michael Wrightd02c5b62014-02-10 15:10:22 -08008721 processKey(mapper, BTN_TOOL_PENCIL, 0);
8722 processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
8723 processSync(mapper);
8724 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8725 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8726 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8727
8728 // mouse
8729 processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
8730 processKey(mapper, BTN_TOOL_MOUSE, 1);
8731 processSync(mapper);
8732 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8733 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8734 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
8735
8736 // lens
8737 processKey(mapper, BTN_TOOL_MOUSE, 0);
8738 processKey(mapper, BTN_TOOL_LENS, 1);
8739 processSync(mapper);
8740 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8741 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8742 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
8743
8744 // double-tap
8745 processKey(mapper, BTN_TOOL_LENS, 0);
8746 processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
8747 processSync(mapper);
8748 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8749 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8750 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8751
8752 // triple-tap
8753 processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
8754 processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
8755 processSync(mapper);
8756 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8757 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8758 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8759
8760 // quad-tap
8761 processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
8762 processKey(mapper, BTN_TOOL_QUADTAP, 1);
8763 processSync(mapper);
8764 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8765 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8766 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8767
8768 // finger
8769 processKey(mapper, BTN_TOOL_QUADTAP, 0);
8770 processKey(mapper, BTN_TOOL_FINGER, 1);
8771 processSync(mapper);
8772 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8773 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8774 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8775
8776 // stylus trumps finger
8777 processKey(mapper, BTN_TOOL_PEN, 1);
8778 processSync(mapper);
8779 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8780 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8781 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8782
8783 // eraser trumps stylus
8784 processKey(mapper, BTN_TOOL_RUBBER, 1);
8785 processSync(mapper);
8786 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8787 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8788 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
8789
8790 // mouse trumps eraser
8791 processKey(mapper, BTN_TOOL_MOUSE, 1);
8792 processSync(mapper);
8793 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8794 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8795 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
8796
8797 // MT tool type trumps BTN tool types: MT_TOOL_FINGER
8798 processToolType(mapper, MT_TOOL_FINGER); // this is the first time we send MT_TOOL_TYPE
8799 processSync(mapper);
8800 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8801 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8802 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8803
8804 // MT tool type trumps BTN tool types: MT_TOOL_PEN
8805 processToolType(mapper, MT_TOOL_PEN);
8806 processSync(mapper);
8807 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8808 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8809 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8810
8811 // back to default tool type
8812 processToolType(mapper, -1); // use a deliberately undefined tool type, for testing
8813 processKey(mapper, BTN_TOOL_MOUSE, 0);
8814 processKey(mapper, BTN_TOOL_RUBBER, 0);
8815 processKey(mapper, BTN_TOOL_PEN, 0);
8816 processKey(mapper, BTN_TOOL_FINGER, 0);
8817 processSync(mapper);
8818 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8819 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8820 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8821}
8822
8823TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008824 addConfigurationProperty("touch.deviceType", "touchScreen");
8825 prepareDisplay(DISPLAY_ORIENTATION_0);
8826 prepareAxes(POSITION | ID | SLOT);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008827 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008828 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008829
8830 NotifyMotionArgs motionArgs;
8831
8832 // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
8833 processId(mapper, 1);
8834 processPosition(mapper, 100, 200);
8835 processSync(mapper);
8836 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8837 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8838 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8839 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8840
8841 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8842 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8843 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8844 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8845
8846 // move a little
8847 processPosition(mapper, 150, 250);
8848 processSync(mapper);
8849 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8850 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8851 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8852 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8853
8854 // down when BTN_TOUCH is pressed, pressure defaults to 1
8855 processKey(mapper, BTN_TOUCH, 1);
8856 processSync(mapper);
8857 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8858 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8859 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8860 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8861
8862 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8863 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8864 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8865 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
8866
8867 // up when BTN_TOUCH is released, hover restored
8868 processKey(mapper, BTN_TOUCH, 0);
8869 processSync(mapper);
8870 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8871 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8872 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8873 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
8874
8875 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8876 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8877 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8878 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8879
8880 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8881 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8882 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8883 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8884
8885 // exit hover when pointer goes away
8886 processId(mapper, -1);
8887 processSync(mapper);
8888 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8889 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8890 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8891 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8892}
8893
8894TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTPressureIsPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008895 addConfigurationProperty("touch.deviceType", "touchScreen");
8896 prepareDisplay(DISPLAY_ORIENTATION_0);
8897 prepareAxes(POSITION | ID | SLOT | PRESSURE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008898 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008899
8900 NotifyMotionArgs motionArgs;
8901
8902 // initially hovering because pressure is 0
8903 processId(mapper, 1);
8904 processPosition(mapper, 100, 200);
8905 processPressure(mapper, 0);
8906 processSync(mapper);
8907 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8908 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8909 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8910 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8911
8912 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8913 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8914 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8915 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8916
8917 // move a little
8918 processPosition(mapper, 150, 250);
8919 processSync(mapper);
8920 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8921 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8922 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8923 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8924
8925 // down when pressure becomes non-zero
8926 processPressure(mapper, RAW_PRESSURE_MAX);
8927 processSync(mapper);
8928 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8929 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8930 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8931 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8932
8933 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8934 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8935 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8936 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
8937
8938 // up when pressure becomes 0, hover restored
8939 processPressure(mapper, 0);
8940 processSync(mapper);
8941 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8942 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8943 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8944 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
8945
8946 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8947 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8948 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8949 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8950
8951 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8952 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8953 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8954 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8955
8956 // exit hover when pointer goes away
8957 processId(mapper, -1);
8958 processSync(mapper);
8959 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8960 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8961 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8962 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8963}
8964
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008965/**
8966 * Set the input device port <--> display port associations, and check that the
8967 * events are routed to the display that matches the display port.
8968 * This can be checked by looking at the displayId of the resulting NotifyMotionArgs.
8969 */
8970TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayPort) {
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008971 const std::string usb2 = "USB2";
8972 const uint8_t hdmi1 = 0;
8973 const uint8_t hdmi2 = 1;
8974 const std::string secondaryUniqueId = "uniqueId2";
Michael Wrightfe3de7d2020-07-02 19:05:30 +01008975 constexpr ViewportType type = ViewportType::EXTERNAL;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008976
8977 addConfigurationProperty("touch.deviceType", "touchScreen");
8978 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008979 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008980
8981 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
8982 mFakePolicy->addInputPortAssociation(usb2, hdmi2);
8983
8984 // We are intentionally not adding the viewport for display 1 yet. Since the port association
8985 // for this input device is specified, and the matching viewport is not present,
8986 // the input device should be disabled (at the mapper level).
8987
8988 // Add viewport for display 2 on hdmi2
8989 prepareSecondaryDisplay(type, hdmi2);
8990 // Send a touch event
8991 processPosition(mapper, 100, 100);
8992 processSync(mapper);
8993 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8994
8995 // Add viewport for display 1 on hdmi1
8996 prepareDisplay(DISPLAY_ORIENTATION_0, hdmi1);
8997 // Send a touch event again
8998 processPosition(mapper, 100, 100);
8999 processSync(mapper);
9000
9001 NotifyMotionArgs args;
9002 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9003 ASSERT_EQ(DISPLAY_ID, args.displayId);
9004}
Michael Wrightd02c5b62014-02-10 15:10:22 -08009005
Arthur Hung6d5b4b22022-01-21 07:21:10 +00009006TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayUniqueId) {
9007 addConfigurationProperty("touch.deviceType", "touchScreen");
9008 prepareAxes(POSITION);
9009 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9010
9011 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
9012
9013 prepareDisplay(DISPLAY_ORIENTATION_0);
9014 prepareVirtualDisplay(DISPLAY_ORIENTATION_0);
9015
9016 // Send a touch event
9017 processPosition(mapper, 100, 100);
9018 processSync(mapper);
9019
9020 NotifyMotionArgs args;
9021 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9022 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
9023}
9024
Arthur Hungc7ad2d02018-12-18 17:41:29 +08009025TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
Garfield Tan888a6a42020-01-09 11:39:16 -08009026 // Setup for second display.
Michael Wright17db18e2020-06-26 20:51:44 +01009027 std::shared_ptr<FakePointerController> fakePointerController =
9028 std::make_shared<FakePointerController>();
Garfield Tan888a6a42020-01-09 11:39:16 -08009029 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08009030 fakePointerController->setPosition(100, 200);
9031 fakePointerController->setButtonState(0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009032 mFakePolicy->setPointerController(fakePointerController);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08009033
Garfield Tan888a6a42020-01-09 11:39:16 -08009034 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009035 prepareSecondaryDisplay(ViewportType::EXTERNAL);
Garfield Tan888a6a42020-01-09 11:39:16 -08009036
Arthur Hungc7ad2d02018-12-18 17:41:29 +08009037 prepareDisplay(DISPLAY_ORIENTATION_0);
9038 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009039 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hungc7ad2d02018-12-18 17:41:29 +08009040
9041 // Check source is mouse that would obtain the PointerController.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009042 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Arthur Hungc7ad2d02018-12-18 17:41:29 +08009043
9044 NotifyMotionArgs motionArgs;
9045 processPosition(mapper, 100, 100);
9046 processSync(mapper);
9047
9048 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9049 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
9050 ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
9051}
9052
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00009053/**
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00009054 * Ensure that the readTime is set to the SYN_REPORT value when processing touch events.
9055 */
9056TEST_F(MultiTouchInputMapperTest, Process_SendsReadTime) {
9057 addConfigurationProperty("touch.deviceType", "touchScreen");
9058 prepareAxes(POSITION);
9059 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9060
9061 prepareDisplay(DISPLAY_ORIENTATION_0);
9062 process(mapper, 10, 11 /*readTime*/, EV_ABS, ABS_MT_TRACKING_ID, 1);
9063 process(mapper, 15, 16 /*readTime*/, EV_ABS, ABS_MT_POSITION_X, 100);
9064 process(mapper, 20, 21 /*readTime*/, EV_ABS, ABS_MT_POSITION_Y, 100);
9065 process(mapper, 25, 26 /*readTime*/, EV_SYN, SYN_REPORT, 0);
9066
9067 NotifyMotionArgs args;
9068 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9069 ASSERT_EQ(26, args.readTime);
9070
9071 process(mapper, 30, 31 /*readTime*/, EV_ABS, ABS_MT_POSITION_X, 110);
9072 process(mapper, 30, 32 /*readTime*/, EV_ABS, ABS_MT_POSITION_Y, 220);
9073 process(mapper, 30, 33 /*readTime*/, EV_SYN, SYN_REPORT, 0);
9074
9075 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9076 ASSERT_EQ(33, args.readTime);
9077}
9078
9079/**
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00009080 * When the viewport is not active (isActive=false), the touch mapper should be disabled and the
9081 * events should not be delivered to the listener.
9082 */
9083TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreDropped) {
9084 addConfigurationProperty("touch.deviceType", "touchScreen");
9085 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
9086 DISPLAY_ORIENTATION_0, false /*isActive*/, UNIQUE_ID, NO_PORT,
9087 ViewportType::INTERNAL);
9088 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
9089 prepareAxes(POSITION);
9090 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9091
9092 NotifyMotionArgs motionArgs;
9093 processPosition(mapper, 100, 100);
9094 processSync(mapper);
9095
9096 mFakeListener->assertNotifyMotionWasNotCalled();
9097}
9098
Garfield Tanc734e4f2021-01-15 20:01:39 -08009099TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_AbortTouches) {
9100 addConfigurationProperty("touch.deviceType", "touchScreen");
9101 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
9102 DISPLAY_ORIENTATION_0, true /*isActive*/, UNIQUE_ID, NO_PORT,
9103 ViewportType::INTERNAL);
9104 std::optional<DisplayViewport> optionalDisplayViewport =
9105 mFakePolicy->getDisplayViewportByUniqueId(UNIQUE_ID);
9106 ASSERT_TRUE(optionalDisplayViewport.has_value());
9107 DisplayViewport displayViewport = *optionalDisplayViewport;
9108
9109 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
9110 prepareAxes(POSITION);
9111 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9112
9113 // Finger down
9114 int32_t x = 100, y = 100;
9115 processPosition(mapper, x, y);
9116 processSync(mapper);
9117
9118 NotifyMotionArgs motionArgs;
9119 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9120 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9121
9122 // Deactivate display viewport
9123 displayViewport.isActive = false;
9124 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
9125 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
9126
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00009127 // The ongoing touch should be canceled immediately
9128 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9129 EXPECT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
9130
9131 // Finger move is ignored
Garfield Tanc734e4f2021-01-15 20:01:39 -08009132 x += 10, y += 10;
9133 processPosition(mapper, x, y);
9134 processSync(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00009135 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
Garfield Tanc734e4f2021-01-15 20:01:39 -08009136
9137 // Reactivate display viewport
9138 displayViewport.isActive = true;
9139 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
9140 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
9141
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00009142 // Finger move again starts new gesture
Garfield Tanc734e4f2021-01-15 20:01:39 -08009143 x += 10, y += 10;
9144 processPosition(mapper, x, y);
9145 processSync(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00009146 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9147 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Garfield Tanc734e4f2021-01-15 20:01:39 -08009148}
9149
Arthur Hung7c645402019-01-25 17:45:42 +08009150TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) {
9151 // Setup the first touch screen device.
Arthur Hung7c645402019-01-25 17:45:42 +08009152 prepareAxes(POSITION | ID | SLOT);
9153 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009154 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung7c645402019-01-25 17:45:42 +08009155
9156 // Create the second touch screen device, and enable multi fingers.
9157 const std::string USB2 = "USB2";
arthurhungdcef2dc2020-08-11 14:47:50 +08009158 const std::string DEVICE_NAME2 = "TOUCHSCREEN2";
Arthur Hung2c9a3342019-07-23 14:18:59 +08009159 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009160 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
arthurhungdcef2dc2020-08-11 14:47:50 +08009161 std::shared_ptr<InputDevice> device2 =
9162 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07009163 ftl::Flags<InputDeviceClass>(0));
arthurhungdcef2dc2020-08-11 14:47:50 +08009164
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009165 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
9166 0 /*flat*/, 0 /*fuzz*/);
9167 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
9168 0 /*flat*/, 0 /*fuzz*/);
9169 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX,
9170 0 /*flat*/, 0 /*fuzz*/);
9171 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX,
9172 0 /*flat*/, 0 /*fuzz*/);
9173 mFakeEventHub->setAbsoluteAxisValue(SECOND_EVENTHUB_ID, ABS_MT_SLOT, 0 /*value*/);
9174 mFakeEventHub->addConfigurationProperty(SECOND_EVENTHUB_ID, String8("touch.deviceType"),
9175 String8("touchScreen"));
Arthur Hung7c645402019-01-25 17:45:42 +08009176
9177 // Setup the second touch screen device.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009178 MultiTouchInputMapper& mapper2 = device2->addMapper<MultiTouchInputMapper>(SECOND_EVENTHUB_ID);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009179 std::list<NotifyArgs> unused =
9180 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
9181 0 /*changes*/);
9182 unused += device2->reset(ARBITRARY_TIME);
Arthur Hung7c645402019-01-25 17:45:42 +08009183
9184 // Setup PointerController.
Michael Wright17db18e2020-06-26 20:51:44 +01009185 std::shared_ptr<FakePointerController> fakePointerController =
9186 std::make_shared<FakePointerController>();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009187 mFakePolicy->setPointerController(fakePointerController);
Arthur Hung7c645402019-01-25 17:45:42 +08009188
9189 // Setup policy for associated displays and show touches.
9190 const uint8_t hdmi1 = 0;
9191 const uint8_t hdmi2 = 1;
9192 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
9193 mFakePolicy->addInputPortAssociation(USB2, hdmi2);
9194 mFakePolicy->setShowTouches(true);
9195
9196 // Create displays.
9197 prepareDisplay(DISPLAY_ORIENTATION_0, hdmi1);
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009198 prepareSecondaryDisplay(ViewportType::EXTERNAL, hdmi2);
Arthur Hung7c645402019-01-25 17:45:42 +08009199
9200 // Default device will reconfigure above, need additional reconfiguration for another device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009201 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
9202 InputReaderConfiguration::CHANGE_DISPLAY_INFO |
9203 InputReaderConfiguration::CHANGE_SHOW_TOUCHES);
Arthur Hung7c645402019-01-25 17:45:42 +08009204
9205 // Two fingers down at default display.
9206 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
9207 processPosition(mapper, x1, y1);
9208 processId(mapper, 1);
9209 processSlot(mapper, 1);
9210 processPosition(mapper, x2, y2);
9211 processId(mapper, 2);
9212 processSync(mapper);
9213
9214 std::map<int32_t, std::vector<int32_t>>::const_iterator iter =
9215 fakePointerController->getSpots().find(DISPLAY_ID);
9216 ASSERT_TRUE(iter != fakePointerController->getSpots().end());
9217 ASSERT_EQ(size_t(2), iter->second.size());
9218
9219 // Two fingers down at second display.
9220 processPosition(mapper2, x1, y1);
9221 processId(mapper2, 1);
9222 processSlot(mapper2, 1);
9223 processPosition(mapper2, x2, y2);
9224 processId(mapper2, 2);
9225 processSync(mapper2);
9226
9227 iter = fakePointerController->getSpots().find(SECONDARY_DISPLAY_ID);
9228 ASSERT_TRUE(iter != fakePointerController->getSpots().end());
9229 ASSERT_EQ(size_t(2), iter->second.size());
Prabir Pradhan197e0862022-07-01 14:28:00 +00009230
9231 // Disable the show touches configuration and ensure the spots are cleared.
9232 mFakePolicy->setShowTouches(false);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009233 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
9234 InputReaderConfiguration::CHANGE_SHOW_TOUCHES);
Prabir Pradhan197e0862022-07-01 14:28:00 +00009235
9236 ASSERT_TRUE(fakePointerController->getSpots().empty());
Arthur Hung7c645402019-01-25 17:45:42 +08009237}
9238
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009239TEST_F(MultiTouchInputMapperTest, VideoFrames_ReceivedByListener) {
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009240 prepareAxes(POSITION);
9241 addConfigurationProperty("touch.deviceType", "touchScreen");
9242 prepareDisplay(DISPLAY_ORIENTATION_0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009243 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009244
9245 NotifyMotionArgs motionArgs;
9246 // Unrotated video frame
9247 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9248 std::vector<TouchVideoFrame> frames{frame};
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009249 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009250 processPosition(mapper, 100, 200);
9251 processSync(mapper);
9252 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9253 ASSERT_EQ(frames, motionArgs.videoFrames);
9254
9255 // Subsequent touch events should not have any videoframes
9256 // This is implemented separately in FakeEventHub,
9257 // but that should match the behaviour of TouchVideoDevice.
9258 processPosition(mapper, 200, 200);
9259 processSync(mapper);
9260 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9261 ASSERT_EQ(std::vector<TouchVideoFrame>(), motionArgs.videoFrames);
9262}
9263
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009264TEST_F(MultiTouchInputMapperTest, VideoFrames_AreNotRotated) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009265 prepareAxes(POSITION);
9266 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009267 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009268 // Unrotated video frame
9269 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9270 NotifyMotionArgs motionArgs;
9271
9272 // Test all 4 orientations
9273 for (int32_t orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90,
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009274 DISPLAY_ORIENTATION_180, DISPLAY_ORIENTATION_270}) {
9275 SCOPED_TRACE("Orientation " + StringPrintf("%i", orientation));
9276 clearViewports();
9277 prepareDisplay(orientation);
9278 std::vector<TouchVideoFrame> frames{frame};
9279 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
9280 processPosition(mapper, 100, 200);
9281 processSync(mapper);
9282 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9283 ASSERT_EQ(frames, motionArgs.videoFrames);
9284 }
9285}
9286
9287TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_AreRotated) {
9288 prepareAxes(POSITION);
9289 addConfigurationProperty("touch.deviceType", "touchScreen");
9290 // Since InputReader works in the un-rotated coordinate space, only devices that are not
9291 // orientation-aware are affected by display rotation.
9292 addConfigurationProperty("touch.orientationAware", "0");
9293 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9294 // Unrotated video frame
9295 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9296 NotifyMotionArgs motionArgs;
9297
9298 // Test all 4 orientations
9299 for (int32_t orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90,
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009300 DISPLAY_ORIENTATION_180, DISPLAY_ORIENTATION_270}) {
9301 SCOPED_TRACE("Orientation " + StringPrintf("%i", orientation));
9302 clearViewports();
9303 prepareDisplay(orientation);
9304 std::vector<TouchVideoFrame> frames{frame};
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009305 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009306 processPosition(mapper, 100, 200);
9307 processSync(mapper);
9308 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009309 // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
9310 // compared to the display. This is so that when the window transform (which contains the
9311 // display rotation) is applied later by InputDispatcher, the coordinates end up in the
9312 // window's coordinate space.
9313 frames[0].rotate(getInverseRotation(orientation));
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009314 ASSERT_EQ(frames, motionArgs.videoFrames);
lilinnan687e58f2022-07-19 16:00:50 +08009315
9316 // Release finger.
9317 processSync(mapper);
9318 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009319 }
9320}
9321
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009322TEST_F(MultiTouchInputMapperTest, VideoFrames_MultipleFramesAreNotRotated) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009323 prepareAxes(POSITION);
9324 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009325 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009326 // Unrotated video frames. There's no rule that they must all have the same dimensions,
9327 // so mix these.
9328 TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9329 TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
9330 TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
9331 std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
9332 NotifyMotionArgs motionArgs;
9333
9334 prepareDisplay(DISPLAY_ORIENTATION_90);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009335 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009336 processPosition(mapper, 100, 200);
9337 processSync(mapper);
9338 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009339 ASSERT_EQ(frames, motionArgs.videoFrames);
9340}
9341
9342TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_MultipleFramesAreRotated) {
9343 prepareAxes(POSITION);
9344 addConfigurationProperty("touch.deviceType", "touchScreen");
9345 // Since InputReader works in the un-rotated coordinate space, only devices that are not
9346 // orientation-aware are affected by display rotation.
9347 addConfigurationProperty("touch.orientationAware", "0");
9348 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9349 // Unrotated video frames. There's no rule that they must all have the same dimensions,
9350 // so mix these.
9351 TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9352 TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
9353 TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
9354 std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
9355 NotifyMotionArgs motionArgs;
9356
9357 prepareDisplay(DISPLAY_ORIENTATION_90);
9358 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
9359 processPosition(mapper, 100, 200);
9360 processSync(mapper);
9361 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9362 std::for_each(frames.begin(), frames.end(), [](TouchVideoFrame& frame) {
9363 // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
9364 // compared to the display. This is so that when the window transform (which contains the
9365 // display rotation) is applied later by InputDispatcher, the coordinates end up in the
9366 // window's coordinate space.
9367 frame.rotate(getInverseRotation(DISPLAY_ORIENTATION_90));
9368 });
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009369 ASSERT_EQ(frames, motionArgs.videoFrames);
9370}
9371
Arthur Hung9da14732019-09-02 16:16:58 +08009372/**
9373 * If we had defined port associations, but the viewport is not ready, the touch device would be
9374 * expected to be disabled, and it should be enabled after the viewport has found.
9375 */
9376TEST_F(MultiTouchInputMapperTest, Configure_EnabledForAssociatedDisplay) {
Arthur Hung9da14732019-09-02 16:16:58 +08009377 constexpr uint8_t hdmi2 = 1;
9378 const std::string secondaryUniqueId = "uniqueId2";
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009379 constexpr ViewportType type = ViewportType::EXTERNAL;
Arthur Hung9da14732019-09-02 16:16:58 +08009380
9381 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi2);
9382
9383 addConfigurationProperty("touch.deviceType", "touchScreen");
9384 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009385 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung9da14732019-09-02 16:16:58 +08009386
9387 ASSERT_EQ(mDevice->isEnabled(), false);
9388
9389 // Add display on hdmi2, the device should be enabled and can receive touch event.
9390 prepareSecondaryDisplay(type, hdmi2);
9391 ASSERT_EQ(mDevice->isEnabled(), true);
9392
9393 // Send a touch event.
9394 processPosition(mapper, 100, 100);
9395 processSync(mapper);
9396
9397 NotifyMotionArgs args;
9398 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9399 ASSERT_EQ(SECONDARY_DISPLAY_ID, args.displayId);
9400}
9401
Arthur Hung421eb1c2020-01-16 00:09:42 +08009402TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleSingleTouch) {
Arthur Hung421eb1c2020-01-16 00:09:42 +08009403 addConfigurationProperty("touch.deviceType", "touchScreen");
9404 prepareDisplay(DISPLAY_ORIENTATION_0);
9405 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009406 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung421eb1c2020-01-16 00:09:42 +08009407
9408 NotifyMotionArgs motionArgs;
9409
9410 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
9411 // finger down
9412 processId(mapper, 1);
9413 processPosition(mapper, x1, y1);
9414 processSync(mapper);
9415 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9416 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9417 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9418
9419 // finger move
9420 processId(mapper, 1);
9421 processPosition(mapper, x2, y2);
9422 processSync(mapper);
9423 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9424 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9425 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9426
9427 // finger up.
9428 processId(mapper, -1);
9429 processSync(mapper);
9430 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9431 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9432 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9433
9434 // new finger down
9435 processId(mapper, 1);
9436 processPosition(mapper, x3, y3);
9437 processSync(mapper);
9438 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9439 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9440 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9441}
9442
9443/**
arthurhungcc7f9802020-04-30 17:55:40 +08009444 * Test single touch should be canceled when received the MT_TOOL_PALM event, and the following
9445 * MOVE and UP events should be ignored.
Arthur Hung421eb1c2020-01-16 00:09:42 +08009446 */
arthurhungcc7f9802020-04-30 17:55:40 +08009447TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_SinglePointer) {
Arthur Hung421eb1c2020-01-16 00:09:42 +08009448 addConfigurationProperty("touch.deviceType", "touchScreen");
9449 prepareDisplay(DISPLAY_ORIENTATION_0);
9450 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009451 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung421eb1c2020-01-16 00:09:42 +08009452
9453 NotifyMotionArgs motionArgs;
9454
9455 // default tool type is finger
9456 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
arthurhungcc7f9802020-04-30 17:55:40 +08009457 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009458 processPosition(mapper, x1, y1);
9459 processSync(mapper);
9460 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9461 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9462 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9463
9464 // Tool changed to MT_TOOL_PALM expect sending the cancel event.
9465 processToolType(mapper, MT_TOOL_PALM);
9466 processSync(mapper);
9467 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9468 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
9469
9470 // Ignore the following MOVE and UP events if had detect a palm event.
arthurhungcc7f9802020-04-30 17:55:40 +08009471 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009472 processPosition(mapper, x2, y2);
9473 processSync(mapper);
9474 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9475
9476 // finger up.
arthurhungcc7f9802020-04-30 17:55:40 +08009477 processId(mapper, INVALID_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009478 processSync(mapper);
9479 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9480
9481 // new finger down
arthurhungcc7f9802020-04-30 17:55:40 +08009482 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009483 processToolType(mapper, MT_TOOL_FINGER);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009484 processPosition(mapper, x3, y3);
9485 processSync(mapper);
9486 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9487 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9488 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9489}
9490
arthurhungbf89a482020-04-17 17:37:55 +08009491/**
arthurhungcc7f9802020-04-30 17:55:40 +08009492 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event from some finger,
9493 * and the rest active fingers could still be allowed to receive the events
arthurhungbf89a482020-04-17 17:37:55 +08009494 */
arthurhungcc7f9802020-04-30 17:55:40 +08009495TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_TwoPointers) {
arthurhungbf89a482020-04-17 17:37:55 +08009496 addConfigurationProperty("touch.deviceType", "touchScreen");
9497 prepareDisplay(DISPLAY_ORIENTATION_0);
9498 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
9499 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9500
9501 NotifyMotionArgs motionArgs;
9502
9503 // default tool type is finger
arthurhungcc7f9802020-04-30 17:55:40 +08009504 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220;
9505 processId(mapper, FIRST_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +08009506 processPosition(mapper, x1, y1);
9507 processSync(mapper);
9508 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9509 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9510 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9511
9512 // Second finger down.
arthurhungcc7f9802020-04-30 17:55:40 +08009513 processSlot(mapper, SECOND_SLOT);
9514 processId(mapper, SECOND_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +08009515 processPosition(mapper, x2, y2);
arthurhungcc7f9802020-04-30 17:55:40 +08009516 processSync(mapper);
9517 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009518 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009519 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
9520
9521 // If the tool type of the first finger changes to MT_TOOL_PALM,
9522 // we expect to receive ACTION_POINTER_UP with cancel flag.
9523 processSlot(mapper, FIRST_SLOT);
9524 processId(mapper, FIRST_TRACKING_ID);
9525 processToolType(mapper, MT_TOOL_PALM);
9526 processSync(mapper);
9527 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009528 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009529 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9530
9531 // The following MOVE events of second finger should be processed.
9532 processSlot(mapper, SECOND_SLOT);
9533 processId(mapper, SECOND_TRACKING_ID);
9534 processPosition(mapper, x2 + 1, y2 + 1);
9535 processSync(mapper);
9536 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9537 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9538 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9539
9540 // First finger up. It used to be in palm mode, and we already generated ACTION_POINTER_UP for
9541 // it. Second finger receive move.
9542 processSlot(mapper, FIRST_SLOT);
9543 processId(mapper, INVALID_TRACKING_ID);
9544 processSync(mapper);
9545 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9546 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9547 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9548
9549 // Second finger keeps moving.
9550 processSlot(mapper, SECOND_SLOT);
9551 processId(mapper, SECOND_TRACKING_ID);
9552 processPosition(mapper, x2 + 2, y2 + 2);
9553 processSync(mapper);
9554 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9555 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9556 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9557
9558 // Second finger up.
9559 processId(mapper, INVALID_TRACKING_ID);
9560 processSync(mapper);
9561 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9562 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9563 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9564}
9565
9566/**
9567 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event, if only 1 finger
9568 * is active, it should send CANCEL after receiving the MT_TOOL_PALM event.
9569 */
9570TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_ShouldCancelWhenAllTouchIsPalm) {
9571 addConfigurationProperty("touch.deviceType", "touchScreen");
9572 prepareDisplay(DISPLAY_ORIENTATION_0);
9573 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
9574 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9575
9576 NotifyMotionArgs motionArgs;
9577
9578 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
9579 // First finger down.
9580 processId(mapper, FIRST_TRACKING_ID);
9581 processPosition(mapper, x1, y1);
9582 processSync(mapper);
9583 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9584 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9585 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9586
9587 // Second finger down.
9588 processSlot(mapper, SECOND_SLOT);
9589 processId(mapper, SECOND_TRACKING_ID);
9590 processPosition(mapper, x2, y2);
arthurhungbf89a482020-04-17 17:37:55 +08009591 processSync(mapper);
9592 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009593 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
arthurhungbf89a482020-04-17 17:37:55 +08009594 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9595
arthurhungcc7f9802020-04-30 17:55:40 +08009596 // If the tool type of the first finger changes to MT_TOOL_PALM,
9597 // we expect to receive ACTION_POINTER_UP with cancel flag.
9598 processSlot(mapper, FIRST_SLOT);
9599 processId(mapper, FIRST_TRACKING_ID);
9600 processToolType(mapper, MT_TOOL_PALM);
9601 processSync(mapper);
9602 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009603 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009604 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9605
9606 // Second finger keeps moving.
9607 processSlot(mapper, SECOND_SLOT);
9608 processId(mapper, SECOND_TRACKING_ID);
9609 processPosition(mapper, x2 + 1, y2 + 1);
9610 processSync(mapper);
9611 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9612 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9613
9614 // second finger becomes palm, receive cancel due to only 1 finger is active.
9615 processId(mapper, SECOND_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +08009616 processToolType(mapper, MT_TOOL_PALM);
9617 processSync(mapper);
9618 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9619 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
9620
arthurhungcc7f9802020-04-30 17:55:40 +08009621 // third finger down.
9622 processSlot(mapper, THIRD_SLOT);
9623 processId(mapper, THIRD_TRACKING_ID);
9624 processToolType(mapper, MT_TOOL_FINGER);
arthurhungbf89a482020-04-17 17:37:55 +08009625 processPosition(mapper, x3, y3);
9626 processSync(mapper);
arthurhungbf89a482020-04-17 17:37:55 +08009627 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9628 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9629 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
arthurhungcc7f9802020-04-30 17:55:40 +08009630 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9631
9632 // third finger move
9633 processId(mapper, THIRD_TRACKING_ID);
9634 processPosition(mapper, x3 + 1, y3 + 1);
9635 processSync(mapper);
9636 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9637 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9638
9639 // first finger up, third finger receive move.
9640 processSlot(mapper, FIRST_SLOT);
9641 processId(mapper, INVALID_TRACKING_ID);
9642 processSync(mapper);
9643 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9644 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9645 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9646
9647 // second finger up, third finger receive move.
9648 processSlot(mapper, SECOND_SLOT);
9649 processId(mapper, INVALID_TRACKING_ID);
9650 processSync(mapper);
9651 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9652 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9653 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9654
9655 // third finger up.
9656 processSlot(mapper, THIRD_SLOT);
9657 processId(mapper, INVALID_TRACKING_ID);
9658 processSync(mapper);
9659 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9660 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9661 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9662}
9663
9664/**
9665 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event from some finger,
9666 * and the active finger could still be allowed to receive the events
9667 */
9668TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_KeepFirstPointer) {
9669 addConfigurationProperty("touch.deviceType", "touchScreen");
9670 prepareDisplay(DISPLAY_ORIENTATION_0);
9671 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
9672 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9673
9674 NotifyMotionArgs motionArgs;
9675
9676 // default tool type is finger
9677 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220;
9678 processId(mapper, FIRST_TRACKING_ID);
9679 processPosition(mapper, x1, y1);
9680 processSync(mapper);
9681 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9682 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9683 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9684
9685 // Second finger down.
9686 processSlot(mapper, SECOND_SLOT);
9687 processId(mapper, SECOND_TRACKING_ID);
9688 processPosition(mapper, x2, y2);
9689 processSync(mapper);
9690 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009691 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009692 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9693
9694 // If the tool type of the second finger changes to MT_TOOL_PALM,
9695 // we expect to receive ACTION_POINTER_UP with cancel flag.
9696 processId(mapper, SECOND_TRACKING_ID);
9697 processToolType(mapper, MT_TOOL_PALM);
9698 processSync(mapper);
9699 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009700 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009701 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9702
9703 // The following MOVE event should be processed.
9704 processSlot(mapper, FIRST_SLOT);
9705 processId(mapper, FIRST_TRACKING_ID);
9706 processPosition(mapper, x1 + 1, y1 + 1);
9707 processSync(mapper);
9708 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9709 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9710 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9711
9712 // second finger up.
9713 processSlot(mapper, SECOND_SLOT);
9714 processId(mapper, INVALID_TRACKING_ID);
9715 processSync(mapper);
9716 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9717 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9718
9719 // first finger keep moving
9720 processSlot(mapper, FIRST_SLOT);
9721 processId(mapper, FIRST_TRACKING_ID);
9722 processPosition(mapper, x1 + 2, y1 + 2);
9723 processSync(mapper);
9724 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9725 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9726
9727 // first finger up.
9728 processId(mapper, INVALID_TRACKING_ID);
9729 processSync(mapper);
9730 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9731 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9732 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
arthurhungbf89a482020-04-17 17:37:55 +08009733}
9734
Arthur Hung9ad18942021-06-19 02:04:46 +00009735/**
9736 * Test multi-touch should sent ACTION_POINTER_UP/ACTION_UP when received the INVALID_TRACKING_ID,
9737 * to prevent the driver side may send unexpected data after set tracking id as INVALID_TRACKING_ID
9738 * cause slot be valid again.
9739 */
9740TEST_F(MultiTouchInputMapperTest, Process_MultiTouch_WithInvalidTrackingId) {
9741 addConfigurationProperty("touch.deviceType", "touchScreen");
9742 prepareDisplay(DISPLAY_ORIENTATION_0);
9743 prepareAxes(POSITION | ID | SLOT | PRESSURE);
9744 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9745
9746 NotifyMotionArgs motionArgs;
9747
9748 constexpr int32_t x1 = 100, y1 = 200, x2 = 0, y2 = 0;
9749 // First finger down.
9750 processId(mapper, FIRST_TRACKING_ID);
9751 processPosition(mapper, x1, y1);
9752 processPressure(mapper, RAW_PRESSURE_MAX);
9753 processSync(mapper);
9754 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9755 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9756 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9757
9758 // First finger move.
9759 processId(mapper, FIRST_TRACKING_ID);
9760 processPosition(mapper, x1 + 1, y1 + 1);
9761 processPressure(mapper, RAW_PRESSURE_MAX);
9762 processSync(mapper);
9763 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9764 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9765 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9766
9767 // Second finger down.
9768 processSlot(mapper, SECOND_SLOT);
9769 processId(mapper, SECOND_TRACKING_ID);
9770 processPosition(mapper, x2, y2);
9771 processPressure(mapper, RAW_PRESSURE_MAX);
9772 processSync(mapper);
9773 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009774 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Arthur Hung9ad18942021-06-19 02:04:46 +00009775 ASSERT_EQ(uint32_t(2), motionArgs.pointerCount);
9776
9777 // second finger up with some unexpected data.
9778 processSlot(mapper, SECOND_SLOT);
9779 processId(mapper, INVALID_TRACKING_ID);
9780 processPosition(mapper, x2, y2);
9781 processSync(mapper);
9782 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009783 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Arthur Hung9ad18942021-06-19 02:04:46 +00009784 ASSERT_EQ(uint32_t(2), motionArgs.pointerCount);
9785
9786 // first finger up with some unexpected data.
9787 processSlot(mapper, FIRST_SLOT);
9788 processId(mapper, INVALID_TRACKING_ID);
9789 processPosition(mapper, x2, y2);
9790 processPressure(mapper, RAW_PRESSURE_MAX);
9791 processSync(mapper);
9792 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9793 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9794 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9795}
9796
Prabir Pradhanafabcde2022-09-27 19:32:43 +00009797TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState) {
9798 addConfigurationProperty("touch.deviceType", "touchScreen");
9799 prepareDisplay(DISPLAY_ORIENTATION_0);
9800 prepareAxes(POSITION | ID | SLOT | PRESSURE);
9801 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9802
9803 // First finger down.
9804 processId(mapper, FIRST_TRACKING_ID);
9805 processPosition(mapper, 100, 200);
9806 processPressure(mapper, RAW_PRESSURE_MAX);
9807 processSync(mapper);
9808 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9809 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
9810
9811 // Second finger down.
9812 processSlot(mapper, SECOND_SLOT);
9813 processId(mapper, SECOND_TRACKING_ID);
9814 processPosition(mapper, 300, 400);
9815 processPressure(mapper, RAW_PRESSURE_MAX);
9816 processSync(mapper);
9817 ASSERT_NO_FATAL_FAILURE(
9818 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(ACTION_POINTER_1_DOWN)));
9819
9820 // Reset the mapper. When the mapper is reset, we expect the current multi-touch state to be
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00009821 // preserved. Resetting should cancel the ongoing gesture.
9822 resetMapper(mapper, ARBITRARY_TIME);
9823 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9824 WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
Prabir Pradhanafabcde2022-09-27 19:32:43 +00009825
9826 // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
9827 // the existing touch state to generate a down event.
9828 processPosition(mapper, 301, 302);
9829 processSync(mapper);
9830 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9831 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
9832 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9833 AllOf(WithMotionAction(ACTION_POINTER_1_DOWN), WithPressure(1.f))));
9834
9835 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9836}
9837
9838TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState_NoPointersDown) {
9839 addConfigurationProperty("touch.deviceType", "touchScreen");
9840 prepareDisplay(DISPLAY_ORIENTATION_0);
9841 prepareAxes(POSITION | ID | SLOT | PRESSURE);
9842 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9843
9844 // First finger touches down and releases.
9845 processId(mapper, FIRST_TRACKING_ID);
9846 processPosition(mapper, 100, 200);
9847 processPressure(mapper, RAW_PRESSURE_MAX);
9848 processSync(mapper);
9849 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9850 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
9851 processId(mapper, INVALID_TRACKING_ID);
9852 processSync(mapper);
9853 ASSERT_NO_FATAL_FAILURE(
9854 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
9855
9856 // Reset the mapper. When the mapper is reset, we expect it to restore the latest
9857 // raw state where no pointers are down.
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00009858 resetMapper(mapper, ARBITRARY_TIME);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00009859 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9860
9861 // Send an empty sync frame. Since there are no pointers, no events are generated.
9862 processSync(mapper);
9863 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9864}
9865
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009866// --- MultiTouchInputMapperTest_ExternalDevice ---
9867
9868class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest {
9869protected:
Chris Yea52ade12020-08-27 16:49:20 -07009870 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009871};
9872
9873/**
9874 * Expect fallback to internal viewport if device is external and external viewport is not present.
9875 */
9876TEST_F(MultiTouchInputMapperTest_ExternalDevice, Viewports_Fallback) {
9877 prepareAxes(POSITION);
9878 addConfigurationProperty("touch.deviceType", "touchScreen");
9879 prepareDisplay(DISPLAY_ORIENTATION_0);
9880 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9881
9882 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
9883
9884 NotifyMotionArgs motionArgs;
9885
9886 // Expect the event to be sent to the internal viewport,
9887 // because an external viewport is not present.
9888 processPosition(mapper, 100, 100);
9889 processSync(mapper);
9890 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9891 ASSERT_EQ(ADISPLAY_ID_DEFAULT, motionArgs.displayId);
9892
9893 // Expect the event to be sent to the external viewport if it is present.
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009894 prepareSecondaryDisplay(ViewportType::EXTERNAL);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009895 processPosition(mapper, 100, 100);
9896 processSync(mapper);
9897 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9898 ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
9899}
Arthur Hung4197f6b2020-03-16 15:39:59 +08009900
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009901TEST_F(MultiTouchInputMapperTest, Process_TouchpadCapture) {
9902 // we need a pointer controller for mouse mode of touchpad (start pointer at 0,0)
9903 std::shared_ptr<FakePointerController> fakePointerController =
9904 std::make_shared<FakePointerController>();
9905 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
9906 fakePointerController->setPosition(0, 0);
9907 fakePointerController->setButtonState(0);
9908
9909 // prepare device and capture
9910 prepareDisplay(DISPLAY_ORIENTATION_0);
9911 prepareAxes(POSITION | ID | SLOT);
9912 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
9913 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
9914 mFakePolicy->setPointerCapture(true);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009915 mFakePolicy->setPointerController(fakePointerController);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009916 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9917
9918 // captured touchpad should be a touchpad source
9919 NotifyDeviceResetArgs resetArgs;
9920 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
9921 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
9922
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00009923 InputDeviceInfo deviceInfo = mDevice->getDeviceInfo();
Chris Yef74dc422020-09-02 22:41:50 -07009924
9925 const InputDeviceInfo::MotionRange* relRangeX =
9926 deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, AINPUT_SOURCE_TOUCHPAD);
9927 ASSERT_NE(relRangeX, nullptr);
9928 ASSERT_EQ(relRangeX->min, -(RAW_X_MAX - RAW_X_MIN));
9929 ASSERT_EQ(relRangeX->max, RAW_X_MAX - RAW_X_MIN);
9930 const InputDeviceInfo::MotionRange* relRangeY =
9931 deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, AINPUT_SOURCE_TOUCHPAD);
9932 ASSERT_NE(relRangeY, nullptr);
9933 ASSERT_EQ(relRangeY->min, -(RAW_Y_MAX - RAW_Y_MIN));
9934 ASSERT_EQ(relRangeY->max, RAW_Y_MAX - RAW_Y_MIN);
9935
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009936 // run captured pointer tests - note that this is unscaled, so input listener events should be
9937 // identical to what the hardware sends (accounting for any
9938 // calibration).
9939 // FINGER 0 DOWN
Chris Ye364fdb52020-08-05 15:07:56 -07009940 processSlot(mapper, 0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009941 processId(mapper, 1);
9942 processPosition(mapper, 100 + RAW_X_MIN, 100 + RAW_Y_MIN);
9943 processKey(mapper, BTN_TOUCH, 1);
9944 processSync(mapper);
9945
9946 // expect coord[0] to contain initial location of touch 0
9947 NotifyMotionArgs args;
9948 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9949 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
9950 ASSERT_EQ(1U, args.pointerCount);
9951 ASSERT_EQ(0, args.pointerProperties[0].id);
9952 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, args.source);
9953 ASSERT_NO_FATAL_FAILURE(
9954 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
9955
9956 // FINGER 1 DOWN
9957 processSlot(mapper, 1);
9958 processId(mapper, 2);
9959 processPosition(mapper, 560 + RAW_X_MIN, 154 + RAW_Y_MIN);
9960 processSync(mapper);
9961
9962 // expect coord[0] to contain previous location, coord[1] to contain new touch 1 location
9963 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009964 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009965 ASSERT_EQ(2U, args.pointerCount);
9966 ASSERT_EQ(0, args.pointerProperties[0].id);
9967 ASSERT_EQ(1, args.pointerProperties[1].id);
9968 ASSERT_NO_FATAL_FAILURE(
9969 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
9970 ASSERT_NO_FATAL_FAILURE(
9971 assertPointerCoords(args.pointerCoords[1], 560, 154, 1, 0, 0, 0, 0, 0, 0, 0));
9972
9973 // FINGER 1 MOVE
9974 processPosition(mapper, 540 + RAW_X_MIN, 690 + RAW_Y_MIN);
9975 processSync(mapper);
9976
9977 // expect coord[0] to contain previous location, coord[1] to contain new touch 1 location
9978 // from move
9979 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9980 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9981 ASSERT_NO_FATAL_FAILURE(
9982 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
9983 ASSERT_NO_FATAL_FAILURE(
9984 assertPointerCoords(args.pointerCoords[1], 540, 690, 1, 0, 0, 0, 0, 0, 0, 0));
9985
9986 // FINGER 0 MOVE
9987 processSlot(mapper, 0);
9988 processPosition(mapper, 50 + RAW_X_MIN, 800 + RAW_Y_MIN);
9989 processSync(mapper);
9990
9991 // expect coord[0] to contain new touch 0 location, coord[1] to contain previous location
9992 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9993 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9994 ASSERT_NO_FATAL_FAILURE(
9995 assertPointerCoords(args.pointerCoords[0], 50, 800, 1, 0, 0, 0, 0, 0, 0, 0));
9996 ASSERT_NO_FATAL_FAILURE(
9997 assertPointerCoords(args.pointerCoords[1], 540, 690, 1, 0, 0, 0, 0, 0, 0, 0));
9998
9999 // BUTTON DOWN
10000 processKey(mapper, BTN_LEFT, 1);
10001 processSync(mapper);
10002
10003 // touchinputmapper design sends a move before button press
10004 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10005 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
10006 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10007 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
10008
10009 // BUTTON UP
10010 processKey(mapper, BTN_LEFT, 0);
10011 processSync(mapper);
10012
10013 // touchinputmapper design sends a move after button release
10014 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10015 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
10016 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10017 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
10018
10019 // FINGER 0 UP
10020 processId(mapper, -1);
10021 processSync(mapper);
10022 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10023 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | 0x0000, args.action);
10024
10025 // FINGER 1 MOVE
10026 processSlot(mapper, 1);
10027 processPosition(mapper, 320 + RAW_X_MIN, 900 + RAW_Y_MIN);
10028 processSync(mapper);
10029
10030 // expect coord[0] to contain new location of touch 1, and properties[0].id to contain 1
10031 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10032 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
10033 ASSERT_EQ(1U, args.pointerCount);
10034 ASSERT_EQ(1, args.pointerProperties[0].id);
10035 ASSERT_NO_FATAL_FAILURE(
10036 assertPointerCoords(args.pointerCoords[0], 320, 900, 1, 0, 0, 0, 0, 0, 0, 0));
10037
10038 // FINGER 1 UP
10039 processId(mapper, -1);
10040 processKey(mapper, BTN_TOUCH, 0);
10041 processSync(mapper);
10042 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10043 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
10044
10045 // non captured touchpad should be a mouse source
10046 mFakePolicy->setPointerCapture(false);
10047 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
10048 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
10049 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
10050}
10051
10052TEST_F(MultiTouchInputMapperTest, Process_UnCapturedTouchpadPointer) {
10053 std::shared_ptr<FakePointerController> fakePointerController =
10054 std::make_shared<FakePointerController>();
10055 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
10056 fakePointerController->setPosition(0, 0);
10057 fakePointerController->setButtonState(0);
10058
10059 // prepare device and capture
10060 prepareDisplay(DISPLAY_ORIENTATION_0);
10061 prepareAxes(POSITION | ID | SLOT);
10062 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
10063 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +000010064 mFakePolicy->setPointerController(fakePointerController);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010065 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10066 // run uncaptured pointer tests - pushes out generic events
10067 // FINGER 0 DOWN
10068 processId(mapper, 3);
10069 processPosition(mapper, 100, 100);
10070 processKey(mapper, BTN_TOUCH, 1);
10071 processSync(mapper);
10072
10073 // start at (100,100), cursor should be at (0,0) * scale
10074 NotifyMotionArgs args;
10075 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10076 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
10077 ASSERT_NO_FATAL_FAILURE(
10078 assertPointerCoords(args.pointerCoords[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
10079
10080 // FINGER 0 MOVE
10081 processPosition(mapper, 200, 200);
10082 processSync(mapper);
10083
10084 // compute scaling to help with touch position checking
10085 float rawDiagonal = hypotf(RAW_X_MAX - RAW_X_MIN, RAW_Y_MAX - RAW_Y_MIN);
10086 float displayDiagonal = hypotf(DISPLAY_WIDTH, DISPLAY_HEIGHT);
10087 float scale =
10088 mFakePolicy->getPointerGestureMovementSpeedRatio() * displayDiagonal / rawDiagonal;
10089
10090 // translate from (100,100) -> (200,200), cursor should have changed to (100,100) * scale)
10091 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10092 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
10093 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 100 * scale, 100 * scale, 0,
10094 0, 0, 0, 0, 0, 0, 0));
10095}
10096
10097TEST_F(MultiTouchInputMapperTest, WhenCapturedAndNotCaptured_GetSources) {
10098 std::shared_ptr<FakePointerController> fakePointerController =
10099 std::make_shared<FakePointerController>();
10100
10101 prepareDisplay(DISPLAY_ORIENTATION_0);
10102 prepareAxes(POSITION | ID | SLOT);
10103 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +000010104 mFakePolicy->setPointerController(fakePointerController);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010105 mFakePolicy->setPointerCapture(false);
10106 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10107
10108 // uncaptured touchpad should be a pointer device
10109 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
10110
10111 // captured touchpad should be a touchpad device
10112 mFakePolicy->setPointerCapture(true);
10113 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
10114 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
10115}
10116
HQ Liue6983c72022-04-19 22:14:56 +000010117class MultiTouchPointerModeTest : public MultiTouchInputMapperTest {
10118protected:
10119 float mPointerMovementScale;
10120 float mPointerXZoomScale;
10121 void preparePointerMode(int xAxisResolution, int yAxisResolution) {
10122 addConfigurationProperty("touch.deviceType", "pointer");
10123 std::shared_ptr<FakePointerController> fakePointerController =
10124 std::make_shared<FakePointerController>();
10125 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
10126 fakePointerController->setPosition(0, 0);
10127 fakePointerController->setButtonState(0);
10128 prepareDisplay(DISPLAY_ORIENTATION_0);
10129
10130 prepareAxes(POSITION);
10131 prepareAbsoluteAxisResolution(xAxisResolution, yAxisResolution);
10132 // In order to enable swipe and freeform gesture in pointer mode, pointer capture
10133 // needs to be disabled, and the pointer gesture needs to be enabled.
10134 mFakePolicy->setPointerCapture(false);
10135 mFakePolicy->setPointerGestureEnabled(true);
10136 mFakePolicy->setPointerController(fakePointerController);
10137
10138 float rawDiagonal = hypotf(RAW_X_MAX - RAW_X_MIN, RAW_Y_MAX - RAW_Y_MIN);
10139 float displayDiagonal = hypotf(DISPLAY_WIDTH, DISPLAY_HEIGHT);
10140 mPointerMovementScale =
10141 mFakePolicy->getPointerGestureMovementSpeedRatio() * displayDiagonal / rawDiagonal;
10142 mPointerXZoomScale =
10143 mFakePolicy->getPointerGestureZoomSpeedRatio() * displayDiagonal / rawDiagonal;
10144 }
10145
10146 void prepareAbsoluteAxisResolution(int xAxisResolution, int yAxisResolution) {
10147 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
10148 /*flat*/ 0,
10149 /*fuzz*/ 0, /*resolution*/ xAxisResolution);
10150 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
10151 /*flat*/ 0,
10152 /*fuzz*/ 0, /*resolution*/ yAxisResolution);
10153 }
10154};
10155
10156/**
10157 * Two fingers down on a pointer mode touch pad. The width
10158 * of the two finger is larger than 1/4 of the touch pack diagnal length. However, it
10159 * is smaller than the fixed min physical length 30mm. Two fingers' distance must
10160 * be greater than the both value to be freeform gesture, so that after two
10161 * fingers start to move downwards, the gesture should be swipe.
10162 */
10163TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthSwipe) {
10164 // The min freeform gesture width is 25units/mm x 30mm = 750
10165 // which is greater than fraction of the diagnal length of the touchpad (349).
10166 // Thus, MaxSwipWidth is 750.
10167 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
10168 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10169 NotifyMotionArgs motionArgs;
10170
10171 // Two fingers down at once.
10172 // The two fingers are 450 units apart, expects the current gesture to be PRESS
10173 // Pointer's initial position is used the [0,0] coordinate.
10174 int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125;
10175
10176 processId(mapper, FIRST_TRACKING_ID);
10177 processPosition(mapper, x1, y1);
10178 processMTSync(mapper);
10179 processId(mapper, SECOND_TRACKING_ID);
10180 processPosition(mapper, x2, y2);
10181 processMTSync(mapper);
10182 processSync(mapper);
10183
10184 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10185 ASSERT_EQ(1U, motionArgs.pointerCount);
10186 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10187 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010188 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010189 ASSERT_NO_FATAL_FAILURE(
10190 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
10191
10192 // It should be recognized as a SWIPE gesture when two fingers start to move down,
10193 // that there should be 1 pointer.
10194 int32_t movingDistance = 200;
10195 y1 += movingDistance;
10196 y2 += movingDistance;
10197
10198 processId(mapper, FIRST_TRACKING_ID);
10199 processPosition(mapper, x1, y1);
10200 processMTSync(mapper);
10201 processId(mapper, SECOND_TRACKING_ID);
10202 processPosition(mapper, x2, y2);
10203 processMTSync(mapper);
10204 processSync(mapper);
10205
10206 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10207 ASSERT_EQ(1U, motionArgs.pointerCount);
10208 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10209 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010210 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010211 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
10212 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
10213 0, 0, 0, 0));
10214}
10215
10216/**
10217 * Two fingers down on a pointer mode touch pad. The width of the two finger is larger
10218 * than the minimum freeform gesture width, 30mm. However, it is smaller than 1/4 of
10219 * the touch pack diagnal length. Two fingers' distance must be greater than the both
10220 * value to be freeform gesture, so that after two fingers start to move downwards,
10221 * the gesture should be swipe.
10222 */
10223TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthLowResolutionSwipe) {
10224 // The min freeform gesture width is 5units/mm x 30mm = 150
10225 // which is greater than fraction of the diagnal length of the touchpad (349).
10226 // Thus, MaxSwipWidth is the fraction of the diagnal length, 349.
10227 preparePointerMode(5 /*xResolution*/, 5 /*yResolution*/);
10228 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10229 NotifyMotionArgs motionArgs;
10230
10231 // Two fingers down at once.
10232 // The two fingers are 250 units apart, expects the current gesture to be PRESS
10233 // Pointer's initial position is used the [0,0] coordinate.
10234 int32_t x1 = 100, y1 = 125, x2 = 350, y2 = 125;
10235
10236 processId(mapper, FIRST_TRACKING_ID);
10237 processPosition(mapper, x1, y1);
10238 processMTSync(mapper);
10239 processId(mapper, SECOND_TRACKING_ID);
10240 processPosition(mapper, x2, y2);
10241 processMTSync(mapper);
10242 processSync(mapper);
10243
10244 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10245 ASSERT_EQ(1U, motionArgs.pointerCount);
10246 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10247 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010248 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010249 ASSERT_NO_FATAL_FAILURE(
10250 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
10251
10252 // It should be recognized as a SWIPE gesture when two fingers start to move down,
10253 // and there should be 1 pointer.
10254 int32_t movingDistance = 200;
10255 y1 += movingDistance;
10256 y2 += movingDistance;
10257
10258 processId(mapper, FIRST_TRACKING_ID);
10259 processPosition(mapper, x1, y1);
10260 processMTSync(mapper);
10261 processId(mapper, SECOND_TRACKING_ID);
10262 processPosition(mapper, x2, y2);
10263 processMTSync(mapper);
10264 processSync(mapper);
10265
10266 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10267 ASSERT_EQ(1U, motionArgs.pointerCount);
10268 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10269 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010270 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010271 // New coordinate is the scaled relative coordinate from the initial coordinate.
10272 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
10273 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
10274 0, 0, 0, 0));
10275}
10276
10277/**
10278 * Touch the touch pad with two fingers with a distance wider than the minimum freeform
10279 * gesture width and 1/4 of the diagnal length of the touchpad. Expect to receive
10280 * freeform gestures after two fingers start to move downwards.
10281 */
10282TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) {
10283 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
10284 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10285
10286 NotifyMotionArgs motionArgs;
10287
10288 // Two fingers down at once. Wider than the max swipe width.
10289 // The gesture is expected to be PRESS, then transformed to FREEFORM
10290 int32_t x1 = 100, y1 = 125, x2 = 900, y2 = 125;
10291
10292 processId(mapper, FIRST_TRACKING_ID);
10293 processPosition(mapper, x1, y1);
10294 processMTSync(mapper);
10295 processId(mapper, SECOND_TRACKING_ID);
10296 processPosition(mapper, x2, y2);
10297 processMTSync(mapper);
10298 processSync(mapper);
10299
10300 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10301 ASSERT_EQ(1U, motionArgs.pointerCount);
10302 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10303 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010304 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010305 // One pointer for PRESS, and its coordinate is used as the origin for pointer coordinates.
10306 ASSERT_NO_FATAL_FAILURE(
10307 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
10308
10309 int32_t movingDistance = 200;
10310
10311 // Move two fingers down, expect a cancel event because gesture is changing to freeform,
10312 // then two down events for two pointers.
10313 y1 += movingDistance;
10314 y2 += movingDistance;
10315
10316 processId(mapper, FIRST_TRACKING_ID);
10317 processPosition(mapper, x1, y1);
10318 processMTSync(mapper);
10319 processId(mapper, SECOND_TRACKING_ID);
10320 processPosition(mapper, x2, y2);
10321 processMTSync(mapper);
10322 processSync(mapper);
10323
10324 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10325 // The previous PRESS gesture is cancelled, because it is transformed to freeform
10326 ASSERT_EQ(1U, motionArgs.pointerCount);
10327 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
10328 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10329 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
10330 ASSERT_EQ(1U, motionArgs.pointerCount);
10331 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10332 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10333 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010334 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010335 ASSERT_EQ(2U, motionArgs.pointerCount);
10336 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN, motionArgs.action & AMOTION_EVENT_ACTION_MASK);
10337 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010338 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010339 // Two pointers' scaled relative coordinates from their initial centroid.
10340 // Initial y coordinates are 0 as y1 and y2 have the same value.
10341 float cookedX1 = (x1 - x2) / 2 * mPointerXZoomScale;
10342 float cookedX2 = (x2 - x1) / 2 * mPointerXZoomScale;
10343 // When pointers move, the new coordinates equal to the initial coordinates plus
10344 // scaled moving distance.
10345 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
10346 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
10347 0, 0, 0, 0));
10348 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], cookedX2,
10349 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
10350 0, 0, 0, 0));
10351
10352 // Move two fingers down again, expect one MOVE motion event.
10353 y1 += movingDistance;
10354 y2 += movingDistance;
10355
10356 processId(mapper, FIRST_TRACKING_ID);
10357 processPosition(mapper, x1, y1);
10358 processMTSync(mapper);
10359 processId(mapper, SECOND_TRACKING_ID);
10360 processPosition(mapper, x2, y2);
10361 processMTSync(mapper);
10362 processSync(mapper);
10363
10364 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10365 ASSERT_EQ(2U, motionArgs.pointerCount);
10366 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10367 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010368 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010369 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
10370 movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
10371 0, 0, 0, 0, 0));
10372 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], cookedX2,
10373 movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
10374 0, 0, 0, 0, 0));
10375}
10376
Harry Cutts39b7ca22022-10-05 15:55:48 +000010377TEST_F(MultiTouchPointerModeTest, TwoFingerSwipeOffsets) {
10378 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
10379 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10380 NotifyMotionArgs motionArgs;
10381
10382 // Place two fingers down.
10383 int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125;
10384
10385 processId(mapper, FIRST_TRACKING_ID);
10386 processPosition(mapper, x1, y1);
10387 processMTSync(mapper);
10388 processId(mapper, SECOND_TRACKING_ID);
10389 processPosition(mapper, x2, y2);
10390 processMTSync(mapper);
10391 processSync(mapper);
10392
10393 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10394 ASSERT_EQ(1U, motionArgs.pointerCount);
10395 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10396 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
10397 ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET));
10398 ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET));
10399
10400 // Move the two fingers down and to the left.
10401 int32_t movingDistance = 200;
10402 x1 -= movingDistance;
10403 y1 += movingDistance;
10404 x2 -= movingDistance;
10405 y2 += movingDistance;
10406
10407 processId(mapper, FIRST_TRACKING_ID);
10408 processPosition(mapper, x1, y1);
10409 processMTSync(mapper);
10410 processId(mapper, SECOND_TRACKING_ID);
10411 processPosition(mapper, x2, y2);
10412 processMTSync(mapper);
10413 processSync(mapper);
10414
10415 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10416 ASSERT_EQ(1U, motionArgs.pointerCount);
10417 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10418 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
10419 ASSERT_LT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET), 0);
10420 ASSERT_GT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET), 0);
10421}
10422
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000010423TEST_F(MultiTouchPointerModeTest, WhenViewportActiveStatusChanged_PointerGestureIsReset) {
10424 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
10425 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
10426 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10427 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
10428
10429 // Start a stylus gesture.
10430 processKey(mapper, BTN_TOOL_PEN, 1);
10431 processId(mapper, FIRST_TRACKING_ID);
10432 processPosition(mapper, 100, 200);
10433 processSync(mapper);
10434 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10435 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
10436 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
10437 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
10438 // TODO(b/257078296): Pointer mode generates extra event.
10439 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10440 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
10441 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
10442 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
10443 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10444
10445 // Make the viewport inactive. This will put the device in disabled mode, and the ongoing stylus
10446 // gesture should be disabled.
10447 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
10448 viewport->isActive = false;
10449 mFakePolicy->updateViewport(*viewport);
10450 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
10451 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10452 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
10453 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
10454 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
10455 // TODO(b/257078296): Pointer mode generates extra event.
10456 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10457 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
10458 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
10459 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
10460 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10461}
10462
Arthur Hung6d5b4b22022-01-21 07:21:10 +000010463// --- JoystickInputMapperTest ---
10464
10465class JoystickInputMapperTest : public InputMapperTest {
10466protected:
10467 static const int32_t RAW_X_MIN;
10468 static const int32_t RAW_X_MAX;
10469 static const int32_t RAW_Y_MIN;
10470 static const int32_t RAW_Y_MAX;
10471
10472 void SetUp() override {
10473 InputMapperTest::SetUp(InputDeviceClass::JOYSTICK | InputDeviceClass::EXTERNAL);
10474 }
10475 void prepareAxes() {
10476 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
10477 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
10478 }
10479
10480 void processAxis(JoystickInputMapper& mapper, int32_t axis, int32_t value) {
10481 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, axis, value);
10482 }
10483
10484 void processSync(JoystickInputMapper& mapper) {
10485 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
10486 }
10487
10488 void prepareVirtualDisplay(int32_t orientation) {
10489 setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH,
10490 VIRTUAL_DISPLAY_HEIGHT, orientation, VIRTUAL_DISPLAY_UNIQUE_ID,
10491 NO_PORT, ViewportType::VIRTUAL);
10492 }
10493};
10494
10495const int32_t JoystickInputMapperTest::RAW_X_MIN = -32767;
10496const int32_t JoystickInputMapperTest::RAW_X_MAX = 32767;
10497const int32_t JoystickInputMapperTest::RAW_Y_MIN = -32767;
10498const int32_t JoystickInputMapperTest::RAW_Y_MAX = 32767;
10499
10500TEST_F(JoystickInputMapperTest, Configure_AssignsDisplayUniqueId) {
10501 prepareAxes();
10502 JoystickInputMapper& mapper = addMapperAndConfigure<JoystickInputMapper>();
10503
10504 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
10505
10506 prepareVirtualDisplay(DISPLAY_ORIENTATION_0);
10507
10508 // Send an axis event
10509 processAxis(mapper, ABS_X, 100);
10510 processSync(mapper);
10511
10512 NotifyMotionArgs args;
10513 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10514 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
10515
10516 // Send another axis event
10517 processAxis(mapper, ABS_Y, 100);
10518 processSync(mapper);
10519
10520 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10521 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
10522}
10523
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010524// --- PeripheralControllerTest ---
Chris Yee2b1e5c2021-03-10 22:45:12 -080010525
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010526class PeripheralControllerTest : public testing::Test {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010527protected:
10528 static const char* DEVICE_NAME;
10529 static const char* DEVICE_LOCATION;
10530 static const int32_t DEVICE_ID;
10531 static const int32_t DEVICE_GENERATION;
10532 static const int32_t DEVICE_CONTROLLER_NUMBER;
Dominik Laskowski2f01d772022-03-23 16:01:29 -070010533 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
Chris Yee2b1e5c2021-03-10 22:45:12 -080010534 static const int32_t EVENTHUB_ID;
10535
10536 std::shared_ptr<FakeEventHub> mFakeEventHub;
10537 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -070010538 std::unique_ptr<TestInputListener> mFakeListener;
Chris Yee2b1e5c2021-03-10 22:45:12 -080010539 std::unique_ptr<InstrumentedInputReader> mReader;
10540 std::shared_ptr<InputDevice> mDevice;
10541
Dominik Laskowski2f01d772022-03-23 16:01:29 -070010542 virtual void SetUp(ftl::Flags<InputDeviceClass> classes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010543 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070010544 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -070010545 mFakeListener = std::make_unique<TestInputListener>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010546 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -070010547 *mFakeListener);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010548 mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes);
10549 }
10550
10551 void SetUp() override { SetUp(DEVICE_CLASSES); }
10552
10553 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -070010554 mFakeListener.reset();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010555 mFakePolicy.clear();
10556 }
10557
Siarhei Vishniakou2935db72022-09-22 13:35:22 -070010558 std::list<NotifyArgs> configureDevice(uint32_t changes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010559 if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
10560 mReader->requestRefreshConfiguration(changes);
10561 mReader->loopOnce();
10562 }
Siarhei Vishniakou2935db72022-09-22 13:35:22 -070010563 return mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010564 }
10565
10566 std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
10567 const std::string& location, int32_t eventHubId,
Dominik Laskowski2f01d772022-03-23 16:01:29 -070010568 ftl::Flags<InputDeviceClass> classes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010569 InputDeviceIdentifier identifier;
10570 identifier.name = name;
10571 identifier.location = location;
10572 std::shared_ptr<InputDevice> device =
10573 std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
10574 identifier);
10575 mReader->pushNextDevice(device);
10576 mFakeEventHub->addDevice(eventHubId, name, classes);
10577 mReader->loopOnce();
10578 return device;
10579 }
10580
10581 template <class T, typename... Args>
10582 T& addControllerAndConfigure(Args... args) {
10583 T& controller = mDevice->addController<T>(EVENTHUB_ID, args...);
10584
10585 return controller;
10586 }
10587};
10588
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010589const char* PeripheralControllerTest::DEVICE_NAME = "device";
10590const char* PeripheralControllerTest::DEVICE_LOCATION = "BLUETOOTH";
10591const int32_t PeripheralControllerTest::DEVICE_ID = END_RESERVED_ID + 1000;
10592const int32_t PeripheralControllerTest::DEVICE_GENERATION = 2;
10593const int32_t PeripheralControllerTest::DEVICE_CONTROLLER_NUMBER = 0;
Dominik Laskowski2f01d772022-03-23 16:01:29 -070010594const ftl::Flags<InputDeviceClass> PeripheralControllerTest::DEVICE_CLASSES =
10595 ftl::Flags<InputDeviceClass>(0); // not needed for current tests
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010596const int32_t PeripheralControllerTest::EVENTHUB_ID = 1;
Chris Yee2b1e5c2021-03-10 22:45:12 -080010597
10598// --- BatteryControllerTest ---
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010599class BatteryControllerTest : public PeripheralControllerTest {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010600protected:
10601 void SetUp() override {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010602 PeripheralControllerTest::SetUp(DEVICE_CLASSES | InputDeviceClass::BATTERY);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010603 }
10604};
10605
10606TEST_F(BatteryControllerTest, GetBatteryCapacity) {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010607 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010608
10609 ASSERT_TRUE(controller.getBatteryCapacity(DEFAULT_BATTERY));
10610 ASSERT_EQ(controller.getBatteryCapacity(DEFAULT_BATTERY).value_or(-1), BATTERY_CAPACITY);
10611}
10612
10613TEST_F(BatteryControllerTest, GetBatteryStatus) {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010614 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010615
10616 ASSERT_TRUE(controller.getBatteryStatus(DEFAULT_BATTERY));
10617 ASSERT_EQ(controller.getBatteryStatus(DEFAULT_BATTERY).value_or(-1), BATTERY_STATUS);
10618}
10619
10620// --- LightControllerTest ---
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010621class LightControllerTest : public PeripheralControllerTest {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010622protected:
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010623 void SetUp() override {
10624 PeripheralControllerTest::SetUp(DEVICE_CLASSES | InputDeviceClass::LIGHT);
10625 }
Chris Yee2b1e5c2021-03-10 22:45:12 -080010626};
10627
Chris Ye85758332021-05-16 23:05:17 -070010628TEST_F(LightControllerTest, MonoLight) {
10629 RawLightInfo infoMono = {.id = 1,
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010630 .name = "mono_light",
Chris Ye85758332021-05-16 23:05:17 -070010631 .maxBrightness = 255,
10632 .flags = InputLightClass::BRIGHTNESS,
10633 .path = ""};
10634 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010635
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010636 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010637 InputDeviceInfo info;
10638 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010639 std::vector<InputDeviceLightInfo> lights = info.getLights();
10640 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010641 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10642 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10643
10644 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_BRIGHTNESS));
10645 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
10646}
10647
10648TEST_F(LightControllerTest, MonoKeyboardBacklight) {
10649 RawLightInfo infoMono = {.id = 1,
10650 .name = "mono_keyboard_backlight",
10651 .maxBrightness = 255,
10652 .flags = InputLightClass::BRIGHTNESS |
10653 InputLightClass::KEYBOARD_BACKLIGHT,
10654 .path = ""};
10655 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
10656
10657 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10658 InputDeviceInfo info;
10659 controller.populateDeviceInfo(&info);
10660 std::vector<InputDeviceLightInfo> lights = info.getLights();
10661 ASSERT_EQ(1U, lights.size());
10662 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
10663 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010664
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010665 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_BRIGHTNESS));
10666 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010667}
10668
10669TEST_F(LightControllerTest, RGBLight) {
10670 RawLightInfo infoRed = {.id = 1,
10671 .name = "red",
10672 .maxBrightness = 255,
10673 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED,
10674 .path = ""};
10675 RawLightInfo infoGreen = {.id = 2,
10676 .name = "green",
10677 .maxBrightness = 255,
10678 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN,
10679 .path = ""};
10680 RawLightInfo infoBlue = {.id = 3,
10681 .name = "blue",
10682 .maxBrightness = 255,
10683 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE,
10684 .path = ""};
10685 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
10686 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
10687 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
10688
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010689 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010690 InputDeviceInfo info;
10691 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010692 std::vector<InputDeviceLightInfo> lights = info.getLights();
10693 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010694 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10695 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10696 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
10697
10698 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10699 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
10700}
10701
10702TEST_F(LightControllerTest, CorrectRGBKeyboardBacklight) {
10703 RawLightInfo infoRed = {.id = 1,
10704 .name = "red_keyboard_backlight",
10705 .maxBrightness = 255,
10706 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED |
10707 InputLightClass::KEYBOARD_BACKLIGHT,
10708 .path = ""};
10709 RawLightInfo infoGreen = {.id = 2,
10710 .name = "green_keyboard_backlight",
10711 .maxBrightness = 255,
10712 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN |
10713 InputLightClass::KEYBOARD_BACKLIGHT,
10714 .path = ""};
10715 RawLightInfo infoBlue = {.id = 3,
10716 .name = "blue_keyboard_backlight",
10717 .maxBrightness = 255,
10718 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE |
10719 InputLightClass::KEYBOARD_BACKLIGHT,
10720 .path = ""};
10721 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
10722 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
10723 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
10724
10725 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10726 InputDeviceInfo info;
10727 controller.populateDeviceInfo(&info);
10728 std::vector<InputDeviceLightInfo> lights = info.getLights();
10729 ASSERT_EQ(1U, lights.size());
10730 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
10731 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10732 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
10733
10734 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10735 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
10736}
10737
10738TEST_F(LightControllerTest, IncorrectRGBKeyboardBacklight) {
10739 RawLightInfo infoRed = {.id = 1,
10740 .name = "red",
10741 .maxBrightness = 255,
10742 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED,
10743 .path = ""};
10744 RawLightInfo infoGreen = {.id = 2,
10745 .name = "green",
10746 .maxBrightness = 255,
10747 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN,
10748 .path = ""};
10749 RawLightInfo infoBlue = {.id = 3,
10750 .name = "blue",
10751 .maxBrightness = 255,
10752 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE,
10753 .path = ""};
10754 RawLightInfo infoGlobal = {.id = 3,
10755 .name = "global_keyboard_backlight",
10756 .maxBrightness = 255,
10757 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GLOBAL |
10758 InputLightClass::KEYBOARD_BACKLIGHT,
10759 .path = ""};
10760 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
10761 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
10762 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
10763 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoGlobal));
10764
10765 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10766 InputDeviceInfo info;
10767 controller.populateDeviceInfo(&info);
10768 std::vector<InputDeviceLightInfo> lights = info.getLights();
10769 ASSERT_EQ(1U, lights.size());
10770 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10771 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10772 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010773
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010774 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10775 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010776}
10777
10778TEST_F(LightControllerTest, MultiColorRGBLight) {
10779 RawLightInfo infoColor = {.id = 1,
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010780 .name = "multi_color",
Chris Yee2b1e5c2021-03-10 22:45:12 -080010781 .maxBrightness = 255,
10782 .flags = InputLightClass::BRIGHTNESS |
10783 InputLightClass::MULTI_INTENSITY |
10784 InputLightClass::MULTI_INDEX,
10785 .path = ""};
10786
10787 mFakeEventHub->addRawLightInfo(infoColor.id, std::move(infoColor));
10788
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010789 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010790 InputDeviceInfo info;
10791 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010792 std::vector<InputDeviceLightInfo> lights = info.getLights();
10793 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010794 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10795 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10796 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
10797
10798 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10799 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
10800}
10801
10802TEST_F(LightControllerTest, MultiColorRGBKeyboardBacklight) {
10803 RawLightInfo infoColor = {.id = 1,
10804 .name = "multi_color_keyboard_backlight",
10805 .maxBrightness = 255,
10806 .flags = InputLightClass::BRIGHTNESS |
10807 InputLightClass::MULTI_INTENSITY |
10808 InputLightClass::MULTI_INDEX |
10809 InputLightClass::KEYBOARD_BACKLIGHT,
10810 .path = ""};
10811
10812 mFakeEventHub->addRawLightInfo(infoColor.id, std::move(infoColor));
10813
10814 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10815 InputDeviceInfo info;
10816 controller.populateDeviceInfo(&info);
10817 std::vector<InputDeviceLightInfo> lights = info.getLights();
10818 ASSERT_EQ(1U, lights.size());
10819 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
10820 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10821 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010822
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010823 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10824 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010825}
10826
10827TEST_F(LightControllerTest, PlayerIdLight) {
10828 RawLightInfo info1 = {.id = 1,
10829 .name = "player1",
10830 .maxBrightness = 255,
10831 .flags = InputLightClass::BRIGHTNESS,
10832 .path = ""};
10833 RawLightInfo info2 = {.id = 2,
10834 .name = "player2",
10835 .maxBrightness = 255,
10836 .flags = InputLightClass::BRIGHTNESS,
10837 .path = ""};
10838 RawLightInfo info3 = {.id = 3,
10839 .name = "player3",
10840 .maxBrightness = 255,
10841 .flags = InputLightClass::BRIGHTNESS,
10842 .path = ""};
10843 RawLightInfo info4 = {.id = 4,
10844 .name = "player4",
10845 .maxBrightness = 255,
10846 .flags = InputLightClass::BRIGHTNESS,
10847 .path = ""};
10848 mFakeEventHub->addRawLightInfo(info1.id, std::move(info1));
10849 mFakeEventHub->addRawLightInfo(info2.id, std::move(info2));
10850 mFakeEventHub->addRawLightInfo(info3.id, std::move(info3));
10851 mFakeEventHub->addRawLightInfo(info4.id, std::move(info4));
10852
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010853 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010854 InputDeviceInfo info;
10855 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010856 std::vector<InputDeviceLightInfo> lights = info.getLights();
10857 ASSERT_EQ(1U, lights.size());
10858 ASSERT_EQ(InputDeviceLightType::PLAYER_ID, lights[0].type);
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010859 ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10860 ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010861
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010862 ASSERT_FALSE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10863 ASSERT_TRUE(controller.setLightPlayerId(lights[0].id, LIGHT_PLAYER_ID));
10864 ASSERT_EQ(controller.getLightPlayerId(lights[0].id).value_or(-1), LIGHT_PLAYER_ID);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010865}
10866
Michael Wrightd02c5b62014-02-10 15:10:22 -080010867} // namespace android