blob: 8aaf066929a35b216af0a5c4c02a09bcc089831b [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>
Harry Cuttsa5b71292022-11-28 12:56:17 +000043#include "FakeEventHub.h"
Harry Cutts6b5fbc52022-11-28 16:37:43 +000044#include "FakeInputReaderPolicy.h"
Harry Cuttsb57f1702022-11-28 15:34:22 +000045#include "FakePointerController.h"
Harry Cuttsa5b71292022-11-28 12:56:17 +000046#include "TestConstants.h"
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +000047#include "android/hardware/input/InputDeviceCountryCode.h"
Michael Wrightdde67b82020-10-27 16:09:22 +000048#include "input/DisplayViewport.h"
49#include "input/Input.h"
Michael Wright17db18e2020-06-26 20:51:44 +010050
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +000051using android::hardware::input::InputDeviceCountryCode;
52
Michael Wrightd02c5b62014-02-10 15:10:22 -080053namespace android {
54
Dominik Laskowski2f01d772022-03-23 16:01:29 -070055using namespace ftl::flag_operators;
Prabir Pradhan739dca42022-09-09 20:12:01 +000056using testing::AllOf;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -070057using std::chrono_literals::operator""ms;
58
Michael Wrightd02c5b62014-02-10 15:10:22 -080059// Arbitrary display properties.
arthurhungcc7f9802020-04-30 17:55:40 +080060static constexpr int32_t DISPLAY_ID = 0;
Prabir Pradhanc13ff082022-09-08 22:03:30 +000061static const std::string DISPLAY_UNIQUE_ID = "local:1";
arthurhungcc7f9802020-04-30 17:55:40 +080062static constexpr int32_t SECONDARY_DISPLAY_ID = DISPLAY_ID + 1;
Prabir Pradhanc13ff082022-09-08 22:03:30 +000063static const std::string SECONDARY_DISPLAY_UNIQUE_ID = "local:2";
arthurhungcc7f9802020-04-30 17:55:40 +080064static constexpr int32_t DISPLAY_WIDTH = 480;
65static constexpr int32_t DISPLAY_HEIGHT = 800;
66static constexpr int32_t VIRTUAL_DISPLAY_ID = 1;
67static constexpr int32_t VIRTUAL_DISPLAY_WIDTH = 400;
68static constexpr int32_t VIRTUAL_DISPLAY_HEIGHT = 500;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -070069static const char* VIRTUAL_DISPLAY_UNIQUE_ID = "virtual:1";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -070070static constexpr std::optional<uint8_t> NO_PORT = std::nullopt; // no physical port is specified
Michael Wrightd02c5b62014-02-10 15:10:22 -080071
arthurhungcc7f9802020-04-30 17:55:40 +080072static constexpr int32_t FIRST_SLOT = 0;
73static constexpr int32_t SECOND_SLOT = 1;
74static constexpr int32_t THIRD_SLOT = 2;
75static constexpr int32_t INVALID_TRACKING_ID = -1;
76static constexpr int32_t FIRST_TRACKING_ID = 0;
77static constexpr int32_t SECOND_TRACKING_ID = 1;
78static constexpr int32_t THIRD_TRACKING_ID = 2;
Chris Ye3fdbfef2021-01-06 18:45:18 -080079static constexpr int32_t LIGHT_BRIGHTNESS = 0x55000000;
80static constexpr int32_t LIGHT_COLOR = 0x7F448866;
81static constexpr int32_t LIGHT_PLAYER_ID = 2;
arthurhungcc7f9802020-04-30 17:55:40 +080082
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080083static constexpr int32_t ACTION_POINTER_0_DOWN =
84 AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
85static constexpr int32_t ACTION_POINTER_0_UP =
86 AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
87static constexpr int32_t ACTION_POINTER_1_DOWN =
88 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
89static constexpr int32_t ACTION_POINTER_1_UP =
90 AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
91
Michael Wrightd02c5b62014-02-10 15:10:22 -080092// Error tolerance for floating point assertions.
93static const float EPSILON = 0.001f;
94
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +000095// Minimum timestamp separation between subsequent input events from a Bluetooth device.
96static constexpr nsecs_t MIN_BLUETOOTH_TIMESTAMP_DELTA = ms2ns(4);
97// Maximum smoothing time delta so that we don't generate events too far into the future.
98constexpr static nsecs_t MAX_BLUETOOTH_SMOOTHING_DELTA = ms2ns(32);
99
Michael Wrightd02c5b62014-02-10 15:10:22 -0800100template<typename T>
101static inline T min(T a, T b) {
102 return a < b ? a : b;
103}
104
105static inline float avg(float x, float y) {
106 return (x + y) / 2;
107}
108
Chris Ye3fdbfef2021-01-06 18:45:18 -0800109// Mapping for light color name and the light color
110const std::unordered_map<std::string, LightColor> LIGHT_COLORS = {{"red", LightColor::RED},
111 {"green", LightColor::GREEN},
112 {"blue", LightColor::BLUE}};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800113
Prabir Pradhanc14266f2021-05-12 15:56:24 -0700114static int32_t getInverseRotation(int32_t orientation) {
115 switch (orientation) {
116 case DISPLAY_ORIENTATION_90:
117 return DISPLAY_ORIENTATION_270;
118 case DISPLAY_ORIENTATION_270:
119 return DISPLAY_ORIENTATION_90;
120 default:
121 return orientation;
122 }
123}
124
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800125static void assertAxisResolution(MultiTouchInputMapper& mapper, int axis, float resolution) {
126 InputDeviceInfo info;
127 mapper.populateDeviceInfo(&info);
128
129 const InputDeviceInfo::MotionRange* motionRange =
130 info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
131 ASSERT_NEAR(motionRange->resolution, resolution, EPSILON);
132}
133
134static void assertAxisNotPresent(MultiTouchInputMapper& mapper, int axis) {
135 InputDeviceInfo info;
136 mapper.populateDeviceInfo(&info);
137
138 const InputDeviceInfo::MotionRange* motionRange =
139 info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
140 ASSERT_EQ(nullptr, motionRange);
141}
142
Siarhei Vishniakou21e96e62022-10-27 10:23:37 -0700143[[maybe_unused]] static void dumpReader(InputReader& reader) {
144 std::string dump;
145 reader.dump(dump);
146 std::istringstream iss(dump);
147 for (std::string line; std::getline(iss, line);) {
148 ALOGE("%s", line.c_str());
149 std::this_thread::sleep_for(std::chrono::milliseconds(1));
150 }
151}
152
Michael Wrightd02c5b62014-02-10 15:10:22 -0800153// --- FakeInputMapper ---
154
155class FakeInputMapper : public InputMapper {
156 uint32_t mSources;
157 int32_t mKeyboardType;
158 int32_t mMetaState;
159 KeyedVector<int32_t, int32_t> mKeyCodeStates;
160 KeyedVector<int32_t, int32_t> mScanCodeStates;
161 KeyedVector<int32_t, int32_t> mSwitchStates;
Philip Junker4af3b3d2021-12-14 10:36:55 +0100162 // fake mapping which would normally come from keyCharacterMap
163 std::unordered_map<int32_t, int32_t> mKeyCodeMapping;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800164 std::vector<int32_t> mSupportedKeyCodes;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800165
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700166 std::mutex mLock;
167 std::condition_variable mStateChangedCondition;
168 bool mConfigureWasCalled GUARDED_BY(mLock);
169 bool mResetWasCalled GUARDED_BY(mLock);
170 bool mProcessWasCalled GUARDED_BY(mLock);
171 RawEvent mLastEvent GUARDED_BY(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800172
Arthur Hungc23540e2018-11-29 20:42:11 +0800173 std::optional<DisplayViewport> mViewport;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800174public:
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800175 FakeInputMapper(InputDeviceContext& deviceContext, uint32_t sources)
176 : InputMapper(deviceContext),
177 mSources(sources),
178 mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
Michael Wrightd02c5b62014-02-10 15:10:22 -0800179 mMetaState(0),
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800180 mConfigureWasCalled(false),
181 mResetWasCalled(false),
182 mProcessWasCalled(false) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800183
Chris Yea52ade12020-08-27 16:49:20 -0700184 virtual ~FakeInputMapper() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185
186 void setKeyboardType(int32_t keyboardType) {
187 mKeyboardType = keyboardType;
188 }
189
190 void setMetaState(int32_t metaState) {
191 mMetaState = metaState;
192 }
193
194 void assertConfigureWasCalled() {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700195 std::unique_lock<std::mutex> lock(mLock);
196 base::ScopedLockAssertion assumeLocked(mLock);
197 const bool configureCalled =
198 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
199 return mConfigureWasCalled;
200 });
201 if (!configureCalled) {
202 FAIL() << "Expected configure() to have been called.";
203 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 mConfigureWasCalled = false;
205 }
206
207 void assertResetWasCalled() {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700208 std::unique_lock<std::mutex> lock(mLock);
209 base::ScopedLockAssertion assumeLocked(mLock);
210 const bool resetCalled =
211 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
212 return mResetWasCalled;
213 });
214 if (!resetCalled) {
215 FAIL() << "Expected reset() to have been called.";
216 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800217 mResetWasCalled = false;
218 }
219
Yi Kong9b14ac62018-07-17 13:48:38 -0700220 void assertProcessWasCalled(RawEvent* outLastEvent = nullptr) {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700221 std::unique_lock<std::mutex> lock(mLock);
222 base::ScopedLockAssertion assumeLocked(mLock);
223 const bool processCalled =
224 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
225 return mProcessWasCalled;
226 });
227 if (!processCalled) {
228 FAIL() << "Expected process() to have been called.";
229 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800230 if (outLastEvent) {
231 *outLastEvent = mLastEvent;
232 }
233 mProcessWasCalled = false;
234 }
235
236 void setKeyCodeState(int32_t keyCode, int32_t state) {
237 mKeyCodeStates.replaceValueFor(keyCode, state);
238 }
239
240 void setScanCodeState(int32_t scanCode, int32_t state) {
241 mScanCodeStates.replaceValueFor(scanCode, state);
242 }
243
244 void setSwitchState(int32_t switchCode, int32_t state) {
245 mSwitchStates.replaceValueFor(switchCode, state);
246 }
247
248 void addSupportedKeyCode(int32_t keyCode) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800249 mSupportedKeyCodes.push_back(keyCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800250 }
251
Philip Junker4af3b3d2021-12-14 10:36:55 +0100252 void addKeyCodeMapping(int32_t fromKeyCode, int32_t toKeyCode) {
253 mKeyCodeMapping.insert_or_assign(fromKeyCode, toKeyCode);
254 }
255
Michael Wrightd02c5b62014-02-10 15:10:22 -0800256private:
Philip Junker4af3b3d2021-12-14 10:36:55 +0100257 uint32_t getSources() const override { return mSources; }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800258
Chris Yea52ade12020-08-27 16:49:20 -0700259 void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800260 InputMapper::populateDeviceInfo(deviceInfo);
261
262 if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) {
263 deviceInfo->setKeyboardType(mKeyboardType);
264 }
265 }
266
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700267 std::list<NotifyArgs> configure(nsecs_t, const InputReaderConfiguration* config,
268 uint32_t changes) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700269 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800270 mConfigureWasCalled = true;
Arthur Hungc23540e2018-11-29 20:42:11 +0800271
272 // Find the associated viewport if exist.
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800273 const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
Arthur Hungc23540e2018-11-29 20:42:11 +0800274 if (displayPort && (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
275 mViewport = config->getDisplayViewportByPort(*displayPort);
276 }
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700277
278 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700279 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800280 }
281
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700282 std::list<NotifyArgs> reset(nsecs_t) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700283 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800284 mResetWasCalled = true;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700285 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700286 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800287 }
288
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700289 std::list<NotifyArgs> process(const RawEvent* rawEvent) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700290 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800291 mLastEvent = *rawEvent;
292 mProcessWasCalled = true;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700293 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700294 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800295 }
296
Chris Yea52ade12020-08-27 16:49:20 -0700297 int32_t getKeyCodeState(uint32_t, int32_t keyCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800298 ssize_t index = mKeyCodeStates.indexOfKey(keyCode);
299 return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
300 }
301
Philip Junker4af3b3d2021-12-14 10:36:55 +0100302 int32_t getKeyCodeForKeyLocation(int32_t locationKeyCode) const override {
303 auto it = mKeyCodeMapping.find(locationKeyCode);
304 return it != mKeyCodeMapping.end() ? it->second : locationKeyCode;
305 }
306
Chris Yea52ade12020-08-27 16:49:20 -0700307 int32_t getScanCodeState(uint32_t, int32_t scanCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800308 ssize_t index = mScanCodeStates.indexOfKey(scanCode);
309 return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
310 }
311
Chris Yea52ade12020-08-27 16:49:20 -0700312 int32_t getSwitchState(uint32_t, int32_t switchCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800313 ssize_t index = mSwitchStates.indexOfKey(switchCode);
314 return index >= 0 ? mSwitchStates.valueAt(index) : AKEY_STATE_UNKNOWN;
315 }
316
Chris Yea52ade12020-08-27 16:49:20 -0700317 // Return true if the device has non-empty key layout.
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700318 bool markSupportedKeyCodes(uint32_t, const std::vector<int32_t>& keyCodes,
Chris Yea52ade12020-08-27 16:49:20 -0700319 uint8_t* outFlags) override {
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700320 for (size_t i = 0; i < keyCodes.size(); i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800321 for (size_t j = 0; j < mSupportedKeyCodes.size(); j++) {
322 if (keyCodes[i] == mSupportedKeyCodes[j]) {
323 outFlags[i] = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800324 }
325 }
326 }
Chris Yea52ade12020-08-27 16:49:20 -0700327 bool result = mSupportedKeyCodes.size() > 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800328 return result;
329 }
330
331 virtual int32_t getMetaState() {
332 return mMetaState;
333 }
334
335 virtual void fadePointer() {
336 }
Arthur Hungc23540e2018-11-29 20:42:11 +0800337
338 virtual std::optional<int32_t> getAssociatedDisplay() {
339 if (mViewport) {
340 return std::make_optional(mViewport->displayId);
341 }
342 return std::nullopt;
343 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800344};
345
346
347// --- InstrumentedInputReader ---
348
349class InstrumentedInputReader : public InputReader {
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800350 std::queue<std::shared_ptr<InputDevice>> mNextDevices;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800351
352public:
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -0700353 InstrumentedInputReader(std::shared_ptr<EventHubInterface> eventHub,
354 const sp<InputReaderPolicyInterface>& policy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700355 InputListenerInterface& listener)
arthurhungdcef2dc2020-08-11 14:47:50 +0800356 : InputReader(eventHub, policy, listener), mFakeContext(this) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800357
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000358 virtual ~InstrumentedInputReader() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800359
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800360 void pushNextDevice(std::shared_ptr<InputDevice> device) { mNextDevices.push(device); }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800361
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800362 std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000363 const std::string& location = "") {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800364 InputDeviceIdentifier identifier;
365 identifier.name = name;
Arthur Hungc23540e2018-11-29 20:42:11 +0800366 identifier.location = location;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800367 int32_t generation = deviceId + 1;
arthurhungdcef2dc2020-08-11 14:47:50 +0800368 return std::make_shared<InputDevice>(&mFakeContext, deviceId, generation, identifier);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800369 }
370
Prabir Pradhan28efc192019-11-05 01:10:04 +0000371 // Make the protected loopOnce method accessible to tests.
372 using InputReader::loopOnce;
373
Michael Wrightd02c5b62014-02-10 15:10:22 -0800374protected:
Chris Ye1c2e0892020-11-30 21:41:44 -0800375 virtual std::shared_ptr<InputDevice> createDeviceLocked(int32_t eventHubId,
376 const InputDeviceIdentifier& identifier)
377 REQUIRES(mLock) {
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800378 if (!mNextDevices.empty()) {
379 std::shared_ptr<InputDevice> device(std::move(mNextDevices.front()));
380 mNextDevices.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800381 return device;
382 }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800383 return InputReader::createDeviceLocked(eventHubId, identifier);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800384 }
385
arthurhungdcef2dc2020-08-11 14:47:50 +0800386 // --- FakeInputReaderContext ---
387 class FakeInputReaderContext : public ContextImpl {
388 int32_t mGlobalMetaState;
389 bool mUpdateGlobalMetaStateWasCalled;
390 int32_t mGeneration;
391
392 public:
393 FakeInputReaderContext(InputReader* reader)
394 : ContextImpl(reader),
395 mGlobalMetaState(0),
396 mUpdateGlobalMetaStateWasCalled(false),
397 mGeneration(1) {}
398
399 virtual ~FakeInputReaderContext() {}
400
401 void assertUpdateGlobalMetaStateWasCalled() {
402 ASSERT_TRUE(mUpdateGlobalMetaStateWasCalled)
403 << "Expected updateGlobalMetaState() to have been called.";
404 mUpdateGlobalMetaStateWasCalled = false;
405 }
406
407 void setGlobalMetaState(int32_t state) { mGlobalMetaState = state; }
408
409 uint32_t getGeneration() { return mGeneration; }
410
411 void updateGlobalMetaState() override {
412 mUpdateGlobalMetaStateWasCalled = true;
413 ContextImpl::updateGlobalMetaState();
414 }
415
416 int32_t getGlobalMetaState() override {
417 return mGlobalMetaState | ContextImpl::getGlobalMetaState();
418 }
419
420 int32_t bumpGeneration() override {
421 mGeneration = ContextImpl::bumpGeneration();
422 return mGeneration;
423 }
424 } mFakeContext;
425
Michael Wrightd02c5b62014-02-10 15:10:22 -0800426 friend class InputReaderTest;
arthurhungdcef2dc2020-08-11 14:47:50 +0800427
428public:
429 FakeInputReaderContext* getContext() { return &mFakeContext; }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800430};
431
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700432// --- InputReaderPolicyTest ---
433class InputReaderPolicyTest : public testing::Test {
Siarhei Vishniakoucd7ac1e2018-10-15 13:39:50 -0700434protected:
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700435 sp<FakeInputReaderPolicy> mFakePolicy;
436
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700437 void SetUp() override { mFakePolicy = sp<FakeInputReaderPolicy>::make(); }
Chris Yea52ade12020-08-27 16:49:20 -0700438 void TearDown() override { mFakePolicy.clear(); }
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700439};
440
441/**
442 * Check that empty set of viewports is an acceptable configuration.
443 * Also try to get internal viewport two different ways - by type and by uniqueId.
444 *
445 * There will be confusion if two viewports with empty uniqueId and identical type are present.
446 * Such configuration is not currently allowed.
447 */
448TEST_F(InputReaderPolicyTest, Viewports_GetCleared) {
Siarhei Vishniakoucd7ac1e2018-10-15 13:39:50 -0700449 static const std::string uniqueId = "local:0";
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700450
451 // We didn't add any viewports yet, so there shouldn't be any.
452 std::optional<DisplayViewport> internalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100453 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700454 ASSERT_FALSE(internalViewport);
455
456 // Add an internal viewport, then clear it
457 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000458 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId, NO_PORT,
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100459 ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700460
461 // Check matching by uniqueId
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700462 internalViewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700463 ASSERT_TRUE(internalViewport);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100464 ASSERT_EQ(ViewportType::INTERNAL, internalViewport->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700465
466 // Check matching by viewport type
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100467 internalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700468 ASSERT_TRUE(internalViewport);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700469 ASSERT_EQ(uniqueId, internalViewport->uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700470
471 mFakePolicy->clearViewports();
472 // Make sure nothing is found after clear
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700473 internalViewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700474 ASSERT_FALSE(internalViewport);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100475 internalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700476 ASSERT_FALSE(internalViewport);
477}
478
479TEST_F(InputReaderPolicyTest, Viewports_GetByType) {
480 const std::string internalUniqueId = "local:0";
481 const std::string externalUniqueId = "local:1";
482 const std::string virtualUniqueId1 = "virtual:2";
483 const std::string virtualUniqueId2 = "virtual:3";
484 constexpr int32_t virtualDisplayId1 = 2;
485 constexpr int32_t virtualDisplayId2 = 3;
486
487 // Add an internal viewport
488 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000489 DISPLAY_ORIENTATION_0, true /*isActive*/, internalUniqueId,
490 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700491 // Add an external viewport
492 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000493 DISPLAY_ORIENTATION_0, true /*isActive*/, externalUniqueId,
494 NO_PORT, ViewportType::EXTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700495 // Add an virtual viewport
496 mFakePolicy->addDisplayViewport(virtualDisplayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000497 DISPLAY_ORIENTATION_0, true /*isActive*/, virtualUniqueId1,
498 NO_PORT, ViewportType::VIRTUAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700499 // Add another virtual viewport
500 mFakePolicy->addDisplayViewport(virtualDisplayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000501 DISPLAY_ORIENTATION_0, true /*isActive*/, virtualUniqueId2,
502 NO_PORT, ViewportType::VIRTUAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700503
504 // Check matching by type for internal
505 std::optional<DisplayViewport> internalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100506 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700507 ASSERT_TRUE(internalViewport);
508 ASSERT_EQ(internalUniqueId, internalViewport->uniqueId);
509
510 // Check matching by type for external
511 std::optional<DisplayViewport> externalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100512 mFakePolicy->getDisplayViewportByType(ViewportType::EXTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700513 ASSERT_TRUE(externalViewport);
514 ASSERT_EQ(externalUniqueId, externalViewport->uniqueId);
515
516 // Check matching by uniqueId for virtual viewport #1
517 std::optional<DisplayViewport> virtualViewport1 =
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700518 mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId1);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700519 ASSERT_TRUE(virtualViewport1);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100520 ASSERT_EQ(ViewportType::VIRTUAL, virtualViewport1->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700521 ASSERT_EQ(virtualUniqueId1, virtualViewport1->uniqueId);
522 ASSERT_EQ(virtualDisplayId1, virtualViewport1->displayId);
523
524 // Check matching by uniqueId for virtual viewport #2
525 std::optional<DisplayViewport> virtualViewport2 =
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700526 mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId2);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700527 ASSERT_TRUE(virtualViewport2);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100528 ASSERT_EQ(ViewportType::VIRTUAL, virtualViewport2->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700529 ASSERT_EQ(virtualUniqueId2, virtualViewport2->uniqueId);
530 ASSERT_EQ(virtualDisplayId2, virtualViewport2->displayId);
531}
532
533
534/**
535 * We can have 2 viewports of the same kind. We can distinguish them by uniqueId, and confirm
536 * that lookup works by checking display id.
537 * Check that 2 viewports of each kind is possible, for all existing viewport types.
538 */
539TEST_F(InputReaderPolicyTest, Viewports_TwoOfSameType) {
540 const std::string uniqueId1 = "uniqueId1";
541 const std::string uniqueId2 = "uniqueId2";
542 constexpr int32_t displayId1 = 2;
543 constexpr int32_t displayId2 = 3;
544
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100545 std::vector<ViewportType> types = {ViewportType::INTERNAL, ViewportType::EXTERNAL,
546 ViewportType::VIRTUAL};
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700547 for (const ViewportType& type : types) {
548 mFakePolicy->clearViewports();
549 // Add a viewport
550 mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000551 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1,
552 NO_PORT, type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700553 // Add another viewport
554 mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000555 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2,
556 NO_PORT, type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700557
558 // Check that correct display viewport was returned by comparing the display IDs.
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700559 std::optional<DisplayViewport> viewport1 =
560 mFakePolicy->getDisplayViewportByUniqueId(uniqueId1);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700561 ASSERT_TRUE(viewport1);
562 ASSERT_EQ(displayId1, viewport1->displayId);
563 ASSERT_EQ(type, viewport1->type);
564
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700565 std::optional<DisplayViewport> viewport2 =
566 mFakePolicy->getDisplayViewportByUniqueId(uniqueId2);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700567 ASSERT_TRUE(viewport2);
568 ASSERT_EQ(displayId2, viewport2->displayId);
569 ASSERT_EQ(type, viewport2->type);
570
571 // When there are multiple viewports of the same kind, and uniqueId is not specified
572 // in the call to getDisplayViewport, then that situation is not supported.
573 // The viewports can be stored in any order, so we cannot rely on the order, since that
574 // is just implementation detail.
575 // However, we can check that it still returns *a* viewport, we just cannot assert
576 // which one specifically is returned.
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700577 std::optional<DisplayViewport> someViewport = mFakePolicy->getDisplayViewportByType(type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700578 ASSERT_TRUE(someViewport);
579 }
580}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800581
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700582/**
Michael Wrightdde67b82020-10-27 16:09:22 +0000583 * When we have multiple internal displays make sure we always return the default display when
584 * querying by type.
585 */
586TEST_F(InputReaderPolicyTest, Viewports_ByTypeReturnsDefaultForInternal) {
587 const std::string uniqueId1 = "uniqueId1";
588 const std::string uniqueId2 = "uniqueId2";
589 constexpr int32_t nonDefaultDisplayId = 2;
590 static_assert(nonDefaultDisplayId != ADISPLAY_ID_DEFAULT,
591 "Test display ID should not be ADISPLAY_ID_DEFAULT");
592
593 // Add the default display first and ensure it gets returned.
594 mFakePolicy->clearViewports();
595 mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000596 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000597 ViewportType::INTERNAL);
598 mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000599 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000600 ViewportType::INTERNAL);
601
602 std::optional<DisplayViewport> viewport =
603 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
604 ASSERT_TRUE(viewport);
605 ASSERT_EQ(ADISPLAY_ID_DEFAULT, viewport->displayId);
606 ASSERT_EQ(ViewportType::INTERNAL, viewport->type);
607
608 // Add the default display second to make sure order doesn't matter.
609 mFakePolicy->clearViewports();
610 mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000611 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000612 ViewportType::INTERNAL);
613 mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000614 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000615 ViewportType::INTERNAL);
616
617 viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
618 ASSERT_TRUE(viewport);
619 ASSERT_EQ(ADISPLAY_ID_DEFAULT, viewport->displayId);
620 ASSERT_EQ(ViewportType::INTERNAL, viewport->type);
621}
622
623/**
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700624 * Check getDisplayViewportByPort
625 */
626TEST_F(InputReaderPolicyTest, Viewports_GetByPort) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100627 constexpr ViewportType type = ViewportType::EXTERNAL;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700628 const std::string uniqueId1 = "uniqueId1";
629 const std::string uniqueId2 = "uniqueId2";
630 constexpr int32_t displayId1 = 1;
631 constexpr int32_t displayId2 = 2;
632 const uint8_t hdmi1 = 0;
633 const uint8_t hdmi2 = 1;
634 const uint8_t hdmi3 = 2;
635
636 mFakePolicy->clearViewports();
637 // Add a viewport that's associated with some display port that's not of interest.
638 mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000639 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1, hdmi3,
640 type);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700641 // Add another viewport, connected to HDMI1 port
642 mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000643 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2, hdmi1,
644 type);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700645
646 // Check that correct display viewport was returned by comparing the display ports.
647 std::optional<DisplayViewport> hdmi1Viewport = mFakePolicy->getDisplayViewportByPort(hdmi1);
648 ASSERT_TRUE(hdmi1Viewport);
649 ASSERT_EQ(displayId2, hdmi1Viewport->displayId);
650 ASSERT_EQ(uniqueId2, hdmi1Viewport->uniqueId);
651
652 // Check that we can still get the same viewport using the uniqueId
653 hdmi1Viewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId2);
654 ASSERT_TRUE(hdmi1Viewport);
655 ASSERT_EQ(displayId2, hdmi1Viewport->displayId);
656 ASSERT_EQ(uniqueId2, hdmi1Viewport->uniqueId);
657 ASSERT_EQ(type, hdmi1Viewport->type);
658
659 // Check that we cannot find a port with "HDMI2", because we never added one
660 std::optional<DisplayViewport> hdmi2Viewport = mFakePolicy->getDisplayViewportByPort(hdmi2);
661 ASSERT_FALSE(hdmi2Viewport);
662}
663
Michael Wrightd02c5b62014-02-10 15:10:22 -0800664// --- InputReaderTest ---
665
666class InputReaderTest : public testing::Test {
667protected:
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700668 std::unique_ptr<TestInputListener> mFakeListener;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800669 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -0700670 std::shared_ptr<FakeEventHub> mFakeEventHub;
Prabir Pradhan28efc192019-11-05 01:10:04 +0000671 std::unique_ptr<InstrumentedInputReader> mReader;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800672
Chris Yea52ade12020-08-27 16:49:20 -0700673 void SetUp() override {
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -0700674 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700675 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700676 mFakeListener = std::make_unique<TestInputListener>();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800677
Prabir Pradhan28efc192019-11-05 01:10:04 +0000678 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700679 *mFakeListener);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800680 }
681
Chris Yea52ade12020-08-27 16:49:20 -0700682 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700683 mFakeListener.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800684 mFakePolicy.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800685 }
686
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700687 void addDevice(int32_t eventHubId, const std::string& name,
688 ftl::Flags<InputDeviceClass> classes, const PropertyMap* configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800689 mFakeEventHub->addDevice(eventHubId, name, classes);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800690
691 if (configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800692 mFakeEventHub->addConfigurationMap(eventHubId, configuration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800693 }
694 mFakeEventHub->finishDeviceScan();
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000695 mReader->loopOnce();
696 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700697 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
698 ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800699 }
700
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800701 void disableDevice(int32_t deviceId) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700702 mFakePolicy->addDisabledDevice(deviceId);
Prabir Pradhan28efc192019-11-05 01:10:04 +0000703 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_ENABLED_STATE);
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700704 }
705
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800706 void enableDevice(int32_t deviceId) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700707 mFakePolicy->removeDisabledDevice(deviceId);
Prabir Pradhan28efc192019-11-05 01:10:04 +0000708 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_ENABLED_STATE);
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700709 }
710
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800711 FakeInputMapper& addDeviceWithFakeInputMapper(int32_t deviceId, int32_t eventHubId,
Chris Ye1b0c7342020-07-28 21:57:03 -0700712 const std::string& name,
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700713 ftl::Flags<InputDeviceClass> classes,
714 uint32_t sources,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800715 const PropertyMap* configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800716 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, name);
717 FakeInputMapper& mapper = device->addMapper<FakeInputMapper>(eventHubId, sources);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800718 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800719 addDevice(eventHubId, name, classes, configuration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800720 return mapper;
721 }
722};
723
Chris Ye98d3f532020-10-01 21:48:59 -0700724TEST_F(InputReaderTest, PolicyGetInputDevices) {
725 ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr));
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700726 ASSERT_NO_FATAL_FAILURE(addDevice(2, "ignored", ftl::Flags<InputDeviceClass>(0),
Chris Ye98d3f532020-10-01 21:48:59 -0700727 nullptr)); // no classes so device will be ignored
Michael Wrightd02c5b62014-02-10 15:10:22 -0800728
729 // Should also have received a notification describing the new input devices.
Chris Ye98d3f532020-10-01 21:48:59 -0700730 const std::vector<InputDeviceInfo>& inputDevices = mFakePolicy->getInputDevices();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800731 ASSERT_EQ(1U, inputDevices.size());
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800732 ASSERT_EQ(END_RESERVED_ID + 1, inputDevices[0].getId());
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100733 ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800734 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
735 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
Siarhei Vishniakou1983a712021-06-04 19:27:09 +0000736 ASSERT_EQ(0U, inputDevices[0].getMotionRanges().size());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800737}
738
Chris Yee7310032020-09-22 15:36:28 -0700739TEST_F(InputReaderTest, GetMergedInputDevices) {
740 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
741 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
742 // Add two subdevices to device
743 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
744 // Must add at least one mapper or the device will be ignored!
745 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
746 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
747
748 // Push same device instance for next device to be added, so they'll have same identifier.
749 mReader->pushNextDevice(device);
750 mReader->pushNextDevice(device);
751 ASSERT_NO_FATAL_FAILURE(
752 addDevice(eventHubIds[0], "fake1", InputDeviceClass::KEYBOARD, nullptr));
753 ASSERT_NO_FATAL_FAILURE(
754 addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
755
756 // Two devices will be merged to one input device as they have same identifier
Siarhei Vishniakou1983a712021-06-04 19:27:09 +0000757 ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
Chris Yee7310032020-09-22 15:36:28 -0700758}
759
Chris Yee14523a2020-12-19 13:46:00 -0800760TEST_F(InputReaderTest, GetMergedInputDevicesEnabled) {
761 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
762 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
763 // Add two subdevices to device
764 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
765 // Must add at least one mapper or the device will be ignored!
766 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
767 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
768
769 // Push same device instance for next device to be added, so they'll have same identifier.
770 mReader->pushNextDevice(device);
771 mReader->pushNextDevice(device);
772 // Sensor device is initially disabled
773 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1",
774 InputDeviceClass::KEYBOARD | InputDeviceClass::SENSOR,
775 nullptr));
776 // Device is disabled because the only sub device is a sensor device and disabled initially.
777 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
778 ASSERT_FALSE(device->isEnabled());
779 ASSERT_NO_FATAL_FAILURE(
780 addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
781 // The merged device is enabled if any sub device is enabled
782 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
783 ASSERT_TRUE(device->isEnabled());
784}
785
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700786TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800787 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700788 constexpr ftl::Flags<InputDeviceClass> deviceClass(InputDeviceClass::KEYBOARD);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800789 constexpr int32_t eventHubId = 1;
790 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700791 // Must add at least one mapper or the device will be ignored!
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800792 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800793 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800794 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700795
Yi Kong9b14ac62018-07-17 13:48:38 -0700796 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700797
798 NotifyDeviceResetArgs resetArgs;
799 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700800 ASSERT_EQ(deviceId, resetArgs.deviceId);
801
802 ASSERT_EQ(device->isEnabled(), true);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800803 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000804 mReader->loopOnce();
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700805
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700806 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700807 ASSERT_EQ(deviceId, resetArgs.deviceId);
808 ASSERT_EQ(device->isEnabled(), false);
809
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800810 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000811 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700812 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
813 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasNotCalled());
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700814 ASSERT_EQ(device->isEnabled(), false);
815
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800816 enableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000817 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700818 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700819 ASSERT_EQ(deviceId, resetArgs.deviceId);
820 ASSERT_EQ(device->isEnabled(), true);
821}
822
Michael Wrightd02c5b62014-02-10 15:10:22 -0800823TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800824 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700825 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800826 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800827 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800828 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800829 AINPUT_SOURCE_KEYBOARD, nullptr);
830 mapper.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800831
832 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(0,
833 AINPUT_SOURCE_ANY, AKEYCODE_A))
834 << "Should return unknown when the device id is >= 0 but unknown.";
835
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800836 ASSERT_EQ(AKEY_STATE_UNKNOWN,
837 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
838 << "Should return unknown when the device id is valid but the sources are not "
839 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800840
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800841 ASSERT_EQ(AKEY_STATE_DOWN,
842 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
843 AKEYCODE_A))
844 << "Should return value provided by mapper when device id is valid and the device "
845 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800846
847 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(-1,
848 AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
849 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
850
851 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(-1,
852 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
853 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
854}
855
Philip Junker4af3b3d2021-12-14 10:36:55 +0100856TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_ForwardsRequestsToMappers) {
857 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
858 constexpr int32_t eventHubId = 1;
859 FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "keyboard",
860 InputDeviceClass::KEYBOARD,
861 AINPUT_SOURCE_KEYBOARD, nullptr);
862 mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
863
864 ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(0, AKEYCODE_Y))
865 << "Should return unknown when the device with the specified id is not found.";
866
867 ASSERT_EQ(AKEYCODE_Z, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
868 << "Should return correct mapping when device id is valid and mapping exists.";
869
870 ASSERT_EQ(AKEYCODE_A, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_A))
871 << "Should return the location key code when device id is valid and there's no "
872 "mapping.";
873}
874
875TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_NoKeyboardMapper) {
876 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
877 constexpr int32_t eventHubId = 1;
878 FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "joystick",
879 InputDeviceClass::JOYSTICK,
880 AINPUT_SOURCE_GAMEPAD, nullptr);
881 mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
882
883 ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
884 << "Should return unknown when the device id is valid but there is no keyboard mapper";
885}
886
Michael Wrightd02c5b62014-02-10 15:10:22 -0800887TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800888 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700889 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800890 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800891 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800892 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800893 AINPUT_SOURCE_KEYBOARD, nullptr);
894 mapper.setScanCodeState(KEY_A, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800895
896 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(0,
897 AINPUT_SOURCE_ANY, KEY_A))
898 << "Should return unknown when the device id is >= 0 but unknown.";
899
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800900 ASSERT_EQ(AKEY_STATE_UNKNOWN,
901 mReader->getScanCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, KEY_A))
902 << "Should return unknown when the device id is valid but the sources are not "
903 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800904
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800905 ASSERT_EQ(AKEY_STATE_DOWN,
906 mReader->getScanCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
907 KEY_A))
908 << "Should return value provided by mapper when device id is valid and the device "
909 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800910
911 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(-1,
912 AINPUT_SOURCE_TRACKBALL, KEY_A))
913 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
914
915 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(-1,
916 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
917 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
918}
919
920TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800921 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700922 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800923 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800924 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800925 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800926 AINPUT_SOURCE_KEYBOARD, nullptr);
927 mapper.setSwitchState(SW_LID, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800928
929 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(0,
930 AINPUT_SOURCE_ANY, SW_LID))
931 << "Should return unknown when the device id is >= 0 but unknown.";
932
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800933 ASSERT_EQ(AKEY_STATE_UNKNOWN,
934 mReader->getSwitchState(deviceId, AINPUT_SOURCE_TRACKBALL, SW_LID))
935 << "Should return unknown when the device id is valid but the sources are not "
936 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800937
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800938 ASSERT_EQ(AKEY_STATE_DOWN,
939 mReader->getSwitchState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
940 SW_LID))
941 << "Should return value provided by mapper when device id is valid and the device "
942 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800943
944 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(-1,
945 AINPUT_SOURCE_TRACKBALL, SW_LID))
946 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
947
948 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(-1,
949 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
950 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
951}
952
953TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800954 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700955 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800956 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800957 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800958 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800959 AINPUT_SOURCE_KEYBOARD, nullptr);
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100960
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800961 mapper.addSupportedKeyCode(AKEYCODE_A);
962 mapper.addSupportedKeyCode(AKEYCODE_B);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800963
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700964 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800965 uint8_t flags[4] = { 0, 0, 0, 1 };
966
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700967 ASSERT_FALSE(mReader->hasKeys(0, AINPUT_SOURCE_ANY, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800968 << "Should return false when device id is >= 0 but unknown.";
969 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
970
971 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700972 ASSERT_FALSE(mReader->hasKeys(deviceId, AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800973 << "Should return false when device id is valid but the sources are not supported by "
974 "the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800975 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
976
977 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700978 ASSERT_TRUE(mReader->hasKeys(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800979 keyCodes, flags))
980 << "Should return value provided by mapper when device id is valid and the device "
981 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800982 ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
983
984 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700985 ASSERT_FALSE(mReader->hasKeys(-1, AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
986 << "Should return false when the device id is < 0 but the sources are not supported by "
987 "any device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800988 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
989
990 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700991 ASSERT_TRUE(
992 mReader->hasKeys(-1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
993 << "Should return value provided by mapper when device id is < 0 and one of the "
994 "devices supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800995 ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
996}
997
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000998TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800999 constexpr int32_t eventHubId = 1;
Chris Ye1b0c7342020-07-28 21:57:03 -07001000 addDevice(eventHubId, "ignored", InputDeviceClass::KEYBOARD, nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001001
1002 NotifyConfigurationChangedArgs args;
1003
1004 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(&args));
1005 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
1006}
1007
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001008TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001009 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001010 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001011 constexpr nsecs_t when = 0;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001012 constexpr int32_t eventHubId = 1;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001013 constexpr nsecs_t readTime = 2;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001014 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001015 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001016 AINPUT_SOURCE_KEYBOARD, nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001017
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001018 mFakeEventHub->enqueueEvent(when, readTime, eventHubId, EV_KEY, KEY_A, 1);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001019 mReader->loopOnce();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001020 ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
1021
1022 RawEvent event;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001023 ASSERT_NO_FATAL_FAILURE(mapper.assertProcessWasCalled(&event));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001024 ASSERT_EQ(when, event.when);
1025 ASSERT_EQ(readTime, event.readTime);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001026 ASSERT_EQ(eventHubId, event.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001027 ASSERT_EQ(EV_KEY, event.type);
1028 ASSERT_EQ(KEY_A, event.code);
1029 ASSERT_EQ(1, event.value);
1030}
1031
Garfield Tan1c7bc862020-01-28 13:24:04 -08001032TEST_F(InputReaderTest, DeviceReset_RandomId) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001033 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001034 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001035 constexpr int32_t eventHubId = 1;
1036 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
Prabir Pradhan42611e02018-11-27 14:04:02 -08001037 // Must add at least one mapper or the device will be ignored!
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001038 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001039 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001040 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Prabir Pradhan42611e02018-11-27 14:04:02 -08001041
1042 NotifyDeviceResetArgs resetArgs;
1043 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001044 int32_t prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08001045
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001046 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001047 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001048 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -08001049 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001050 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08001051
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001052 enableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001053 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001054 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -08001055 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001056 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08001057
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001058 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001059 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001060 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -08001061 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001062 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08001063}
1064
Garfield Tan1c7bc862020-01-28 13:24:04 -08001065TEST_F(InputReaderTest, DeviceReset_GenerateIdWithInputReaderSource) {
1066 constexpr int32_t deviceId = 1;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001067 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Garfield Tan1c7bc862020-01-28 13:24:04 -08001068 constexpr int32_t eventHubId = 1;
1069 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1070 // Must add at least one mapper or the device will be ignored!
1071 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001072 mReader->pushNextDevice(device);
Garfield Tan1c7bc862020-01-28 13:24:04 -08001073 ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr));
1074
1075 NotifyDeviceResetArgs resetArgs;
1076 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1077 ASSERT_EQ(IdGenerator::Source::INPUT_READER, IdGenerator::getSource(resetArgs.id));
1078}
1079
Arthur Hungc23540e2018-11-29 20:42:11 +08001080TEST_F(InputReaderTest, Device_CanDispatchToDisplay) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001081 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001082 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001083 constexpr int32_t eventHubId = 1;
Arthur Hungc23540e2018-11-29 20:42:11 +08001084 const char* DEVICE_LOCATION = "USB1";
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001085 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1086 FakeInputMapper& mapper =
1087 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_TOUCHSCREEN);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001088 mReader->pushNextDevice(device);
Arthur Hungc23540e2018-11-29 20:42:11 +08001089
1090 const uint8_t hdmi1 = 1;
1091
1092 // Associated touch screen with second display.
1093 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
1094
1095 // Add default and second display.
Prabir Pradhan28efc192019-11-05 01:10:04 +00001096 mFakePolicy->clearViewports();
Arthur Hungc23540e2018-11-29 20:42:11 +08001097 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001098 DISPLAY_ORIENTATION_0, true /*isActive*/, "local:0", NO_PORT,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001099 ViewportType::INTERNAL);
Arthur Hungc23540e2018-11-29 20:42:11 +08001100 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001101 DISPLAY_ORIENTATION_0, true /*isActive*/, "local:1", hdmi1,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001102 ViewportType::EXTERNAL);
Arthur Hungc23540e2018-11-29 20:42:11 +08001103 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001104 mReader->loopOnce();
Prabir Pradhan28efc192019-11-05 01:10:04 +00001105
1106 // Add the device, and make sure all of the callbacks are triggered.
1107 // The device is added after the input port associations are processed since
1108 // we do not yet support dynamic device-to-display associations.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001109 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001110 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled());
Prabir Pradhan28efc192019-11-05 01:10:04 +00001111 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001112 ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
Arthur Hungc23540e2018-11-29 20:42:11 +08001113
Arthur Hung2c9a3342019-07-23 14:18:59 +08001114 // Device should only dispatch to the specified display.
Arthur Hungc23540e2018-11-29 20:42:11 +08001115 ASSERT_EQ(deviceId, device->getId());
1116 ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, DISPLAY_ID));
1117 ASSERT_TRUE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
Arthur Hung2c9a3342019-07-23 14:18:59 +08001118
1119 // Can't dispatch event from a disabled device.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001120 disableDevice(deviceId);
Prabir Pradhan28efc192019-11-05 01:10:04 +00001121 mReader->loopOnce();
Arthur Hung2c9a3342019-07-23 14:18:59 +08001122 ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
Arthur Hungc23540e2018-11-29 20:42:11 +08001123}
1124
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001125TEST_F(InputReaderTest, WhenEnabledChanges_AllSubdevicesAreUpdated) {
1126 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001127 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001128 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
1129 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1130 // Must add at least one mapper or the device will be ignored!
1131 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
1132 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
1133 mReader->pushNextDevice(device);
1134 mReader->pushNextDevice(device);
1135 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
1136 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
1137
1138 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
1139
1140 NotifyDeviceResetArgs resetArgs;
1141 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1142 ASSERT_EQ(deviceId, resetArgs.deviceId);
1143 ASSERT_TRUE(device->isEnabled());
1144 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1145 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1146
1147 disableDevice(deviceId);
1148 mReader->loopOnce();
1149
1150 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1151 ASSERT_EQ(deviceId, resetArgs.deviceId);
1152 ASSERT_FALSE(device->isEnabled());
1153 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1154 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1155
1156 enableDevice(deviceId);
1157 mReader->loopOnce();
1158
1159 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1160 ASSERT_EQ(deviceId, resetArgs.deviceId);
1161 ASSERT_TRUE(device->isEnabled());
1162 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1163 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1164}
1165
1166TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToSubdeviceMappers) {
1167 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001168 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001169 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
1170 // Add two subdevices to device
1171 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1172 FakeInputMapper& mapperDevice1 =
1173 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
1174 FakeInputMapper& mapperDevice2 =
1175 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
1176 mReader->pushNextDevice(device);
1177 mReader->pushNextDevice(device);
1178 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
1179 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
1180
1181 mapperDevice1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
1182 mapperDevice2.setKeyCodeState(AKEYCODE_B, AKEY_STATE_DOWN);
1183
1184 ASSERT_EQ(AKEY_STATE_DOWN,
1185 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_A));
1186 ASSERT_EQ(AKEY_STATE_DOWN,
1187 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_B));
1188 ASSERT_EQ(AKEY_STATE_UNKNOWN,
1189 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_C));
1190}
1191
Prabir Pradhan7e186182020-11-10 13:56:45 -08001192TEST_F(InputReaderTest, ChangingPointerCaptureNotifiesInputListener) {
1193 NotifyPointerCaptureChangedArgs args;
1194
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001195 auto request = mFakePolicy->setPointerCapture(true);
Prabir Pradhan7e186182020-11-10 13:56:45 -08001196 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
1197 mReader->loopOnce();
1198 mFakeListener->assertNotifyCaptureWasCalled(&args);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001199 ASSERT_TRUE(args.request.enable) << "Pointer Capture should be enabled.";
1200 ASSERT_EQ(args.request, request) << "Pointer Capture sequence number should match.";
Prabir Pradhan7e186182020-11-10 13:56:45 -08001201
1202 mFakePolicy->setPointerCapture(false);
1203 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
1204 mReader->loopOnce();
1205 mFakeListener->assertNotifyCaptureWasCalled(&args);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001206 ASSERT_FALSE(args.request.enable) << "Pointer Capture should be disabled.";
Prabir Pradhan7e186182020-11-10 13:56:45 -08001207
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001208 // Verify that the Pointer Capture state is not updated when the configuration value
Prabir Pradhan7e186182020-11-10 13:56:45 -08001209 // does not change.
1210 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
1211 mReader->loopOnce();
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001212 mFakeListener->assertNotifyCaptureWasNotCalled();
Prabir Pradhan7e186182020-11-10 13:56:45 -08001213}
1214
Chris Ye87143712020-11-10 05:05:58 +00001215class FakeVibratorInputMapper : public FakeInputMapper {
1216public:
1217 FakeVibratorInputMapper(InputDeviceContext& deviceContext, uint32_t sources)
1218 : FakeInputMapper(deviceContext, sources) {}
1219
1220 std::vector<int32_t> getVibratorIds() override { return getDeviceContext().getVibratorIds(); }
1221};
1222
1223TEST_F(InputReaderTest, VibratorGetVibratorIds) {
1224 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001225 ftl::Flags<InputDeviceClass> deviceClass =
1226 InputDeviceClass::KEYBOARD | InputDeviceClass::VIBRATOR;
Chris Ye87143712020-11-10 05:05:58 +00001227 constexpr int32_t eventHubId = 1;
1228 const char* DEVICE_LOCATION = "BLUETOOTH";
1229 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1230 FakeVibratorInputMapper& mapper =
1231 device->addMapper<FakeVibratorInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
1232 mReader->pushNextDevice(device);
1233
1234 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1235 ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
1236
1237 ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
1238 ASSERT_EQ(mReader->getVibratorIds(deviceId).size(), 2U);
1239}
1240
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001241// --- FakePeripheralController ---
Kim Low03ea0352020-11-06 12:45:07 -08001242
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001243class FakePeripheralController : public PeripheralControllerInterface {
Chris Yee2b1e5c2021-03-10 22:45:12 -08001244public:
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001245 FakePeripheralController(InputDeviceContext& deviceContext) : mDeviceContext(deviceContext) {}
Chris Yee2b1e5c2021-03-10 22:45:12 -08001246
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001247 ~FakePeripheralController() override {}
Chris Yee2b1e5c2021-03-10 22:45:12 -08001248
Andy Chenf9f1a022022-08-29 20:07:10 -04001249 int32_t getEventHubId() const { return getDeviceContext().getEventHubId(); }
1250
Chris Yee2b1e5c2021-03-10 22:45:12 -08001251 void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {}
1252
1253 void dump(std::string& dump) override {}
1254
1255 std::optional<int32_t> getBatteryCapacity(int32_t batteryId) override {
1256 return getDeviceContext().getBatteryCapacity(batteryId);
Kim Low03ea0352020-11-06 12:45:07 -08001257 }
1258
Chris Yee2b1e5c2021-03-10 22:45:12 -08001259 std::optional<int32_t> getBatteryStatus(int32_t batteryId) override {
1260 return getDeviceContext().getBatteryStatus(batteryId);
Kim Low03ea0352020-11-06 12:45:07 -08001261 }
Chris Ye3fdbfef2021-01-06 18:45:18 -08001262
1263 bool setLightColor(int32_t lightId, int32_t color) override {
1264 getDeviceContext().setLightBrightness(lightId, color >> 24);
1265 return true;
1266 }
1267
1268 std::optional<int32_t> getLightColor(int32_t lightId) override {
1269 std::optional<int32_t> result = getDeviceContext().getLightBrightness(lightId);
1270 if (!result.has_value()) {
1271 return std::nullopt;
1272 }
1273 return result.value() << 24;
1274 }
Chris Yee2b1e5c2021-03-10 22:45:12 -08001275
1276 bool setLightPlayerId(int32_t lightId, int32_t playerId) override { return true; }
1277
1278 std::optional<int32_t> getLightPlayerId(int32_t lightId) override { return std::nullopt; }
1279
1280private:
1281 InputDeviceContext& mDeviceContext;
1282 inline int32_t getDeviceId() { return mDeviceContext.getId(); }
1283 inline InputDeviceContext& getDeviceContext() { return mDeviceContext; }
Andy Chenf9f1a022022-08-29 20:07:10 -04001284 inline InputDeviceContext& getDeviceContext() const { return mDeviceContext; }
Chris Ye3fdbfef2021-01-06 18:45:18 -08001285};
1286
Chris Yee2b1e5c2021-03-10 22:45:12 -08001287TEST_F(InputReaderTest, BatteryGetCapacity) {
1288 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001289 ftl::Flags<InputDeviceClass> deviceClass =
1290 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
Chris Yee2b1e5c2021-03-10 22:45:12 -08001291 constexpr int32_t eventHubId = 1;
1292 const char* DEVICE_LOCATION = "BLUETOOTH";
1293 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001294 FakePeripheralController& controller =
1295 device->addController<FakePeripheralController>(eventHubId);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001296 mReader->pushNextDevice(device);
1297
1298 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1299
Harry Cuttsa5b71292022-11-28 12:56:17 +00001300 ASSERT_EQ(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY),
1301 FakeEventHub::BATTERY_CAPACITY);
1302 ASSERT_EQ(mReader->getBatteryCapacity(deviceId), FakeEventHub::BATTERY_CAPACITY);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001303}
1304
1305TEST_F(InputReaderTest, BatteryGetStatus) {
1306 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001307 ftl::Flags<InputDeviceClass> deviceClass =
1308 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
Chris Yee2b1e5c2021-03-10 22:45:12 -08001309 constexpr int32_t eventHubId = 1;
1310 const char* DEVICE_LOCATION = "BLUETOOTH";
1311 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001312 FakePeripheralController& controller =
1313 device->addController<FakePeripheralController>(eventHubId);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001314 mReader->pushNextDevice(device);
1315
1316 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1317
Harry Cuttsa5b71292022-11-28 12:56:17 +00001318 ASSERT_EQ(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY),
1319 FakeEventHub::BATTERY_STATUS);
1320 ASSERT_EQ(mReader->getBatteryStatus(deviceId), FakeEventHub::BATTERY_STATUS);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001321}
1322
Prabir Pradhane287ecd2022-09-07 21:18:05 +00001323TEST_F(InputReaderTest, BatteryGetDevicePath) {
1324 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1325 ftl::Flags<InputDeviceClass> deviceClass =
1326 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
1327 constexpr int32_t eventHubId = 1;
1328 const char* DEVICE_LOCATION = "BLUETOOTH";
1329 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1330 device->addController<FakePeripheralController>(eventHubId);
1331 mReader->pushNextDevice(device);
1332
1333 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1334
Harry Cuttsa5b71292022-11-28 12:56:17 +00001335 ASSERT_EQ(mReader->getBatteryDevicePath(deviceId), FakeEventHub::BATTERY_DEVPATH);
Prabir Pradhane287ecd2022-09-07 21:18:05 +00001336}
1337
Chris Ye3fdbfef2021-01-06 18:45:18 -08001338TEST_F(InputReaderTest, LightGetColor) {
1339 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001340 ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD | InputDeviceClass::LIGHT;
Chris Ye3fdbfef2021-01-06 18:45:18 -08001341 constexpr int32_t eventHubId = 1;
1342 const char* DEVICE_LOCATION = "BLUETOOTH";
1343 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001344 FakePeripheralController& controller =
1345 device->addController<FakePeripheralController>(eventHubId);
Chris Ye3fdbfef2021-01-06 18:45:18 -08001346 mReader->pushNextDevice(device);
1347 RawLightInfo info = {.id = 1,
1348 .name = "Mono",
1349 .maxBrightness = 255,
1350 .flags = InputLightClass::BRIGHTNESS,
1351 .path = ""};
1352 mFakeEventHub->addRawLightInfo(1 /* rawId */, std::move(info));
1353 mFakeEventHub->fakeLightBrightness(1 /* rawId */, 0x55);
1354
1355 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Chris Ye3fdbfef2021-01-06 18:45:18 -08001356
Chris Yee2b1e5c2021-03-10 22:45:12 -08001357 ASSERT_TRUE(controller.setLightColor(1 /* lightId */, LIGHT_BRIGHTNESS));
1358 ASSERT_EQ(controller.getLightColor(1 /* lightId */), LIGHT_BRIGHTNESS);
Chris Ye3fdbfef2021-01-06 18:45:18 -08001359 ASSERT_TRUE(mReader->setLightColor(deviceId, 1 /* lightId */, LIGHT_BRIGHTNESS));
1360 ASSERT_EQ(mReader->getLightColor(deviceId, 1 /* lightId */), LIGHT_BRIGHTNESS);
1361}
1362
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001363// --- InputReaderIntegrationTest ---
1364
1365// These tests create and interact with the InputReader only through its interface.
1366// The InputReader is started during SetUp(), which starts its processing in its own
1367// thread. The tests use linux uinput to emulate input devices.
1368// NOTE: Interacting with the physical device while these tests are running may cause
1369// the tests to fail.
1370class InputReaderIntegrationTest : public testing::Test {
1371protected:
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001372 std::unique_ptr<TestInputListener> mTestListener;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001373 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001374 std::unique_ptr<InputReaderInterface> mReader;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001375
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00001376 std::shared_ptr<FakePointerController> mFakePointerController;
1377
Chris Yea52ade12020-08-27 16:49:20 -07001378 void SetUp() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001379#if !defined(__ANDROID__)
1380 GTEST_SKIP();
1381#endif
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07001382 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00001383 mFakePointerController = std::make_shared<FakePointerController>();
1384 mFakePolicy->setPointerController(mFakePointerController);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001385 mTestListener = std::make_unique<TestInputListener>(2000ms /*eventHappenedTimeout*/,
1386 30ms /*eventDidNotHappenTimeout*/);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001387
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001388 mReader = std::make_unique<InputReader>(std::make_shared<EventHub>(), mFakePolicy,
1389 *mTestListener);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001390 ASSERT_EQ(mReader->start(), OK);
1391
1392 // Since this test is run on a real device, all the input devices connected
1393 // to the test device will show up in mReader. We wait for those input devices to
1394 // show up before beginning the tests.
1395 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1396 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1397 }
1398
Chris Yea52ade12020-08-27 16:49:20 -07001399 void TearDown() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001400#if !defined(__ANDROID__)
1401 return;
1402#endif
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001403 ASSERT_EQ(mReader->stop(), OK);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001404 mReader.reset();
1405 mTestListener.reset();
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001406 mFakePolicy.clear();
1407 }
Prabir Pradhanda20b172022-09-26 17:01:18 +00001408
1409 std::optional<InputDeviceInfo> findDeviceByName(const std::string& name) {
1410 const std::vector<InputDeviceInfo> inputDevices = mFakePolicy->getInputDevices();
1411 const auto& it = std::find_if(inputDevices.begin(), inputDevices.end(),
1412 [&name](const InputDeviceInfo& info) {
1413 return info.getIdentifier().name == name;
1414 });
1415 return it != inputDevices.end() ? std::make_optional(*it) : std::nullopt;
1416 }
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001417};
1418
1419TEST_F(InputReaderIntegrationTest, TestInvalidDevice) {
1420 // An invalid input device that is only used for this test.
1421 class InvalidUinputDevice : public UinputDevice {
1422 public:
Prabir Pradhanb7d434e2022-10-14 22:41:38 +00001423 InvalidUinputDevice() : UinputDevice("Invalid Device", 99 /*productId*/) {}
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001424
1425 private:
1426 void configureDevice(int fd, uinput_user_dev* device) override {}
1427 };
1428
1429 const size_t numDevices = mFakePolicy->getInputDevices().size();
1430
1431 // UinputDevice does not set any event or key bits, so InputReader should not
1432 // consider it as a valid device.
1433 std::unique_ptr<UinputDevice> invalidDevice = createUinputDevice<InvalidUinputDevice>();
1434 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
1435 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
1436 ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
1437
1438 invalidDevice.reset();
1439 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
1440 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
1441 ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
1442}
1443
1444TEST_F(InputReaderIntegrationTest, AddNewDevice) {
1445 const size_t initialNumDevices = mFakePolicy->getInputDevices().size();
1446
1447 std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
1448 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1449 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1450 ASSERT_EQ(initialNumDevices + 1, mFakePolicy->getInputDevices().size());
1451
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001452 const auto device = findDeviceByName(keyboard->getName());
1453 ASSERT_TRUE(device.has_value());
1454 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, device->getKeyboardType());
1455 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources());
1456 ASSERT_EQ(0U, device->getMotionRanges().size());
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001457
1458 keyboard.reset();
1459 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1460 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1461 ASSERT_EQ(initialNumDevices, mFakePolicy->getInputDevices().size());
1462}
1463
1464TEST_F(InputReaderIntegrationTest, SendsEventsToInputListener) {
1465 std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
1466 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1467
1468 NotifyConfigurationChangedArgs configChangedArgs;
1469 ASSERT_NO_FATAL_FAILURE(
1470 mTestListener->assertNotifyConfigurationChangedWasCalled(&configChangedArgs));
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001471 int32_t prevId = configChangedArgs.id;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001472 nsecs_t prevTimestamp = configChangedArgs.eventTime;
1473
1474 NotifyKeyArgs keyArgs;
1475 keyboard->pressAndReleaseHomeKey();
1476 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
1477 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
Garfield Tan1c7bc862020-01-28 13:24:04 -08001478 ASSERT_NE(prevId, keyArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001479 prevId = keyArgs.id;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001480 ASSERT_LE(prevTimestamp, keyArgs.eventTime);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001481 ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001482 prevTimestamp = keyArgs.eventTime;
1483
1484 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
1485 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
Garfield Tan1c7bc862020-01-28 13:24:04 -08001486 ASSERT_NE(prevId, keyArgs.id);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001487 ASSERT_LE(prevTimestamp, keyArgs.eventTime);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001488 ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001489}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001490
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001491TEST_F(InputReaderIntegrationTest, ExternalStylusesButtons) {
1492 std::unique_ptr<UinputExternalStylus> stylus = createUinputDevice<UinputExternalStylus>();
1493 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1494
1495 const auto device = findDeviceByName(stylus->getName());
1496 ASSERT_TRUE(device.has_value());
1497
Prabir Pradhana3621852022-10-14 18:57:23 +00001498 // An external stylus with buttons should also be recognized as a keyboard.
1499 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_STYLUS, device->getSources())
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001500 << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
1501 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, device->getKeyboardType());
1502
1503 const auto DOWN =
1504 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD));
1505 const auto UP = AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD));
1506
1507 stylus->pressAndReleaseKey(BTN_STYLUS);
1508 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1509 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1510 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1511 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1512
1513 stylus->pressAndReleaseKey(BTN_STYLUS2);
1514 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1515 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_SECONDARY))));
1516 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1517 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_SECONDARY))));
1518
1519 stylus->pressAndReleaseKey(BTN_STYLUS3);
1520 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1521 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
1522 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1523 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
1524}
1525
Siarhei Vishniakoua0d2b802020-05-13 14:00:31 -07001526/**
1527 * The Steam controller sends BTN_GEAR_DOWN and BTN_GEAR_UP for the two "paddle" buttons
1528 * on the back. In this test, we make sure that BTN_GEAR_DOWN / BTN_WHEEL and BTN_GEAR_UP
1529 * are passed to the listener.
1530 */
1531static_assert(BTN_GEAR_DOWN == BTN_WHEEL);
1532TEST_F(InputReaderIntegrationTest, SendsGearDownAndUpToInputListener) {
1533 std::unique_ptr<UinputSteamController> controller = createUinputDevice<UinputSteamController>();
1534 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1535 NotifyKeyArgs keyArgs;
1536
1537 controller->pressAndReleaseKey(BTN_GEAR_DOWN);
1538 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
1539 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
1540 ASSERT_EQ(BTN_GEAR_DOWN, keyArgs.scanCode);
1541
1542 controller->pressAndReleaseKey(BTN_GEAR_UP);
1543 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
1544 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
1545 ASSERT_EQ(BTN_GEAR_UP, keyArgs.scanCode);
1546}
1547
Arthur Hungaab25622020-01-16 11:22:11 +08001548// --- TouchProcessTest ---
1549class TouchIntegrationTest : public InputReaderIntegrationTest {
1550protected:
Arthur Hungaab25622020-01-16 11:22:11 +08001551 const std::string UNIQUE_ID = "local:0";
1552
Chris Yea52ade12020-08-27 16:49:20 -07001553 void SetUp() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001554#if !defined(__ANDROID__)
1555 GTEST_SKIP();
1556#endif
Arthur Hungaab25622020-01-16 11:22:11 +08001557 InputReaderIntegrationTest::SetUp();
1558 // At least add an internal display.
1559 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
1560 DISPLAY_ORIENTATION_0, UNIQUE_ID, NO_PORT,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001561 ViewportType::INTERNAL);
Arthur Hungaab25622020-01-16 11:22:11 +08001562
1563 mDevice = createUinputDevice<UinputTouchScreen>(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT));
1564 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1565 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
Prabir Pradhanda20b172022-09-26 17:01:18 +00001566 const auto info = findDeviceByName(mDevice->getName());
1567 ASSERT_TRUE(info);
1568 mDeviceInfo = *info;
Arthur Hungaab25622020-01-16 11:22:11 +08001569 }
1570
1571 void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
1572 int32_t orientation, const std::string& uniqueId,
1573 std::optional<uint8_t> physicalPort,
1574 ViewportType viewportType) {
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001575 mFakePolicy->addDisplayViewport(displayId, width, height, orientation, true /*isActive*/,
1576 uniqueId, physicalPort, viewportType);
Arthur Hungaab25622020-01-16 11:22:11 +08001577 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
1578 }
1579
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001580 void assertReceivedMotion(int32_t action, const std::vector<Point>& points) {
1581 NotifyMotionArgs args;
1582 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1583 EXPECT_EQ(action, args.action);
1584 ASSERT_EQ(points.size(), args.pointerCount);
1585 for (size_t i = 0; i < args.pointerCount; i++) {
1586 EXPECT_EQ(points[i].x, args.pointerCoords[i].getX());
1587 EXPECT_EQ(points[i].y, args.pointerCoords[i].getY());
1588 }
1589 }
1590
Arthur Hungaab25622020-01-16 11:22:11 +08001591 std::unique_ptr<UinputTouchScreen> mDevice;
Prabir Pradhanda20b172022-09-26 17:01:18 +00001592 InputDeviceInfo mDeviceInfo;
Arthur Hungaab25622020-01-16 11:22:11 +08001593};
1594
1595TEST_F(TouchIntegrationTest, InputEvent_ProcessSingleTouch) {
1596 NotifyMotionArgs args;
1597 const Point centerPoint = mDevice->getCenterPoint();
1598
1599 // ACTION_DOWN
Arthur Hung9ad18942021-06-19 02:04:46 +00001600 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001601 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001602 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001603 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1604 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1605
1606 // ACTION_MOVE
1607 mDevice->sendMove(centerPoint + Point(1, 1));
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001608 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001609 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1610 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1611
1612 // ACTION_UP
1613 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001614 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001615 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1616 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
1617}
1618
1619TEST_F(TouchIntegrationTest, InputEvent_ProcessMultiTouch) {
1620 NotifyMotionArgs args;
1621 const Point centerPoint = mDevice->getCenterPoint();
1622
1623 // ACTION_DOWN
Arthur Hung9ad18942021-06-19 02:04:46 +00001624 mDevice->sendSlot(FIRST_SLOT);
1625 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001626 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001627 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001628 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1629 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1630
1631 // ACTION_POINTER_DOWN (Second slot)
1632 const Point secondPoint = centerPoint + Point(100, 100);
1633 mDevice->sendSlot(SECOND_SLOT);
1634 mDevice->sendTrackingId(SECOND_TRACKING_ID);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001635 mDevice->sendDown(secondPoint);
1636 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001637 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001638 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001639
1640 // ACTION_MOVE (Second slot)
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001641 mDevice->sendMove(secondPoint + Point(1, 1));
1642 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001643 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1644 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1645
1646 // ACTION_POINTER_UP (Second slot)
arthurhungcc7f9802020-04-30 17:55:40 +08001647 mDevice->sendPointerUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001648 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001649 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001650 ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001651
1652 // ACTION_UP
1653 mDevice->sendSlot(FIRST_SLOT);
1654 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001655 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001656 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1657 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
1658}
1659
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001660/**
1661 * What happens when a pointer goes up while another pointer moves in the same frame? Are POINTER_UP
1662 * events guaranteed to contain the same data as a preceding MOVE, or can they contain different
1663 * data?
1664 * In this test, we try to send a change in coordinates in Pointer 0 in the same frame as the
1665 * liftoff of Pointer 1. We check that POINTER_UP event is generated first, and the MOVE event
1666 * for Pointer 0 only is generated after.
1667 * Suppose we are only interested in learning the movement of Pointer 0. If we only observe MOVE
1668 * events, we will not miss any information.
1669 * Even though the Pointer 1 up event contains updated Pointer 0 coordinates, there is another MOVE
1670 * event generated afterwards that contains the newest movement of pointer 0.
1671 * This is important for palm rejection. If there is a subsequent InputListener stage that detects
1672 * palms, and wants to cancel Pointer 1, then it is safe to simply drop POINTER_1_UP event without
1673 * losing information about non-palm pointers.
1674 */
1675TEST_F(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerUp) {
1676 NotifyMotionArgs args;
1677 const Point centerPoint = mDevice->getCenterPoint();
1678
1679 // ACTION_DOWN
1680 mDevice->sendSlot(FIRST_SLOT);
1681 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1682 mDevice->sendDown(centerPoint);
1683 mDevice->sendSync();
1684 assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
1685
1686 // ACTION_POINTER_DOWN (Second slot)
1687 const Point secondPoint = centerPoint + Point(100, 100);
1688 mDevice->sendSlot(SECOND_SLOT);
1689 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1690 mDevice->sendDown(secondPoint);
1691 mDevice->sendSync();
1692 assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
1693
1694 // ACTION_MOVE (First slot)
1695 mDevice->sendSlot(FIRST_SLOT);
1696 mDevice->sendMove(centerPoint + Point(5, 5));
1697 // ACTION_POINTER_UP (Second slot)
1698 mDevice->sendSlot(SECOND_SLOT);
1699 mDevice->sendPointerUp();
1700 // Send a single sync for the above 2 pointer updates
1701 mDevice->sendSync();
1702
1703 // First, we should get POINTER_UP for the second pointer
1704 assertReceivedMotion(ACTION_POINTER_1_UP,
1705 {/*first pointer */ centerPoint + Point(5, 5),
1706 /*second pointer*/ secondPoint});
1707
1708 // Next, the MOVE event for the first pointer
1709 assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
1710}
1711
1712/**
1713 * Similar scenario as above. The difference is that when the second pointer goes up, it will first
1714 * move, and then it will go up, all in the same frame.
1715 * In this scenario, the movement of the second pointer just prior to liftoff is ignored, and never
1716 * gets sent to the listener.
1717 */
1718TEST_F(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerMoveAndUp) {
1719 NotifyMotionArgs args;
1720 const Point centerPoint = mDevice->getCenterPoint();
1721
1722 // ACTION_DOWN
1723 mDevice->sendSlot(FIRST_SLOT);
1724 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1725 mDevice->sendDown(centerPoint);
1726 mDevice->sendSync();
1727 assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
1728
1729 // ACTION_POINTER_DOWN (Second slot)
1730 const Point secondPoint = centerPoint + Point(100, 100);
1731 mDevice->sendSlot(SECOND_SLOT);
1732 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1733 mDevice->sendDown(secondPoint);
1734 mDevice->sendSync();
1735 assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
1736
1737 // ACTION_MOVE (First slot)
1738 mDevice->sendSlot(FIRST_SLOT);
1739 mDevice->sendMove(centerPoint + Point(5, 5));
1740 // ACTION_POINTER_UP (Second slot)
1741 mDevice->sendSlot(SECOND_SLOT);
1742 mDevice->sendMove(secondPoint + Point(6, 6));
1743 mDevice->sendPointerUp();
1744 // Send a single sync for the above 2 pointer updates
1745 mDevice->sendSync();
1746
1747 // First, we should get POINTER_UP for the second pointer
1748 // The movement of the second pointer during the liftoff frame is ignored.
1749 // The coordinates 'secondPoint + Point(6, 6)' are never sent to the listener.
1750 assertReceivedMotion(ACTION_POINTER_1_UP,
1751 {/*first pointer */ centerPoint + Point(5, 5),
1752 /*second pointer*/ secondPoint});
1753
1754 // Next, the MOVE event for the first pointer
1755 assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
1756}
1757
Arthur Hungaab25622020-01-16 11:22:11 +08001758TEST_F(TouchIntegrationTest, InputEvent_ProcessPalm) {
1759 NotifyMotionArgs args;
1760 const Point centerPoint = mDevice->getCenterPoint();
1761
1762 // ACTION_DOWN
arthurhungcc7f9802020-04-30 17:55:40 +08001763 mDevice->sendSlot(FIRST_SLOT);
1764 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001765 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001766 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001767 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1768 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1769
arthurhungcc7f9802020-04-30 17:55:40 +08001770 // ACTION_POINTER_DOWN (second slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001771 const Point secondPoint = centerPoint + Point(100, 100);
1772 mDevice->sendSlot(SECOND_SLOT);
1773 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1774 mDevice->sendDown(secondPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001775 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001776 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001777 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001778
arthurhungcc7f9802020-04-30 17:55:40 +08001779 // ACTION_MOVE (second slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001780 mDevice->sendMove(secondPoint + Point(1, 1));
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001781 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001782 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1783 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1784
arthurhungcc7f9802020-04-30 17:55:40 +08001785 // Send MT_TOOL_PALM (second slot), which indicates that the touch IC has determined this to be
1786 // a palm event.
1787 // Expect to receive the ACTION_POINTER_UP with cancel flag.
Arthur Hungaab25622020-01-16 11:22:11 +08001788 mDevice->sendToolType(MT_TOOL_PALM);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001789 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001790 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001791 ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
arthurhungcc7f9802020-04-30 17:55:40 +08001792 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, args.flags);
Arthur Hungaab25622020-01-16 11:22:11 +08001793
arthurhungcc7f9802020-04-30 17:55:40 +08001794 // Send up to second slot, expect first slot send moving.
1795 mDevice->sendPointerUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001796 mDevice->sendSync();
arthurhungcc7f9802020-04-30 17:55:40 +08001797 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1798 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001799
arthurhungcc7f9802020-04-30 17:55:40 +08001800 // Send ACTION_UP (first slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001801 mDevice->sendSlot(FIRST_SLOT);
1802 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001803 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001804
arthurhungcc7f9802020-04-30 17:55:40 +08001805 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1806 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001807}
1808
Prabir Pradhanda20b172022-09-26 17:01:18 +00001809TEST_F(TouchIntegrationTest, NotifiesPolicyWhenStylusGestureStarted) {
1810 const Point centerPoint = mDevice->getCenterPoint();
1811
1812 // Send down with the pen tool selected. The policy should be notified of the stylus presence.
1813 mDevice->sendSlot(FIRST_SLOT);
1814 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1815 mDevice->sendToolType(MT_TOOL_PEN);
1816 mDevice->sendDown(centerPoint);
1817 mDevice->sendSync();
1818 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1819 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1820 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
1821
1822 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
1823
1824 // Release the stylus touch.
1825 mDevice->sendUp();
1826 mDevice->sendSync();
1827 ASSERT_NO_FATAL_FAILURE(
1828 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
1829
1830 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
1831
1832 // Touch down with the finger, without the pen tool selected. The policy is not notified.
1833 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1834 mDevice->sendToolType(MT_TOOL_FINGER);
1835 mDevice->sendDown(centerPoint);
1836 mDevice->sendSync();
1837 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1838 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1839 WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))));
1840
1841 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
1842
1843 mDevice->sendUp();
1844 mDevice->sendSync();
1845 ASSERT_NO_FATAL_FAILURE(
1846 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
1847
1848 // Send a move event with the stylus tool without BTN_TOUCH to generate a hover enter.
1849 // The policy should be notified of the stylus presence.
1850 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1851 mDevice->sendToolType(MT_TOOL_PEN);
1852 mDevice->sendMove(centerPoint);
1853 mDevice->sendSync();
1854 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1855 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1856 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
1857
1858 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
1859}
1860
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001861TEST_F(TouchIntegrationTest, StylusButtonsGenerateKeyEvents) {
1862 mDevice->sendKey(BTN_STYLUS, 1);
1863 mDevice->sendSync();
1864 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1865 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
1866 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1867
1868 mDevice->sendKey(BTN_STYLUS, 0);
1869 mDevice->sendSync();
1870 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1871 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
1872 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1873}
1874
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001875TEST_F(TouchIntegrationTest, StylusButtonsSurroundingTouchGesture) {
1876 const Point centerPoint = mDevice->getCenterPoint();
1877
1878 // Press the stylus button.
1879 mDevice->sendKey(BTN_STYLUS, 1);
1880 mDevice->sendSync();
1881 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1882 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
1883 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1884
1885 // Start and finish a stylus gesture.
1886 mDevice->sendSlot(FIRST_SLOT);
1887 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1888 mDevice->sendToolType(MT_TOOL_PEN);
1889 mDevice->sendDown(centerPoint);
1890 mDevice->sendSync();
1891 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1892 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1893 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
1894 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1895 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1896 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
1897 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
1898 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1899
1900 mDevice->sendTrackingId(INVALID_TRACKING_ID);
1901 mDevice->sendSync();
1902 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1903 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
1904 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0))));
1905 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1906 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
1907 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0))));
1908
1909 // Release the stylus button.
1910 mDevice->sendKey(BTN_STYLUS, 0);
1911 mDevice->sendSync();
1912 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1913 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
1914 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1915}
1916
1917TEST_F(TouchIntegrationTest, StylusButtonsWithinTouchGesture) {
1918 const Point centerPoint = mDevice->getCenterPoint();
1919
1920 // Start a stylus gesture.
1921 mDevice->sendSlot(FIRST_SLOT);
1922 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1923 mDevice->sendToolType(MT_TOOL_PEN);
1924 mDevice->sendDown(centerPoint);
1925 mDevice->sendSync();
1926 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1927 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1928 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0))));
1929
1930 // Press and release a stylus button. Each change in button state also generates a MOVE event.
1931 mDevice->sendKey(BTN_STYLUS, 1);
1932 mDevice->sendSync();
1933 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1934 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
1935 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1936 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1937 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
1938 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
1939 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1940 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1941 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
1942 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
1943 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1944
1945 mDevice->sendKey(BTN_STYLUS, 0);
1946 mDevice->sendSync();
1947 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1948 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
1949 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1950 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1951 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
1952 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0))));
1953 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1954 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
1955 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0))));
1956
1957 // Finish the stylus gesture.
1958 mDevice->sendTrackingId(INVALID_TRACKING_ID);
1959 mDevice->sendSync();
1960 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1961 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
1962 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0))));
1963}
1964
Michael Wrightd02c5b62014-02-10 15:10:22 -08001965// --- InputDeviceTest ---
Michael Wrightd02c5b62014-02-10 15:10:22 -08001966class InputDeviceTest : public testing::Test {
1967protected:
1968 static const char* DEVICE_NAME;
Arthur Hung2c9a3342019-07-23 14:18:59 +08001969 static const char* DEVICE_LOCATION;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001970 static const int32_t DEVICE_ID;
1971 static const int32_t DEVICE_GENERATION;
1972 static const int32_t DEVICE_CONTROLLER_NUMBER;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001973 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001974 static const int32_t EVENTHUB_ID;
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00001975 static const std::string DEVICE_BLUETOOTH_ADDRESS;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001976
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07001977 std::shared_ptr<FakeEventHub> mFakeEventHub;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001978 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001979 std::unique_ptr<TestInputListener> mFakeListener;
arthurhungdcef2dc2020-08-11 14:47:50 +08001980 std::unique_ptr<InstrumentedInputReader> mReader;
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +00001981 std::shared_ptr<InputDevice> mDevice;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001982
Chris Yea52ade12020-08-27 16:49:20 -07001983 void SetUp() override {
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07001984 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07001985 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001986 mFakeListener = std::make_unique<TestInputListener>();
arthurhungdcef2dc2020-08-11 14:47:50 +08001987 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001988 *mFakeListener);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001989 InputDeviceIdentifier identifier;
1990 identifier.name = DEVICE_NAME;
Arthur Hung2c9a3342019-07-23 14:18:59 +08001991 identifier.location = DEVICE_LOCATION;
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00001992 identifier.bluetoothAddress = DEVICE_BLUETOOTH_ADDRESS;
arthurhungdcef2dc2020-08-11 14:47:50 +08001993 mDevice = std::make_shared<InputDevice>(mReader->getContext(), DEVICE_ID, DEVICE_GENERATION,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001994 identifier);
arthurhungdcef2dc2020-08-11 14:47:50 +08001995 mReader->pushNextDevice(mDevice);
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001996 mFakeEventHub->addDevice(EVENTHUB_ID, DEVICE_NAME, ftl::Flags<InputDeviceClass>(0));
arthurhungdcef2dc2020-08-11 14:47:50 +08001997 mReader->loopOnce();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001998 }
1999
Chris Yea52ade12020-08-27 16:49:20 -07002000 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002001 mFakeListener.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002002 mFakePolicy.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002003 }
2004};
2005
2006const char* InputDeviceTest::DEVICE_NAME = "device";
Arthur Hung2c9a3342019-07-23 14:18:59 +08002007const char* InputDeviceTest::DEVICE_LOCATION = "USB1";
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002008const int32_t InputDeviceTest::DEVICE_ID = END_RESERVED_ID + 1000;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002009const int32_t InputDeviceTest::DEVICE_GENERATION = 2;
2010const int32_t InputDeviceTest::DEVICE_CONTROLLER_NUMBER = 0;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002011const ftl::Flags<InputDeviceClass> InputDeviceTest::DEVICE_CLASSES =
Chris Ye1b0c7342020-07-28 21:57:03 -07002012 InputDeviceClass::KEYBOARD | InputDeviceClass::TOUCH | InputDeviceClass::JOYSTICK;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002013const int32_t InputDeviceTest::EVENTHUB_ID = 1;
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00002014const std::string InputDeviceTest::DEVICE_BLUETOOTH_ADDRESS = "11:AA:22:BB:33:CC";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002015
2016TEST_F(InputDeviceTest, ImmutableProperties) {
2017 ASSERT_EQ(DEVICE_ID, mDevice->getId());
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01002018 ASSERT_STREQ(DEVICE_NAME, mDevice->getName().c_str());
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002019 ASSERT_EQ(ftl::Flags<InputDeviceClass>(0), mDevice->getClasses());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002020}
2021
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +00002022TEST_F(InputDeviceTest, CountryCodeCorrectlyMapped) {
2023 mFakeEventHub->setCountryCode(EVENTHUB_ID, InputDeviceCountryCode::INTERNATIONAL);
2024
2025 // Configuration
2026 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
2027 InputReaderConfiguration config;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002028 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +00002029
2030 ASSERT_EQ(InputDeviceCountryCode::INTERNATIONAL, mDevice->getDeviceInfo().getCountryCode());
2031}
2032
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002033TEST_F(InputDeviceTest, WhenDeviceCreated_EnabledIsFalse) {
2034 ASSERT_EQ(mDevice->isEnabled(), false);
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07002035}
2036
Michael Wrightd02c5b62014-02-10 15:10:22 -08002037TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
2038 // Configuration.
2039 InputReaderConfiguration config;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002040 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002041
2042 // Reset.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002043 unused += mDevice->reset(ARBITRARY_TIME);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002044
2045 NotifyDeviceResetArgs resetArgs;
2046 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2047 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
2048 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
2049
2050 // Metadata.
2051 ASSERT_TRUE(mDevice->isIgnored());
2052 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mDevice->getSources());
2053
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00002054 InputDeviceInfo info = mDevice->getDeviceInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002055 ASSERT_EQ(DEVICE_ID, info.getId());
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01002056 ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002057 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType());
2058 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources());
2059
2060 // State queries.
2061 ASSERT_EQ(0, mDevice->getMetaState());
2062
2063 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, 0))
2064 << "Ignored device should return unknown key code state.";
2065 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 0))
2066 << "Ignored device should return unknown scan code state.";
2067 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 0))
2068 << "Ignored device should return unknown switch state.";
2069
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002070 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B};
Michael Wrightd02c5b62014-02-10 15:10:22 -08002071 uint8_t flags[2] = { 0, 1 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002072 ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -08002073 << "Ignored device should never mark any key codes.";
2074 ASSERT_EQ(0, flags[0]) << "Flag for unsupported key should be unchanged.";
2075 ASSERT_EQ(1, flags[1]) << "Flag for unsupported key should be unchanged.";
2076}
2077
2078TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) {
2079 // Configuration.
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002080 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "key", "value");
Michael Wrightd02c5b62014-02-10 15:10:22 -08002081
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002082 FakeInputMapper& mapper1 =
2083 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002084 mapper1.setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC);
2085 mapper1.setMetaState(AMETA_ALT_ON);
2086 mapper1.addSupportedKeyCode(AKEYCODE_A);
2087 mapper1.addSupportedKeyCode(AKEYCODE_B);
2088 mapper1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
2089 mapper1.setKeyCodeState(AKEYCODE_B, AKEY_STATE_UP);
2090 mapper1.setScanCodeState(2, AKEY_STATE_DOWN);
2091 mapper1.setScanCodeState(3, AKEY_STATE_UP);
2092 mapper1.setSwitchState(4, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002093
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002094 FakeInputMapper& mapper2 =
2095 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_TOUCHSCREEN);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002096 mapper2.setMetaState(AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002097
2098 InputReaderConfiguration config;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002099 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002100
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002101 std::string propertyValue;
2102 ASSERT_TRUE(mDevice->getConfiguration().tryGetProperty("key", propertyValue))
Michael Wrightd02c5b62014-02-10 15:10:22 -08002103 << "Device should have read configuration during configuration phase.";
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002104 ASSERT_EQ("value", propertyValue);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002105
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002106 ASSERT_NO_FATAL_FAILURE(mapper1.assertConfigureWasCalled());
2107 ASSERT_NO_FATAL_FAILURE(mapper2.assertConfigureWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002108
2109 // Reset
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002110 unused += mDevice->reset(ARBITRARY_TIME);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002111 ASSERT_NO_FATAL_FAILURE(mapper1.assertResetWasCalled());
2112 ASSERT_NO_FATAL_FAILURE(mapper2.assertResetWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002113
2114 NotifyDeviceResetArgs resetArgs;
2115 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2116 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
2117 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
2118
2119 // Metadata.
2120 ASSERT_FALSE(mDevice->isIgnored());
2121 ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), mDevice->getSources());
2122
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00002123 InputDeviceInfo info = mDevice->getDeviceInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002124 ASSERT_EQ(DEVICE_ID, info.getId());
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01002125 ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002126 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType());
2127 ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources());
2128
2129 // State queries.
2130 ASSERT_EQ(AMETA_ALT_ON | AMETA_SHIFT_ON, mDevice->getMetaState())
2131 << "Should query mappers and combine meta states.";
2132
2133 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2134 << "Should return unknown key code state when source not supported.";
2135 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2136 << "Should return unknown scan code state when source not supported.";
2137 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2138 << "Should return unknown switch state when source not supported.";
2139
2140 ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, AKEYCODE_A))
2141 << "Should query mapper when source is supported.";
2142 ASSERT_EQ(AKEY_STATE_UP, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 3))
2143 << "Should query mapper when source is supported.";
2144 ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 4))
2145 << "Should query mapper when source is supported.";
2146
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002147 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2};
Michael Wrightd02c5b62014-02-10 15:10:22 -08002148 uint8_t flags[4] = { 0, 0, 0, 1 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002149 ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -08002150 << "Should do nothing when source is unsupported.";
2151 ASSERT_EQ(0, flags[0]) << "Flag should be unchanged when source is unsupported.";
2152 ASSERT_EQ(0, flags[1]) << "Flag should be unchanged when source is unsupported.";
2153 ASSERT_EQ(0, flags[2]) << "Flag should be unchanged when source is unsupported.";
2154 ASSERT_EQ(1, flags[3]) << "Flag should be unchanged when source is unsupported.";
2155
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002156 ASSERT_TRUE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -08002157 << "Should query mapper when source is supported.";
2158 ASSERT_EQ(1, flags[0]) << "Flag for supported key should be set.";
2159 ASSERT_EQ(1, flags[1]) << "Flag for supported key should be set.";
2160 ASSERT_EQ(0, flags[2]) << "Flag for unsupported key should be unchanged.";
2161 ASSERT_EQ(1, flags[3]) << "Flag for unsupported key should be unchanged.";
2162
2163 // Event handling.
2164 RawEvent event;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002165 event.deviceId = EVENTHUB_ID;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002166 unused += mDevice->process(&event, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002167
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002168 ASSERT_NO_FATAL_FAILURE(mapper1.assertProcessWasCalled());
2169 ASSERT_NO_FATAL_FAILURE(mapper2.assertProcessWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002170}
2171
Arthur Hung2c9a3342019-07-23 14:18:59 +08002172// A single input device is associated with a specific display. Check that:
2173// 1. Device is disabled if the viewport corresponding to the associated display is not found
2174// 2. Device is disabled when setEnabled API is called
2175TEST_F(InputDeviceTest, Configure_AssignsDisplayPort) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002176 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_TOUCHSCREEN);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002177
2178 // First Configuration.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002179 std::list<NotifyArgs> unused =
2180 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002181
2182 // Device should be enabled by default.
2183 ASSERT_TRUE(mDevice->isEnabled());
2184
2185 // Prepare associated info.
2186 constexpr uint8_t hdmi = 1;
2187 const std::string UNIQUE_ID = "local:1";
2188
2189 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002190 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2191 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002192 // Device should be disabled because it is associated with a specific display via
2193 // input port <-> display port association, but the corresponding display is not found
2194 ASSERT_FALSE(mDevice->isEnabled());
2195
2196 // Prepare displays.
2197 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00002198 DISPLAY_ORIENTATION_0, true /*isActive*/, UNIQUE_ID, hdmi,
2199 ViewportType::INTERNAL);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002200 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2201 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002202 ASSERT_TRUE(mDevice->isEnabled());
2203
2204 // Device should be disabled after set disable.
2205 mFakePolicy->addDisabledDevice(mDevice->getId());
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002206 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2207 InputReaderConfiguration::CHANGE_ENABLED_STATE);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002208 ASSERT_FALSE(mDevice->isEnabled());
2209
2210 // Device should still be disabled even found the associated display.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002211 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2212 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002213 ASSERT_FALSE(mDevice->isEnabled());
2214}
Michael Wrightd02c5b62014-02-10 15:10:22 -08002215
Christine Franks1ba71cc2021-04-07 14:37:42 -07002216TEST_F(InputDeviceTest, Configure_AssignsDisplayUniqueId) {
2217 // Device should be enabled by default.
2218 mFakePolicy->clearViewports();
2219 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002220 std::list<NotifyArgs> unused =
2221 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
Christine Franks1ba71cc2021-04-07 14:37:42 -07002222 ASSERT_TRUE(mDevice->isEnabled());
2223
2224 // Device should be disabled because it is associated with a specific display, but the
2225 // corresponding display is not found.
Christine Franks2a2293c2022-01-18 11:51:16 -08002226 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002227 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2228 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Christine Franks1ba71cc2021-04-07 14:37:42 -07002229 ASSERT_FALSE(mDevice->isEnabled());
2230
2231 // Device should be enabled when a display is found.
2232 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
2233 DISPLAY_ORIENTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID,
2234 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002235 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2236 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Christine Franks1ba71cc2021-04-07 14:37:42 -07002237 ASSERT_TRUE(mDevice->isEnabled());
2238
2239 // Device should be disabled after set disable.
2240 mFakePolicy->addDisabledDevice(mDevice->getId());
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002241 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2242 InputReaderConfiguration::CHANGE_ENABLED_STATE);
Christine Franks1ba71cc2021-04-07 14:37:42 -07002243 ASSERT_FALSE(mDevice->isEnabled());
2244
2245 // Device should still be disabled even found the associated display.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002246 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2247 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Christine Franks1ba71cc2021-04-07 14:37:42 -07002248 ASSERT_FALSE(mDevice->isEnabled());
2249}
2250
Christine Franks2a2293c2022-01-18 11:51:16 -08002251TEST_F(InputDeviceTest, Configure_UniqueId_CorrectlyMatches) {
2252 mFakePolicy->clearViewports();
2253 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002254 std::list<NotifyArgs> unused =
2255 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
Christine Franks2a2293c2022-01-18 11:51:16 -08002256
Christine Franks2a2293c2022-01-18 11:51:16 -08002257 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
2258 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
2259 DISPLAY_ORIENTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID,
2260 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002261 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2262 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Christine Franks2a2293c2022-01-18 11:51:16 -08002263 ASSERT_EQ(DISPLAY_UNIQUE_ID, mDevice->getAssociatedDisplayUniqueId());
2264}
2265
Siarhei Vishniakou30feb8c2022-09-28 10:48:29 -07002266/**
2267 * This test reproduces a crash caused by a dangling reference that remains after device is added
2268 * and removed. The reference is accessed in InputDevice::dump(..);
2269 */
2270TEST_F(InputDeviceTest, DumpDoesNotCrash) {
2271 constexpr int32_t TEST_EVENTHUB_ID = 10;
2272 mFakeEventHub->addDevice(TEST_EVENTHUB_ID, "Test EventHub device", InputDeviceClass::BATTERY);
2273
2274 InputDevice device(mReader->getContext(), 1 /*id*/, 2 /*generation*/, {} /*identifier*/);
2275 device.addEventHubDevice(TEST_EVENTHUB_ID, true /*populateMappers*/);
2276 device.removeEventHubDevice(TEST_EVENTHUB_ID);
2277 std::string dumpStr, eventHubDevStr;
2278 device.dump(dumpStr, eventHubDevStr);
2279}
2280
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00002281TEST_F(InputDeviceTest, GetBluetoothAddress) {
2282 const auto& address = mReader->getBluetoothAddress(DEVICE_ID);
2283 ASSERT_TRUE(address);
2284 ASSERT_EQ(DEVICE_BLUETOOTH_ADDRESS, *address);
2285}
2286
Michael Wrightd02c5b62014-02-10 15:10:22 -08002287// --- InputMapperTest ---
2288
2289class InputMapperTest : public testing::Test {
2290protected:
2291 static const char* DEVICE_NAME;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07002292 static const char* DEVICE_LOCATION;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002293 static const int32_t DEVICE_ID;
2294 static const int32_t DEVICE_GENERATION;
2295 static const int32_t DEVICE_CONTROLLER_NUMBER;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002296 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002297 static const int32_t EVENTHUB_ID;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002298
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07002299 std::shared_ptr<FakeEventHub> mFakeEventHub;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002300 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002301 std::unique_ptr<TestInputListener> mFakeListener;
arthurhungdcef2dc2020-08-11 14:47:50 +08002302 std::unique_ptr<InstrumentedInputReader> mReader;
2303 std::shared_ptr<InputDevice> mDevice;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002304
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002305 virtual void SetUp(ftl::Flags<InputDeviceClass> classes, int bus = 0) {
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07002306 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07002307 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002308 mFakeListener = std::make_unique<TestInputListener>();
arthurhungdcef2dc2020-08-11 14:47:50 +08002309 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002310 *mFakeListener);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002311 mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes, bus);
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002312 // Consume the device reset notification generated when adding a new device.
2313 mFakeListener->assertNotifyDeviceResetWasCalled();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002314 }
2315
Prabir Pradhanc14266f2021-05-12 15:56:24 -07002316 void SetUp() override {
Prabir Pradhanc14266f2021-05-12 15:56:24 -07002317 SetUp(DEVICE_CLASSES);
2318 }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002319
Chris Yea52ade12020-08-27 16:49:20 -07002320 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002321 mFakeListener.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002322 mFakePolicy.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002323 }
2324
2325 void addConfigurationProperty(const char* key, const char* value) {
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002326 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, key, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002327 }
2328
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002329 std::list<NotifyArgs> configureDevice(uint32_t changes) {
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00002330 if (!changes ||
2331 (changes &
2332 (InputReaderConfiguration::CHANGE_DISPLAY_INFO |
2333 InputReaderConfiguration::CHANGE_POINTER_CAPTURE))) {
arthurhungdcef2dc2020-08-11 14:47:50 +08002334 mReader->requestRefreshConfiguration(changes);
2335 mReader->loopOnce();
Prabir Pradhanc7ef27e2020-02-03 19:19:15 -08002336 }
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002337 std::list<NotifyArgs> out =
2338 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes);
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002339 // Loop the reader to flush the input listener queue.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002340 for (const NotifyArgs& args : out) {
2341 mFakeListener->notify(args);
2342 }
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002343 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002344 return out;
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08002345 }
2346
arthurhungdcef2dc2020-08-11 14:47:50 +08002347 std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
2348 const std::string& location, int32_t eventHubId,
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002349 ftl::Flags<InputDeviceClass> classes, int bus = 0) {
arthurhungdcef2dc2020-08-11 14:47:50 +08002350 InputDeviceIdentifier identifier;
2351 identifier.name = name;
2352 identifier.location = location;
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002353 identifier.bus = bus;
arthurhungdcef2dc2020-08-11 14:47:50 +08002354 std::shared_ptr<InputDevice> device =
2355 std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
2356 identifier);
2357 mReader->pushNextDevice(device);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002358 mFakeEventHub->addDevice(eventHubId, name, classes, bus);
arthurhungdcef2dc2020-08-11 14:47:50 +08002359 mReader->loopOnce();
2360 return device;
2361 }
2362
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002363 template <class T, typename... Args>
2364 T& addMapperAndConfigure(Args... args) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002365 T& mapper = mDevice->addMapper<T>(EVENTHUB_ID, args...);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08002366 configureDevice(0);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002367 std::list<NotifyArgs> resetArgList = mDevice->reset(ARBITRARY_TIME);
2368 resetArgList += mapper.reset(ARBITRARY_TIME);
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002369 // Loop the reader to flush the input listener queue.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002370 for (const NotifyArgs& loopArgs : resetArgList) {
2371 mFakeListener->notify(loopArgs);
2372 }
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002373 mReader->loopOnce();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002374 return mapper;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002375 }
2376
2377 void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07002378 int32_t orientation, const std::string& uniqueId,
2379 std::optional<uint8_t> physicalPort, ViewportType viewportType) {
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00002380 mFakePolicy->addDisplayViewport(displayId, width, height, orientation, true /*isActive*/,
2381 uniqueId, physicalPort, viewportType);
Santos Cordonfa5cf462017-04-05 10:37:00 -07002382 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2383 }
2384
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002385 void clearViewports() {
2386 mFakePolicy->clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002387 }
2388
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002389 std::list<NotifyArgs> process(InputMapper& mapper, nsecs_t when, nsecs_t readTime, int32_t type,
2390 int32_t code, int32_t value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002391 RawEvent event;
2392 event.when = when;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002393 event.readTime = readTime;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002394 event.deviceId = mapper.getDeviceContext().getEventHubId();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002395 event.type = type;
2396 event.code = code;
2397 event.value = value;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002398 std::list<NotifyArgs> processArgList = mapper.process(&event);
2399 for (const NotifyArgs& args : processArgList) {
2400 mFakeListener->notify(args);
2401 }
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002402 // Loop the reader to flush the input listener queue.
arthurhungdcef2dc2020-08-11 14:47:50 +08002403 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002404 return processArgList;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002405 }
2406
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00002407 void resetMapper(InputMapper& mapper, nsecs_t when) {
2408 const auto resetArgs = mapper.reset(when);
2409 for (const auto args : resetArgs) {
2410 mFakeListener->notify(args);
2411 }
2412 // Loop the reader to flush the input listener queue.
2413 mReader->loopOnce();
2414 }
2415
Michael Wrightd02c5b62014-02-10 15:10:22 -08002416 static void assertMotionRange(const InputDeviceInfo& info,
2417 int32_t axis, uint32_t source, float min, float max, float flat, float fuzz) {
2418 const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source);
Yi Kong9b14ac62018-07-17 13:48:38 -07002419 ASSERT_TRUE(range != nullptr) << "Axis: " << axis << " Source: " << source;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002420 ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source;
2421 ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source;
2422 ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source;
2423 ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source;
2424 ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source;
2425 ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source;
2426 }
2427
Prabir Pradhanf5334b82021-05-13 14:00:39 -07002428 static void assertPointerCoords(const PointerCoords& coords, float x, float y, float pressure,
2429 float size, float touchMajor, float touchMinor, float toolMajor,
2430 float toolMinor, float orientation, float distance,
2431 float scaledAxisEpsilon = 1.f) {
2432 ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), scaledAxisEpsilon);
2433 ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), scaledAxisEpsilon);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002434 ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON);
2435 ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07002436 ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2437 scaledAxisEpsilon);
2438 ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2439 scaledAxisEpsilon);
2440 ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2441 scaledAxisEpsilon);
2442 ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2443 scaledAxisEpsilon);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002444 ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON);
2445 ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON);
2446 }
2447
Michael Wright17db18e2020-06-26 20:51:44 +01002448 static void assertPosition(const FakePointerController& controller, float x, float y) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002449 float actualX, actualY;
Michael Wright17db18e2020-06-26 20:51:44 +01002450 controller.getPosition(&actualX, &actualY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002451 ASSERT_NEAR(x, actualX, 1);
2452 ASSERT_NEAR(y, actualY, 1);
2453 }
2454};
2455
2456const char* InputMapperTest::DEVICE_NAME = "device";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07002457const char* InputMapperTest::DEVICE_LOCATION = "USB1";
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002458const int32_t InputMapperTest::DEVICE_ID = END_RESERVED_ID + 1000;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002459const int32_t InputMapperTest::DEVICE_GENERATION = 2;
2460const int32_t InputMapperTest::DEVICE_CONTROLLER_NUMBER = 0;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002461const ftl::Flags<InputDeviceClass> InputMapperTest::DEVICE_CLASSES =
2462 ftl::Flags<InputDeviceClass>(0); // not needed for current tests
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002463const int32_t InputMapperTest::EVENTHUB_ID = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002464
2465// --- SwitchInputMapperTest ---
2466
2467class SwitchInputMapperTest : public InputMapperTest {
2468protected:
2469};
2470
2471TEST_F(SwitchInputMapperTest, GetSources) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002472 SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002473
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002474 ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002475}
2476
2477TEST_F(SwitchInputMapperTest, GetSwitchState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002478 SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002479
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002480 mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002481 ASSERT_EQ(1, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002482
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002483 mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002484 ASSERT_EQ(0, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002485}
2486
2487TEST_F(SwitchInputMapperTest, Process) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002488 SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002489 std::list<NotifyArgs> out;
2490 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_LID, 1);
2491 ASSERT_TRUE(out.empty());
2492 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_JACK_PHYSICAL_INSERT, 1);
2493 ASSERT_TRUE(out.empty());
2494 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_HEADPHONE_INSERT, 0);
2495 ASSERT_TRUE(out.empty());
2496 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002497
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002498 ASSERT_EQ(1u, out.size());
2499 const NotifySwitchArgs& args = std::get<NotifySwitchArgs>(*out.begin());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002500 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
Dan Albert1bd2fc02016-02-02 15:11:57 -08002501 ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT), args.switchValues);
2502 ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT) | (1 << SW_HEADPHONE_INSERT),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002503 args.switchMask);
2504 ASSERT_EQ(uint32_t(0), args.policyFlags);
2505}
2506
Chris Ye87143712020-11-10 05:05:58 +00002507// --- VibratorInputMapperTest ---
2508class VibratorInputMapperTest : public InputMapperTest {
2509protected:
2510 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::VIBRATOR); }
2511};
2512
2513TEST_F(VibratorInputMapperTest, GetSources) {
2514 VibratorInputMapper& mapper = addMapperAndConfigure<VibratorInputMapper>();
2515
2516 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mapper.getSources());
2517}
2518
2519TEST_F(VibratorInputMapperTest, GetVibratorIds) {
2520 VibratorInputMapper& mapper = addMapperAndConfigure<VibratorInputMapper>();
2521
2522 ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
2523}
2524
2525TEST_F(VibratorInputMapperTest, Vibrate) {
2526 constexpr uint8_t DEFAULT_AMPLITUDE = 192;
Chris Yefb552902021-02-03 17:18:37 -08002527 constexpr int32_t VIBRATION_TOKEN = 100;
Chris Ye87143712020-11-10 05:05:58 +00002528 VibratorInputMapper& mapper = addMapperAndConfigure<VibratorInputMapper>();
2529
2530 VibrationElement pattern(2);
2531 VibrationSequence sequence(2);
2532 pattern.duration = std::chrono::milliseconds(200);
2533 pattern.channels = {{0 /* vibratorId */, DEFAULT_AMPLITUDE / 2},
2534 {1 /* vibratorId */, DEFAULT_AMPLITUDE}};
2535 sequence.addElement(pattern);
2536 pattern.duration = std::chrono::milliseconds(500);
2537 pattern.channels = {{0 /* vibratorId */, DEFAULT_AMPLITUDE / 4},
2538 {1 /* vibratorId */, DEFAULT_AMPLITUDE}};
2539 sequence.addElement(pattern);
2540
2541 std::vector<int64_t> timings = {0, 1};
2542 std::vector<uint8_t> amplitudes = {DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE / 2};
2543
2544 ASSERT_FALSE(mapper.isVibrating());
Chris Yefb552902021-02-03 17:18:37 -08002545 // Start vibrating
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002546 std::list<NotifyArgs> out = mapper.vibrate(sequence, -1 /* repeat */, VIBRATION_TOKEN);
Chris Ye87143712020-11-10 05:05:58 +00002547 ASSERT_TRUE(mapper.isVibrating());
Chris Yefb552902021-02-03 17:18:37 -08002548 // Verify vibrator state listener was notified.
2549 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002550 ASSERT_EQ(1u, out.size());
2551 const NotifyVibratorStateArgs& vibrateArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
2552 ASSERT_EQ(DEVICE_ID, vibrateArgs.deviceId);
2553 ASSERT_TRUE(vibrateArgs.isOn);
Chris Yefb552902021-02-03 17:18:37 -08002554 // Stop vibrating
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002555 out = mapper.cancelVibrate(VIBRATION_TOKEN);
Chris Yefb552902021-02-03 17:18:37 -08002556 ASSERT_FALSE(mapper.isVibrating());
2557 // Verify vibrator state listener was notified.
2558 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002559 ASSERT_EQ(1u, out.size());
2560 const NotifyVibratorStateArgs& cancelArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
2561 ASSERT_EQ(DEVICE_ID, cancelArgs.deviceId);
2562 ASSERT_FALSE(cancelArgs.isOn);
Chris Ye87143712020-11-10 05:05:58 +00002563}
Michael Wrightd02c5b62014-02-10 15:10:22 -08002564
Chris Yef59a2f42020-10-16 12:55:26 -07002565// --- SensorInputMapperTest ---
2566
2567class SensorInputMapperTest : public InputMapperTest {
2568protected:
2569 static const int32_t ACCEL_RAW_MIN;
2570 static const int32_t ACCEL_RAW_MAX;
2571 static const int32_t ACCEL_RAW_FUZZ;
2572 static const int32_t ACCEL_RAW_FLAT;
2573 static const int32_t ACCEL_RAW_RESOLUTION;
2574
2575 static const int32_t GYRO_RAW_MIN;
2576 static const int32_t GYRO_RAW_MAX;
2577 static const int32_t GYRO_RAW_FUZZ;
2578 static const int32_t GYRO_RAW_FLAT;
2579 static const int32_t GYRO_RAW_RESOLUTION;
2580
2581 static const float GRAVITY_MS2_UNIT;
2582 static const float DEGREE_RADIAN_UNIT;
2583
2584 void prepareAccelAxes();
2585 void prepareGyroAxes();
2586 void setAccelProperties();
2587 void setGyroProperties();
2588 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::SENSOR); }
2589};
2590
2591const int32_t SensorInputMapperTest::ACCEL_RAW_MIN = -32768;
2592const int32_t SensorInputMapperTest::ACCEL_RAW_MAX = 32768;
2593const int32_t SensorInputMapperTest::ACCEL_RAW_FUZZ = 16;
2594const int32_t SensorInputMapperTest::ACCEL_RAW_FLAT = 0;
2595const int32_t SensorInputMapperTest::ACCEL_RAW_RESOLUTION = 8192;
2596
2597const int32_t SensorInputMapperTest::GYRO_RAW_MIN = -2097152;
2598const int32_t SensorInputMapperTest::GYRO_RAW_MAX = 2097152;
2599const int32_t SensorInputMapperTest::GYRO_RAW_FUZZ = 16;
2600const int32_t SensorInputMapperTest::GYRO_RAW_FLAT = 0;
2601const int32_t SensorInputMapperTest::GYRO_RAW_RESOLUTION = 1024;
2602
2603const float SensorInputMapperTest::GRAVITY_MS2_UNIT = 9.80665f;
2604const float SensorInputMapperTest::DEGREE_RADIAN_UNIT = 0.0174533f;
2605
2606void SensorInputMapperTest::prepareAccelAxes() {
2607 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
2608 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
2609 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
2610 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
2611 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Z, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
2612 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
2613}
2614
2615void SensorInputMapperTest::prepareGyroAxes() {
2616 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RX, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
2617 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
2618 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RY, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
2619 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
2620 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RZ, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
2621 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
2622}
2623
2624void SensorInputMapperTest::setAccelProperties() {
2625 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 0, InputDeviceSensorType::ACCELEROMETER,
2626 /* sensorDataIndex */ 0);
2627 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 1, InputDeviceSensorType::ACCELEROMETER,
2628 /* sensorDataIndex */ 1);
2629 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 2, InputDeviceSensorType::ACCELEROMETER,
2630 /* sensorDataIndex */ 2);
2631 mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP);
2632 addConfigurationProperty("sensor.accelerometer.reportingMode", "0");
2633 addConfigurationProperty("sensor.accelerometer.maxDelay", "100000");
2634 addConfigurationProperty("sensor.accelerometer.minDelay", "5000");
2635 addConfigurationProperty("sensor.accelerometer.power", "1.5");
2636}
2637
2638void SensorInputMapperTest::setGyroProperties() {
2639 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 3, InputDeviceSensorType::GYROSCOPE,
2640 /* sensorDataIndex */ 0);
2641 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 4, InputDeviceSensorType::GYROSCOPE,
2642 /* sensorDataIndex */ 1);
2643 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 5, InputDeviceSensorType::GYROSCOPE,
2644 /* sensorDataIndex */ 2);
2645 mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP);
2646 addConfigurationProperty("sensor.gyroscope.reportingMode", "0");
2647 addConfigurationProperty("sensor.gyroscope.maxDelay", "100000");
2648 addConfigurationProperty("sensor.gyroscope.minDelay", "5000");
2649 addConfigurationProperty("sensor.gyroscope.power", "0.8");
2650}
2651
2652TEST_F(SensorInputMapperTest, GetSources) {
2653 SensorInputMapper& mapper = addMapperAndConfigure<SensorInputMapper>();
2654
2655 ASSERT_EQ(static_cast<uint32_t>(AINPUT_SOURCE_SENSOR), mapper.getSources());
2656}
2657
2658TEST_F(SensorInputMapperTest, ProcessAccelerometerSensor) {
2659 setAccelProperties();
2660 prepareAccelAxes();
2661 SensorInputMapper& mapper = addMapperAndConfigure<SensorInputMapper>();
2662
2663 ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::ACCELEROMETER,
2664 std::chrono::microseconds(10000),
2665 std::chrono::microseconds(0)));
Chris Yee14523a2020-12-19 13:46:00 -08002666 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002667 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, 20000);
2668 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, -20000);
2669 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Z, 40000);
2670 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
2671 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Chris Yef59a2f42020-10-16 12:55:26 -07002672
2673 NotifySensorArgs args;
2674 std::vector<float> values = {20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT,
2675 -20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT,
2676 40000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT};
2677
2678 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args));
2679 ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR);
2680 ASSERT_EQ(args.deviceId, DEVICE_ID);
2681 ASSERT_EQ(args.sensorType, InputDeviceSensorType::ACCELEROMETER);
2682 ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
2683 ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME);
2684 ASSERT_EQ(args.values, values);
2685 mapper.flushSensor(InputDeviceSensorType::ACCELEROMETER);
2686}
2687
2688TEST_F(SensorInputMapperTest, ProcessGyroscopeSensor) {
2689 setGyroProperties();
2690 prepareGyroAxes();
2691 SensorInputMapper& mapper = addMapperAndConfigure<SensorInputMapper>();
2692
2693 ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::GYROSCOPE,
2694 std::chrono::microseconds(10000),
2695 std::chrono::microseconds(0)));
Chris Yee14523a2020-12-19 13:46:00 -08002696 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002697 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RX, 20000);
2698 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RY, -20000);
2699 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RZ, 40000);
2700 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
2701 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Chris Yef59a2f42020-10-16 12:55:26 -07002702
2703 NotifySensorArgs args;
2704 std::vector<float> values = {20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT,
2705 -20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT,
2706 40000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT};
2707
2708 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args));
2709 ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR);
2710 ASSERT_EQ(args.deviceId, DEVICE_ID);
2711 ASSERT_EQ(args.sensorType, InputDeviceSensorType::GYROSCOPE);
2712 ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
2713 ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME);
2714 ASSERT_EQ(args.values, values);
2715 mapper.flushSensor(InputDeviceSensorType::GYROSCOPE);
2716}
2717
Michael Wrightd02c5b62014-02-10 15:10:22 -08002718// --- KeyboardInputMapperTest ---
2719
2720class KeyboardInputMapperTest : public InputMapperTest {
2721protected:
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002722 const std::string UNIQUE_ID = "local:0";
2723
2724 void prepareDisplay(int32_t orientation);
2725
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002726 void testDPadKeyRotation(KeyboardInputMapper& mapper, int32_t originalScanCode,
Arthur Hung2c9a3342019-07-23 14:18:59 +08002727 int32_t originalKeyCode, int32_t rotatedKeyCode,
2728 int32_t displayId = ADISPLAY_ID_NONE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002729};
2730
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002731/* Similar to setDisplayInfoAndReconfigure, but pre-populates all parameters except for the
2732 * orientation.
2733 */
2734void KeyboardInputMapperTest::prepareDisplay(int32_t orientation) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01002735 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation, UNIQUE_ID,
2736 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002737}
2738
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002739void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper& mapper,
Arthur Hung2c9a3342019-07-23 14:18:59 +08002740 int32_t originalScanCode, int32_t originalKeyCode,
2741 int32_t rotatedKeyCode, int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002742 NotifyKeyArgs args;
2743
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002744 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002745 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2746 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
2747 ASSERT_EQ(originalScanCode, args.scanCode);
2748 ASSERT_EQ(rotatedKeyCode, args.keyCode);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002749 ASSERT_EQ(displayId, args.displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002750
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002751 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002752 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2753 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
2754 ASSERT_EQ(originalScanCode, args.scanCode);
2755 ASSERT_EQ(rotatedKeyCode, args.keyCode);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002756 ASSERT_EQ(displayId, args.displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002757}
2758
Michael Wrightd02c5b62014-02-10 15:10:22 -08002759TEST_F(KeyboardInputMapperTest, GetSources) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002760 KeyboardInputMapper& mapper =
2761 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
2762 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002763
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002764 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002765}
2766
2767TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) {
2768 const int32_t USAGE_A = 0x070004;
2769 const int32_t USAGE_UNKNOWN = 0x07ffff;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002770 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
2771 mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
Chris Yea52ade12020-08-27 16:49:20 -07002772 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, POLICY_FLAG_WAKE);
2773 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, POLICY_FLAG_WAKE);
2774 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, POLICY_FLAG_WAKE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002775
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002776 KeyboardInputMapper& mapper =
2777 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
2778 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08002779 // Initial metastate is AMETA_NONE.
2780 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002781
2782 // Key down by scan code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002783 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002784 NotifyKeyArgs args;
2785 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2786 ASSERT_EQ(DEVICE_ID, args.deviceId);
2787 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
2788 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
2789 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
2790 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
2791 ASSERT_EQ(KEY_HOME, args.scanCode);
2792 ASSERT_EQ(AMETA_NONE, args.metaState);
2793 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
2794 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
2795 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
2796
2797 // Key up by scan code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002798 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002799 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2800 ASSERT_EQ(DEVICE_ID, args.deviceId);
2801 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
2802 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
2803 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
2804 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
2805 ASSERT_EQ(KEY_HOME, args.scanCode);
2806 ASSERT_EQ(AMETA_NONE, args.metaState);
2807 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
2808 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
2809 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
2810
2811 // Key down by usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002812 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_A);
2813 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, 0, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002814 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2815 ASSERT_EQ(DEVICE_ID, args.deviceId);
2816 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
2817 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
2818 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
2819 ASSERT_EQ(AKEYCODE_A, args.keyCode);
2820 ASSERT_EQ(0, args.scanCode);
2821 ASSERT_EQ(AMETA_NONE, args.metaState);
2822 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
2823 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
2824 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
2825
2826 // Key up by usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002827 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_A);
2828 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002829 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2830 ASSERT_EQ(DEVICE_ID, args.deviceId);
2831 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
2832 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
2833 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
2834 ASSERT_EQ(AKEYCODE_A, args.keyCode);
2835 ASSERT_EQ(0, args.scanCode);
2836 ASSERT_EQ(AMETA_NONE, args.metaState);
2837 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
2838 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
2839 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
2840
2841 // Key down with unknown scan code or usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002842 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
2843 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UNKNOWN, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002844 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2845 ASSERT_EQ(DEVICE_ID, args.deviceId);
2846 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
2847 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
2848 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
2849 ASSERT_EQ(0, args.keyCode);
2850 ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
2851 ASSERT_EQ(AMETA_NONE, args.metaState);
2852 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
2853 ASSERT_EQ(0U, args.policyFlags);
2854 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
2855
2856 // Key up with unknown scan code or usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002857 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
2858 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_UNKNOWN, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002859 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2860 ASSERT_EQ(DEVICE_ID, args.deviceId);
2861 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
2862 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
2863 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
2864 ASSERT_EQ(0, args.keyCode);
2865 ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
2866 ASSERT_EQ(AMETA_NONE, args.metaState);
2867 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
2868 ASSERT_EQ(0U, args.policyFlags);
2869 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
2870}
2871
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002872/**
2873 * Ensure that the readTime is set to the time when the EV_KEY is received.
2874 */
2875TEST_F(KeyboardInputMapperTest, Process_SendsReadTime) {
2876 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
2877
2878 KeyboardInputMapper& mapper =
2879 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
2880 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
2881 NotifyKeyArgs args;
2882
2883 // Key down
2884 process(mapper, ARBITRARY_TIME, 12 /*readTime*/, EV_KEY, KEY_HOME, 1);
2885 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2886 ASSERT_EQ(12, args.readTime);
2887
2888 // Key up
2889 process(mapper, ARBITRARY_TIME, 15 /*readTime*/, EV_KEY, KEY_HOME, 1);
2890 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2891 ASSERT_EQ(15, args.readTime);
2892}
2893
Michael Wrightd02c5b62014-02-10 15:10:22 -08002894TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002895 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFTSHIFT, 0, AKEYCODE_SHIFT_LEFT, 0);
2896 mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
Chris Yea52ade12020-08-27 16:49:20 -07002897 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, 0);
2898 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, 0);
2899 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002900
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002901 KeyboardInputMapper& mapper =
2902 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
2903 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002904
Arthur Hung95f68612022-04-07 14:08:22 +08002905 // Initial metastate is AMETA_NONE.
2906 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002907
2908 // Metakey down.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002909 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_LEFTSHIFT, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002910 NotifyKeyArgs args;
2911 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2912 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002913 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
arthurhungdcef2dc2020-08-11 14:47:50 +08002914 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertUpdateGlobalMetaStateWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002915
2916 // Key down.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002917 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_A, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002918 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2919 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002920 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002921
2922 // Key up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002923 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, KEY_A, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2925 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002926 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002927
2928 // Metakey up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002929 process(mapper, ARBITRARY_TIME + 3, READ_TIME, EV_KEY, KEY_LEFTSHIFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002930 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2931 ASSERT_EQ(AMETA_NONE, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002932 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
arthurhungdcef2dc2020-08-11 14:47:50 +08002933 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertUpdateGlobalMetaStateWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002934}
2935
2936TEST_F(KeyboardInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateDPad) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002937 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
2938 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
2939 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
2940 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002941
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002942 KeyboardInputMapper& mapper =
2943 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
2944 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002945
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002946 prepareDisplay(DISPLAY_ORIENTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002947 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
2948 KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP));
2949 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
2950 KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT));
2951 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
2952 KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN));
2953 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
2954 KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT));
2955}
2956
2957TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002958 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
2959 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
2960 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
2961 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002962
Michael Wrightd02c5b62014-02-10 15:10:22 -08002963 addConfigurationProperty("keyboard.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002964 KeyboardInputMapper& mapper =
2965 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
2966 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002967
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002968 prepareDisplay(DISPLAY_ORIENTATION_0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002969 ASSERT_NO_FATAL_FAILURE(
2970 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID));
2971 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
2972 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
2973 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
2974 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
2975 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
2976 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002977
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002978 clearViewports();
2979 prepareDisplay(DISPLAY_ORIENTATION_90);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002980 ASSERT_NO_FATAL_FAILURE(
2981 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, DISPLAY_ID));
2982 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
2983 AKEYCODE_DPAD_UP, DISPLAY_ID));
2984 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
2985 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
2986 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
2987 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002988
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002989 clearViewports();
2990 prepareDisplay(DISPLAY_ORIENTATION_180);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002991 ASSERT_NO_FATAL_FAILURE(
2992 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN, DISPLAY_ID));
2993 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
2994 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
2995 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
2996 AKEYCODE_DPAD_UP, DISPLAY_ID));
2997 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
2998 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002999
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003000 clearViewports();
3001 prepareDisplay(DISPLAY_ORIENTATION_270);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003002 ASSERT_NO_FATAL_FAILURE(
3003 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3004 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3005 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3006 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3007 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3008 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3009 AKEYCODE_DPAD_UP, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003010
3011 // Special case: if orientation changes while key is down, we still emit the same keycode
3012 // in the key up as we did in the key down.
3013 NotifyKeyArgs args;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003014 clearViewports();
3015 prepareDisplay(DISPLAY_ORIENTATION_270);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003016 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003017 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3018 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3019 ASSERT_EQ(KEY_UP, args.scanCode);
3020 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
3021
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003022 clearViewports();
3023 prepareDisplay(DISPLAY_ORIENTATION_180);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003024 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003025 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3026 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3027 ASSERT_EQ(KEY_UP, args.scanCode);
3028 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
3029}
3030
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003031TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_NotOrientationAware) {
3032 // If the keyboard is not orientation aware,
3033 // key events should not be associated with a specific display id
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003034 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003035
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003036 KeyboardInputMapper& mapper =
3037 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3038 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003039 NotifyKeyArgs args;
3040
3041 // Display id should be ADISPLAY_ID_NONE without any display configuration.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003042 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003043 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003044 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003045 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3046 ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
3047
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003048 prepareDisplay(DISPLAY_ORIENTATION_0);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003049 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003050 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003051 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003052 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3053 ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
3054}
3055
3056TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_OrientationAware) {
3057 // If the keyboard is orientation aware,
3058 // key events should be associated with the internal viewport
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003059 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003060
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003061 addConfigurationProperty("keyboard.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003062 KeyboardInputMapper& mapper =
3063 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3064 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003065 NotifyKeyArgs args;
3066
3067 // Display id should be ADISPLAY_ID_NONE without any display configuration.
3068 // ^--- already checked by the previous test
3069
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003070 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003071 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003072 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003073 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003074 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003075 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3076 ASSERT_EQ(DISPLAY_ID, args.displayId);
3077
3078 constexpr int32_t newDisplayId = 2;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003079 clearViewports();
3080 setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003081 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003082 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003083 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003084 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003085 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3086 ASSERT_EQ(newDisplayId, args.displayId);
3087}
3088
Michael Wrightd02c5b62014-02-10 15:10:22 -08003089TEST_F(KeyboardInputMapperTest, GetKeyCodeState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003090 KeyboardInputMapper& mapper =
3091 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3092 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003093
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003094 mFakeEventHub->setKeyCodeState(EVENTHUB_ID, AKEYCODE_A, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003095 ASSERT_EQ(1, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003096
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003097 mFakeEventHub->setKeyCodeState(EVENTHUB_ID, AKEYCODE_A, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003098 ASSERT_EQ(0, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003099}
3100
Philip Junker4af3b3d2021-12-14 10:36:55 +01003101TEST_F(KeyboardInputMapperTest, GetKeyCodeForKeyLocation) {
3102 KeyboardInputMapper& mapper =
3103 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3104 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3105
3106 mFakeEventHub->addKeyCodeMapping(EVENTHUB_ID, AKEYCODE_Y, AKEYCODE_Z);
3107 ASSERT_EQ(AKEYCODE_Z, mapper.getKeyCodeForKeyLocation(AKEYCODE_Y))
3108 << "If a mapping is available, the result is equal to the mapping";
3109
3110 ASSERT_EQ(AKEYCODE_A, mapper.getKeyCodeForKeyLocation(AKEYCODE_A))
3111 << "If no mapping is available, the result is the key location";
3112}
3113
Michael Wrightd02c5b62014-02-10 15:10:22 -08003114TEST_F(KeyboardInputMapperTest, GetScanCodeState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003115 KeyboardInputMapper& mapper =
3116 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3117 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003118
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003119 mFakeEventHub->setScanCodeState(EVENTHUB_ID, KEY_A, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003120 ASSERT_EQ(1, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003121
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003122 mFakeEventHub->setScanCodeState(EVENTHUB_ID, KEY_A, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003123 ASSERT_EQ(0, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003124}
3125
3126TEST_F(KeyboardInputMapperTest, MarkSupportedKeyCodes) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003127 KeyboardInputMapper& mapper =
3128 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3129 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003130
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003131 mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003132
Michael Wrightd02c5b62014-02-10 15:10:22 -08003133 uint8_t flags[2] = { 0, 0 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07003134 ASSERT_TRUE(mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, {AKEYCODE_A, AKEYCODE_B}, flags));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003135 ASSERT_TRUE(flags[0]);
3136 ASSERT_FALSE(flags[1]);
3137}
3138
3139TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003140 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3141 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3142 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3143 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3144 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3145 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003146
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003147 KeyboardInputMapper& mapper =
3148 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3149 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003150 // Initial metastate is AMETA_NONE.
3151 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003152
3153 // Initialization should have turned all of the lights off.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003154 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3155 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3156 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003157
3158 // Toggle caps lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003159 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3160 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003161 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3162 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3163 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003164 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003165
3166 // Toggle num lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003167 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3168 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003169 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3170 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3171 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003172 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003173
3174 // Toggle caps lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003175 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3176 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003177 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3178 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3179 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003180 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003181
3182 // Toggle scroll lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003183 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3184 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003185 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3186 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3187 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003188 ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003189
3190 // Toggle num lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003191 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3192 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003193 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3194 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3195 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003196 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003197
3198 // Toggle scroll lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003199 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3200 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003201 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3202 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3203 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003204 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003205}
3206
Chris Yea52ade12020-08-27 16:49:20 -07003207TEST_F(KeyboardInputMapperTest, NoMetaStateWhenMetaKeysNotPresent) {
3208 mFakeEventHub->addKey(EVENTHUB_ID, BTN_A, 0, AKEYCODE_BUTTON_A, 0);
3209 mFakeEventHub->addKey(EVENTHUB_ID, BTN_B, 0, AKEYCODE_BUTTON_B, 0);
3210 mFakeEventHub->addKey(EVENTHUB_ID, BTN_X, 0, AKEYCODE_BUTTON_X, 0);
3211 mFakeEventHub->addKey(EVENTHUB_ID, BTN_Y, 0, AKEYCODE_BUTTON_Y, 0);
3212
3213 KeyboardInputMapper& mapper =
3214 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3215 AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
3216
Chris Yea52ade12020-08-27 16:49:20 -07003217 // Meta state should be AMETA_NONE after reset
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003218 std::list<NotifyArgs> unused = mapper.reset(ARBITRARY_TIME);
Chris Yea52ade12020-08-27 16:49:20 -07003219 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3220 // Meta state should be AMETA_NONE with update, as device doesn't have the keys.
3221 mapper.updateMetaState(AKEYCODE_NUM_LOCK);
3222 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3223
3224 NotifyKeyArgs args;
3225 // Press button "A"
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003226 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_A, 1);
Chris Yea52ade12020-08-27 16:49:20 -07003227 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3228 ASSERT_EQ(AMETA_NONE, args.metaState);
3229 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3230 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3231 ASSERT_EQ(AKEYCODE_BUTTON_A, args.keyCode);
3232
3233 // Button up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003234 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, BTN_A, 0);
Chris Yea52ade12020-08-27 16:49:20 -07003235 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3236 ASSERT_EQ(AMETA_NONE, args.metaState);
3237 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3238 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3239 ASSERT_EQ(AKEYCODE_BUTTON_A, args.keyCode);
3240}
3241
Arthur Hung2c9a3342019-07-23 14:18:59 +08003242TEST_F(KeyboardInputMapperTest, Configure_AssignsDisplayPort) {
3243 // keyboard 1.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003244 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3245 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3246 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3247 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003248
3249 // keyboard 2.
3250 const std::string USB2 = "USB2";
arthurhungdcef2dc2020-08-11 14:47:50 +08003251 const std::string DEVICE_NAME2 = "KEYBOARD2";
Arthur Hung2c9a3342019-07-23 14:18:59 +08003252 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003253 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
arthurhungdcef2dc2020-08-11 14:47:50 +08003254 std::shared_ptr<InputDevice> device2 =
3255 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07003256 ftl::Flags<InputDeviceClass>(0));
arthurhungdcef2dc2020-08-11 14:47:50 +08003257
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003258 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3259 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3260 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3261 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003262
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003263 KeyboardInputMapper& mapper =
3264 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3265 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003266
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003267 KeyboardInputMapper& mapper2 =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003268 device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003269 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003270 std::list<NotifyArgs> unused =
3271 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3272 0 /*changes*/);
3273 unused += device2->reset(ARBITRARY_TIME);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003274
3275 // Prepared displays and associated info.
3276 constexpr uint8_t hdmi1 = 0;
3277 constexpr uint8_t hdmi2 = 1;
3278 const std::string SECONDARY_UNIQUE_ID = "local:1";
3279
3280 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
3281 mFakePolicy->addInputPortAssociation(USB2, hdmi2);
3282
3283 // No associated display viewport found, should disable the device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003284 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3285 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003286 ASSERT_FALSE(device2->isEnabled());
3287
3288 // Prepare second display.
3289 constexpr int32_t newDisplayId = 2;
3290 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003291 UNIQUE_ID, hdmi1, ViewportType::INTERNAL);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003292 setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003293 SECONDARY_UNIQUE_ID, hdmi2, ViewportType::EXTERNAL);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003294 // Default device will reconfigure above, need additional reconfiguration for another device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003295 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3296 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003297
3298 // Device should be enabled after the associated display is found.
3299 ASSERT_TRUE(mDevice->isEnabled());
3300 ASSERT_TRUE(device2->isEnabled());
3301
3302 // Test pad key events
3303 ASSERT_NO_FATAL_FAILURE(
3304 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID));
3305 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3306 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3307 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3308 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3309 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3310 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3311
3312 ASSERT_NO_FATAL_FAILURE(
3313 testDPadKeyRotation(mapper2, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, newDisplayId));
3314 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3315 AKEYCODE_DPAD_RIGHT, newDisplayId));
3316 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3317 AKEYCODE_DPAD_DOWN, newDisplayId));
3318 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3319 AKEYCODE_DPAD_LEFT, newDisplayId));
3320}
Michael Wrightd02c5b62014-02-10 15:10:22 -08003321
arthurhungc903df12020-08-11 15:08:42 +08003322TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleAfterReattach) {
3323 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3324 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3325 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3326 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3327 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3328 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3329
3330 KeyboardInputMapper& mapper =
3331 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3332 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003333 // Initial metastate is AMETA_NONE.
3334 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
arthurhungc903df12020-08-11 15:08:42 +08003335
3336 // Initialization should have turned all of the lights off.
3337 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3338 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3339 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3340
3341 // Toggle caps lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003342 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3343 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003344 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3345 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
3346
3347 // Toggle num lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003348 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3349 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003350 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3351 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState());
3352
3353 // Toggle scroll lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003354 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3355 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003356 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3357 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
3358
3359 mFakeEventHub->removeDevice(EVENTHUB_ID);
3360 mReader->loopOnce();
3361
3362 // keyboard 2 should default toggle keys.
3363 const std::string USB2 = "USB2";
3364 const std::string DEVICE_NAME2 = "KEYBOARD2";
3365 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
3366 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
3367 std::shared_ptr<InputDevice> device2 =
3368 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07003369 ftl::Flags<InputDeviceClass>(0));
arthurhungc903df12020-08-11 15:08:42 +08003370 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3371 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/);
3372 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3373 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3374 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3375 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3376
arthurhung6fe95782020-10-05 22:41:16 +08003377 KeyboardInputMapper& mapper2 =
3378 device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
3379 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003380 std::list<NotifyArgs> unused =
3381 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3382 0 /*changes*/);
3383 unused += device2->reset(ARBITRARY_TIME);
arthurhungc903df12020-08-11 15:08:42 +08003384
3385 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_CAPSL));
3386 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_NUML));
3387 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_SCROLLL));
arthurhung6fe95782020-10-05 22:41:16 +08003388 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON,
3389 mapper2.getMetaState());
arthurhungc903df12020-08-11 15:08:42 +08003390}
3391
Arthur Hungcb40a002021-08-03 14:31:01 +00003392TEST_F(KeyboardInputMapperTest, Process_toggleCapsLockState) {
3393 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3394 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3395 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3396
3397 // Suppose we have two mappers. (DPAD + KEYBOARD)
3398 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_DPAD,
3399 AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
3400 KeyboardInputMapper& mapper =
3401 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3402 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003403 // Initial metastate is AMETA_NONE.
3404 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Arthur Hungcb40a002021-08-03 14:31:01 +00003405
3406 mReader->toggleCapsLockState(DEVICE_ID);
3407 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
3408}
3409
Arthur Hungfb3cc112022-04-13 07:39:50 +00003410TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleInMultiDevices) {
3411 // keyboard 1.
3412 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3413 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3414 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3415 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3416 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3417 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3418
3419 KeyboardInputMapper& mapper1 =
3420 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3421 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3422
3423 // keyboard 2.
3424 const std::string USB2 = "USB2";
3425 const std::string DEVICE_NAME2 = "KEYBOARD2";
3426 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
3427 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
3428 std::shared_ptr<InputDevice> device2 =
3429 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
3430 ftl::Flags<InputDeviceClass>(0));
3431 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3432 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/);
3433 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3434 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3435 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3436 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3437
3438 KeyboardInputMapper& mapper2 =
3439 device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
3440 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003441 std::list<NotifyArgs> unused =
3442 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3443 0 /*changes*/);
3444 unused += device2->reset(ARBITRARY_TIME);
Arthur Hungfb3cc112022-04-13 07:39:50 +00003445
Arthur Hung95f68612022-04-07 14:08:22 +08003446 // Initial metastate is AMETA_NONE.
3447 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3448 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3449
3450 // Toggle num lock on and off.
3451 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3452 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Arthur Hungfb3cc112022-04-13 07:39:50 +00003453 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3454 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper1.getMetaState());
3455 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper2.getMetaState());
3456
3457 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3458 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
3459 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3460 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3461 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3462
3463 // Toggle caps lock on and off.
3464 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3465 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
3466 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3467 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper1.getMetaState());
3468 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper2.getMetaState());
3469
3470 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3471 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
3472 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3473 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3474 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3475
3476 // Toggle scroll lock on and off.
3477 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3478 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
3479 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3480 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper1.getMetaState());
3481 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper2.getMetaState());
3482
3483 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3484 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
3485 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3486 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3487 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3488}
3489
Arthur Hung2141d542022-08-23 07:45:21 +00003490TEST_F(KeyboardInputMapperTest, Process_DisabledDevice) {
3491 const int32_t USAGE_A = 0x070004;
3492 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3493 mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
3494
3495 KeyboardInputMapper& mapper =
3496 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3497 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3498 // Key down by scan code.
3499 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
3500 NotifyKeyArgs args;
3501 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3502 ASSERT_EQ(DEVICE_ID, args.deviceId);
3503 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3504 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3505 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3506 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3507 ASSERT_EQ(KEY_HOME, args.scanCode);
3508 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3509
3510 // Disable device, it should synthesize cancellation events for down events.
3511 mFakePolicy->addDisabledDevice(DEVICE_ID);
3512 configureDevice(InputReaderConfiguration::CHANGE_ENABLED_STATE);
3513
3514 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3515 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3516 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3517 ASSERT_EQ(KEY_HOME, args.scanCode);
3518 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED, args.flags);
3519}
3520
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003521// --- KeyboardInputMapperTest_ExternalDevice ---
3522
3523class KeyboardInputMapperTest_ExternalDevice : public InputMapperTest {
3524protected:
Chris Yea52ade12020-08-27 16:49:20 -07003525 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003526};
3527
3528TEST_F(KeyboardInputMapperTest_ExternalDevice, WakeBehavior) {
Powei Fengd041c5d2019-05-03 17:11:33 -07003529 // For external devices, non-media keys will trigger wake on key down. Media keys need to be
3530 // marked as WAKE in the keylayout file to trigger wake.
Powei Fengd041c5d2019-05-03 17:11:33 -07003531
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003532 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, 0);
3533 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, 0);
3534 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAYPAUSE, 0, AKEYCODE_MEDIA_PLAY_PAUSE,
3535 POLICY_FLAG_WAKE);
Powei Fengd041c5d2019-05-03 17:11:33 -07003536
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003537 KeyboardInputMapper& mapper =
3538 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3539 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Powei Fengd041c5d2019-05-03 17:11:33 -07003540
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003541 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003542 NotifyKeyArgs args;
3543 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3544 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3545
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003546 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003547 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3548 ASSERT_EQ(uint32_t(0), args.policyFlags);
3549
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003550 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAY, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003551 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3552 ASSERT_EQ(uint32_t(0), args.policyFlags);
3553
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003554 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAY, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003555 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3556 ASSERT_EQ(uint32_t(0), args.policyFlags);
3557
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003558 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAYPAUSE, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003559 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3560 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3561
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003562 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAYPAUSE, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003563 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3564 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3565}
3566
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003567TEST_F(KeyboardInputMapperTest_ExternalDevice, DoNotWakeByDefaultBehavior) {
Powei Fengd041c5d2019-05-03 17:11:33 -07003568 // Tv Remote key's wake behavior is prescribed by the keylayout file.
Powei Fengd041c5d2019-05-03 17:11:33 -07003569
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003570 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3571 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3572 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, POLICY_FLAG_WAKE);
Powei Fengd041c5d2019-05-03 17:11:33 -07003573
Powei Fengd041c5d2019-05-03 17:11:33 -07003574 addConfigurationProperty("keyboard.doNotWakeByDefault", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003575 KeyboardInputMapper& mapper =
3576 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3577 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Powei Fengd041c5d2019-05-03 17:11:33 -07003578
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003579 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003580 NotifyKeyArgs args;
3581 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3582 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3583
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003584 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003585 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3586 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3587
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003588 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_DOWN, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003589 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3590 ASSERT_EQ(uint32_t(0), args.policyFlags);
3591
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003592 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_DOWN, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003593 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3594 ASSERT_EQ(uint32_t(0), args.policyFlags);
3595
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003596 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAY, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003597 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3598 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3599
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003600 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAY, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003601 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3602 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3603}
3604
Michael Wrightd02c5b62014-02-10 15:10:22 -08003605// --- CursorInputMapperTest ---
3606
3607class CursorInputMapperTest : public InputMapperTest {
3608protected:
3609 static const int32_t TRACKBALL_MOVEMENT_THRESHOLD;
3610
Michael Wright17db18e2020-06-26 20:51:44 +01003611 std::shared_ptr<FakePointerController> mFakePointerController;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003612
Chris Yea52ade12020-08-27 16:49:20 -07003613 void SetUp() override {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003614 InputMapperTest::SetUp();
3615
Michael Wright17db18e2020-06-26 20:51:44 +01003616 mFakePointerController = std::make_shared<FakePointerController>();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00003617 mFakePolicy->setPointerController(mFakePointerController);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003618 }
3619
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003620 void testMotionRotation(CursorInputMapper& mapper, int32_t originalX, int32_t originalY,
3621 int32_t rotatedX, int32_t rotatedY);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07003622
3623 void prepareDisplay(int32_t orientation) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00003624 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation,
3625 DISPLAY_UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
3626 }
3627
3628 void prepareSecondaryDisplay() {
3629 setDisplayInfoAndReconfigure(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
3630 DISPLAY_ORIENTATION_0, SECONDARY_DISPLAY_UNIQUE_ID, NO_PORT,
3631 ViewportType::EXTERNAL);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07003632 }
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003633
3634 static void assertCursorPointerCoords(const PointerCoords& coords, float x, float y,
3635 float pressure) {
3636 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(coords, x, y, pressure, 0.0f, 0.0f, 0.0f, 0.0f,
3637 0.0f, 0.0f, 0.0f, EPSILON));
3638 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003639};
3640
3641const int32_t CursorInputMapperTest::TRACKBALL_MOVEMENT_THRESHOLD = 6;
3642
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003643void CursorInputMapperTest::testMotionRotation(CursorInputMapper& mapper, int32_t originalX,
3644 int32_t originalY, int32_t rotatedX,
3645 int32_t rotatedY) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003646 NotifyMotionArgs args;
3647
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003648 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, originalX);
3649 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, originalY);
3650 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003651 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3652 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003653 ASSERT_NO_FATAL_FAILURE(
3654 assertCursorPointerCoords(args.pointerCoords[0],
3655 float(rotatedX) / TRACKBALL_MOVEMENT_THRESHOLD,
3656 float(rotatedY) / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003657}
3658
3659TEST_F(CursorInputMapperTest, WhenModeIsPointer_GetSources_ReturnsMouse) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003660 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003661 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003662
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003663 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003664}
3665
3666TEST_F(CursorInputMapperTest, WhenModeIsNavigation_GetSources_ReturnsTrackball) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003667 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003668 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003669
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003670 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003671}
3672
3673TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeFromPointerController) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003674 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003675 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003676
3677 InputDeviceInfo info;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003678 mapper.populateDeviceInfo(&info);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003679
3680 // Initially there may not be a valid motion range.
Yi Kong9b14ac62018-07-17 13:48:38 -07003681 ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE));
3682 ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003683 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
3684 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE, 0.0f, 1.0f, 0.0f, 0.0f));
3685
3686 // When the bounds are set, then there should be a valid motion range.
3687 mFakePointerController->setBounds(1, 2, 800 - 1, 480 - 1);
3688
3689 InputDeviceInfo info2;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003690 mapper.populateDeviceInfo(&info2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003691
3692 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
3693 AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE,
3694 1, 800 - 1, 0.0f, 0.0f));
3695 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
3696 AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE,
3697 2, 480 - 1, 0.0f, 0.0f));
3698 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
3699 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE,
3700 0.0f, 1.0f, 0.0f, 0.0f));
3701}
3702
3703TEST_F(CursorInputMapperTest, WhenModeIsNavigation_PopulateDeviceInfo_ReturnsScaledRange) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003704 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003705 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003706
3707 InputDeviceInfo info;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003708 mapper.populateDeviceInfo(&info);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003709
3710 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
3711 AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_TRACKBALL,
3712 -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
3713 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
3714 AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_TRACKBALL,
3715 -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
3716 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
3717 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TRACKBALL,
3718 0.0f, 1.0f, 0.0f, 0.0f));
3719}
3720
3721TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003722 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003723 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003724
arthurhungdcef2dc2020-08-11 14:47:50 +08003725 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003726
3727 NotifyMotionArgs args;
3728
3729 // Button press.
3730 // Mostly testing non x/y behavior here so we don't need to check again elsewhere.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003731 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
3732 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003733 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3734 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3735 ASSERT_EQ(DEVICE_ID, args.deviceId);
3736 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
3737 ASSERT_EQ(uint32_t(0), args.policyFlags);
3738 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
3739 ASSERT_EQ(0, args.flags);
3740 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
3741 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
3742 ASSERT_EQ(0, args.edgeFlags);
3743 ASSERT_EQ(uint32_t(1), args.pointerCount);
3744 ASSERT_EQ(0, args.pointerProperties[0].id);
3745 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003746 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003747 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
3748 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
3749 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3750
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003751 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3752 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3753 ASSERT_EQ(DEVICE_ID, args.deviceId);
3754 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
3755 ASSERT_EQ(uint32_t(0), args.policyFlags);
3756 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
3757 ASSERT_EQ(0, args.flags);
3758 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
3759 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
3760 ASSERT_EQ(0, args.edgeFlags);
3761 ASSERT_EQ(uint32_t(1), args.pointerCount);
3762 ASSERT_EQ(0, args.pointerProperties[0].id);
3763 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003764 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003765 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
3766 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
3767 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3768
Michael Wrightd02c5b62014-02-10 15:10:22 -08003769 // Button release. Should have same down time.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003770 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, BTN_MOUSE, 0);
3771 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003772 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3773 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3774 ASSERT_EQ(DEVICE_ID, args.deviceId);
3775 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
3776 ASSERT_EQ(uint32_t(0), args.policyFlags);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003777 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
3778 ASSERT_EQ(0, args.flags);
3779 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
3780 ASSERT_EQ(0, args.buttonState);
3781 ASSERT_EQ(0, args.edgeFlags);
3782 ASSERT_EQ(uint32_t(1), args.pointerCount);
3783 ASSERT_EQ(0, args.pointerProperties[0].id);
3784 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003785 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003786 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
3787 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
3788 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3789
3790 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3791 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3792 ASSERT_EQ(DEVICE_ID, args.deviceId);
3793 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
3794 ASSERT_EQ(uint32_t(0), args.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003795 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
3796 ASSERT_EQ(0, args.flags);
3797 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
3798 ASSERT_EQ(0, args.buttonState);
3799 ASSERT_EQ(0, args.edgeFlags);
3800 ASSERT_EQ(uint32_t(1), args.pointerCount);
3801 ASSERT_EQ(0, args.pointerProperties[0].id);
3802 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003803 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003804 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
3805 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
3806 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3807}
3808
3809TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentXYUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003810 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003811 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003812
3813 NotifyMotionArgs args;
3814
3815 // Motion in X but not Y.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003816 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
3817 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003818 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3819 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003820 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
3821 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f,
3822 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003823
3824 // Motion in Y but not X.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003825 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, -2);
3826 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003827 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3828 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003829 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f,
3830 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003831}
3832
3833TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003834 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003835 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003836
3837 NotifyMotionArgs args;
3838
3839 // Button press.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003840 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
3841 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003842 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3843 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003844 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003845
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003846 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3847 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003848 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003849
Michael Wrightd02c5b62014-02-10 15:10:22 -08003850 // Button release.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003851 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 0);
3852 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003853 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003854 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003855 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003856
3857 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003858 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003859 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003860}
3861
3862TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003863 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003864 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003865
3866 NotifyMotionArgs args;
3867
3868 // Combined X, Y and Button.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003869 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
3870 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, -2);
3871 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
3872 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003873 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3874 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003875 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
3876 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
3877 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003878
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003879 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3880 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003881 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
3882 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
3883 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003884
Michael Wrightd02c5b62014-02-10 15:10:22 -08003885 // Move X, Y a bit while pressed.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003886 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 2);
3887 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 1);
3888 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003889 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3890 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003891 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
3892 2.0f / TRACKBALL_MOVEMENT_THRESHOLD,
3893 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003894
3895 // Release Button.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003896 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 0);
3897 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003898 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003899 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003900 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003901
3902 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003903 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003904 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003905}
3906
Prabir Pradhanc14266f2021-05-12 15:56:24 -07003907TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldNotRotateMotions) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00003908 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003909 addConfigurationProperty("cursor.mode", "navigation");
Prabir Pradhanc14266f2021-05-12 15:56:24 -07003910 // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
3911 // need to be rotated.
3912 addConfigurationProperty("cursor.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003913 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003914
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07003915 prepareDisplay(DISPLAY_ORIENTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003916 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1));
3917 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1));
3918 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0));
3919 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, -1));
3920 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1));
3921 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
3922 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0));
3923 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1));
3924}
3925
Prabir Pradhanc14266f2021-05-12 15:56:24 -07003926TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldRotateMotions) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00003927 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003928 addConfigurationProperty("cursor.mode", "navigation");
Prabir Pradhanc14266f2021-05-12 15:56:24 -07003929 // Since InputReader works in the un-rotated coordinate space, only devices that are not
3930 // orientation-aware are affected by display rotation.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003931 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003932
Prabir Pradhanc13ff082022-09-08 22:03:30 +00003933 clearViewports();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07003934 prepareDisplay(DISPLAY_ORIENTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003935 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1));
3936 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1));
3937 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0));
3938 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, -1));
3939 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1));
3940 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
3941 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0));
3942 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1));
3943
Prabir Pradhanc13ff082022-09-08 22:03:30 +00003944 clearViewports();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07003945 prepareDisplay(DISPLAY_ORIENTATION_90);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07003946 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, -1, 0));
3947 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, -1, 1));
3948 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 0, 1));
3949 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, 1));
3950 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 1, 0));
3951 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, -1));
3952 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, -1));
3953 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, -1));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003954
Prabir Pradhanc13ff082022-09-08 22:03:30 +00003955 clearViewports();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07003956 prepareDisplay(DISPLAY_ORIENTATION_180);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003957 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, -1));
3958 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, -1, -1));
3959 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, -1, 0));
3960 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, -1, 1));
3961 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, 1));
3962 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, 1));
3963 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 1, 0));
3964 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, -1));
3965
Prabir Pradhanc13ff082022-09-08 22:03:30 +00003966 clearViewports();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07003967 prepareDisplay(DISPLAY_ORIENTATION_270);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07003968 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 1, 0));
3969 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, -1));
3970 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 0, -1));
3971 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, -1, -1));
3972 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, -1, 0));
3973 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, 1));
3974 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, 1));
3975 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, 1));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003976}
3977
3978TEST_F(CursorInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003979 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003980 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003981
3982 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
3983 mFakePointerController->setPosition(100, 200);
3984 mFakePointerController->setButtonState(0);
3985
3986 NotifyMotionArgs motionArgs;
3987 NotifyKeyArgs keyArgs;
3988
3989 // press BTN_LEFT, release BTN_LEFT
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003990 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_LEFT, 1);
3991 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003992 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3993 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
3994 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
3995 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003996 ASSERT_NO_FATAL_FAILURE(
3997 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003998
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003999 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4000 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4001 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
4002 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004003 ASSERT_NO_FATAL_FAILURE(
4004 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004005
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004006 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_LEFT, 0);
4007 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004008 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004009 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004010 ASSERT_EQ(0, motionArgs.buttonState);
4011 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004012 ASSERT_NO_FATAL_FAILURE(
4013 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004014
4015 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004016 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004017 ASSERT_EQ(0, motionArgs.buttonState);
4018 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004019 ASSERT_NO_FATAL_FAILURE(
4020 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004021
4022 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004023 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004024 ASSERT_EQ(0, motionArgs.buttonState);
4025 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004026 ASSERT_NO_FATAL_FAILURE(
4027 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004028
4029 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004030 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_RIGHT, 1);
4031 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 1);
4032 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004033 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4034 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4035 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4036 motionArgs.buttonState);
4037 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4038 mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004039 ASSERT_NO_FATAL_FAILURE(
4040 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004041
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004042 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4043 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4044 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4045 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4046 mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004047 ASSERT_NO_FATAL_FAILURE(
4048 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004049
4050 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4051 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4052 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4053 motionArgs.buttonState);
4054 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4055 mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004056 ASSERT_NO_FATAL_FAILURE(
4057 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004058
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004059 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_RIGHT, 0);
4060 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004061 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004062 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004063 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4064 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004065 ASSERT_NO_FATAL_FAILURE(
4066 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004067
4068 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004069 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004070 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4071 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004072 ASSERT_NO_FATAL_FAILURE(
4073 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004074
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004075 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
4076 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004077 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004078 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4079 ASSERT_EQ(0, motionArgs.buttonState);
4080 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004081 ASSERT_NO_FATAL_FAILURE(
4082 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004083 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
4084 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004085
4086 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004087 ASSERT_EQ(0, motionArgs.buttonState);
4088 ASSERT_EQ(0, mFakePointerController->getButtonState());
4089 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004090 ASSERT_NO_FATAL_FAILURE(
4091 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004092
Michael Wrightd02c5b62014-02-10 15:10:22 -08004093 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4094 ASSERT_EQ(0, motionArgs.buttonState);
4095 ASSERT_EQ(0, mFakePointerController->getButtonState());
4096 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004097 ASSERT_NO_FATAL_FAILURE(
4098 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004099
4100 // press BTN_BACK, release BTN_BACK
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004101 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_BACK, 1);
4102 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004103 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4104 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4105 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004106
Michael Wrightd02c5b62014-02-10 15:10:22 -08004107 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004108 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004109 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4110 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004111 ASSERT_NO_FATAL_FAILURE(
4112 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004113
4114 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4115 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4116 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4117 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004118 ASSERT_NO_FATAL_FAILURE(
4119 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004120
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004121 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_BACK, 0);
4122 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004123 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004124 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004125 ASSERT_EQ(0, motionArgs.buttonState);
4126 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004127 ASSERT_NO_FATAL_FAILURE(
4128 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004129
4130 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004131 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004132 ASSERT_EQ(0, motionArgs.buttonState);
4133 ASSERT_EQ(0, mFakePointerController->getButtonState());
4134
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004135 ASSERT_NO_FATAL_FAILURE(
4136 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004137 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4138 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4139 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4140
4141 // press BTN_SIDE, release BTN_SIDE
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004142 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_SIDE, 1);
4143 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004144 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4145 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4146 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004147
Michael Wrightd02c5b62014-02-10 15:10:22 -08004148 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004149 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004150 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4151 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004152 ASSERT_NO_FATAL_FAILURE(
4153 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004154
4155 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4156 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4157 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4158 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004159 ASSERT_NO_FATAL_FAILURE(
4160 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004161
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004162 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_SIDE, 0);
4163 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004164 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004165 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004166 ASSERT_EQ(0, motionArgs.buttonState);
4167 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004168 ASSERT_NO_FATAL_FAILURE(
4169 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004170
4171 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4172 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4173 ASSERT_EQ(0, motionArgs.buttonState);
4174 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004175 ASSERT_NO_FATAL_FAILURE(
4176 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004177
Michael Wrightd02c5b62014-02-10 15:10:22 -08004178 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4179 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4180 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4181
4182 // press BTN_FORWARD, release BTN_FORWARD
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004183 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_FORWARD, 1);
4184 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004185 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4186 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4187 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004188
Michael Wrightd02c5b62014-02-10 15:10:22 -08004189 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004190 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004191 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4192 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004193 ASSERT_NO_FATAL_FAILURE(
4194 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004195
4196 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4197 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4198 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4199 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004200 ASSERT_NO_FATAL_FAILURE(
4201 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004202
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004203 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_FORWARD, 0);
4204 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004205 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004206 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004207 ASSERT_EQ(0, motionArgs.buttonState);
4208 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004209 ASSERT_NO_FATAL_FAILURE(
4210 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004211
4212 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4213 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4214 ASSERT_EQ(0, motionArgs.buttonState);
4215 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004216 ASSERT_NO_FATAL_FAILURE(
4217 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004218
Michael Wrightd02c5b62014-02-10 15:10:22 -08004219 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4220 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4221 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4222
4223 // press BTN_EXTRA, release BTN_EXTRA
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004224 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_EXTRA, 1);
4225 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004226 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4227 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4228 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004229
Michael Wrightd02c5b62014-02-10 15:10:22 -08004230 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004231 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004232 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4233 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004234 ASSERT_NO_FATAL_FAILURE(
4235 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004236
4237 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4238 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4239 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4240 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004241 ASSERT_NO_FATAL_FAILURE(
4242 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004243
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004244 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_EXTRA, 0);
4245 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004246 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004247 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004248 ASSERT_EQ(0, motionArgs.buttonState);
4249 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004250 ASSERT_NO_FATAL_FAILURE(
4251 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004252
4253 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4254 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4255 ASSERT_EQ(0, motionArgs.buttonState);
4256 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004257 ASSERT_NO_FATAL_FAILURE(
4258 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004259
Michael Wrightd02c5b62014-02-10 15:10:22 -08004260 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4261 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4262 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4263}
4264
4265TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerAround) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004266 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004267 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004268
4269 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
4270 mFakePointerController->setPosition(100, 200);
4271 mFakePointerController->setButtonState(0);
4272
4273 NotifyMotionArgs args;
4274
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004275 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4276 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4277 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004278 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004279 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4280 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4281 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4282 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 +01004283 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004284}
4285
4286TEST_F(CursorInputMapperTest, Process_PointerCapture) {
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004287 addConfigurationProperty("cursor.mode", "pointer");
4288 mFakePolicy->setPointerCapture(true);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004289 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004290
4291 NotifyDeviceResetArgs resetArgs;
4292 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
4293 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
4294 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4295
4296 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
4297 mFakePointerController->setPosition(100, 200);
4298 mFakePointerController->setButtonState(0);
4299
4300 NotifyMotionArgs args;
4301
4302 // Move.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004303 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4304 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4305 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004306 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4307 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4308 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4309 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4310 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 +01004311 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 100.0f, 200.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004312
4313 // Button press.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004314 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4315 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004316 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4317 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4318 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
4319 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4320 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4321 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4322 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4323 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
4324 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4325 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4326
4327 // Button release.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004328 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4329 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004330 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4331 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4332 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
4333 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4334 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4335 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4336 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4337 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
4338 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4339 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4340
4341 // Another move.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004342 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 30);
4343 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 40);
4344 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004345 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4346 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4347 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4348 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4349 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 +01004350 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 100.0f, 200.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004351
4352 // Disable pointer capture and check that the device generation got bumped
4353 // and events are generated the usual way.
arthurhungdcef2dc2020-08-11 14:47:50 +08004354 const uint32_t generation = mReader->getContext()->getGeneration();
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004355 mFakePolicy->setPointerCapture(false);
4356 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
arthurhungdcef2dc2020-08-11 14:47:50 +08004357 ASSERT_TRUE(mReader->getContext()->getGeneration() != generation);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004358
4359 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004360 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4361
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004362 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4363 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4364 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004365 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4366 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004367 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4368 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4369 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 +01004370 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004371}
4372
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00004373/**
4374 * When Pointer Capture is enabled, we expect to report unprocessed relative movements, so any
4375 * pointer acceleration or speed processing should not be applied.
4376 */
4377TEST_F(CursorInputMapperTest, PointerCaptureDisablesVelocityProcessing) {
4378 addConfigurationProperty("cursor.mode", "pointer");
4379 const VelocityControlParameters testParams(5.f /*scale*/, 0.f /*low threshold*/,
4380 100.f /*high threshold*/, 10.f /*acceleration*/);
4381 mFakePolicy->setVelocityControlParams(testParams);
4382 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4383
4384 NotifyDeviceResetArgs resetArgs;
4385 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
4386 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
4387 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4388
4389 NotifyMotionArgs args;
4390
4391 // Move and verify scale is applied.
4392 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4393 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4394 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4395 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4396 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4397 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4398 const float relX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
4399 const float relY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
4400 ASSERT_GT(relX, 10);
4401 ASSERT_GT(relY, 20);
4402
4403 // Enable Pointer Capture
4404 mFakePolicy->setPointerCapture(true);
4405 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
4406 NotifyPointerCaptureChangedArgs captureArgs;
4407 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
4408 ASSERT_TRUE(captureArgs.request.enable);
4409
4410 // Move and verify scale is not applied.
4411 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4412 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4413 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4414 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4415 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4416 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4417 ASSERT_EQ(10, args.pointerCoords[0].getX());
4418 ASSERT_EQ(20, args.pointerCoords[0].getY());
4419}
4420
Prabir Pradhan208360b2022-06-24 18:37:04 +00004421TEST_F(CursorInputMapperTest, PointerCaptureDisablesOrientationChanges) {
4422 addConfigurationProperty("cursor.mode", "pointer");
4423 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4424
4425 NotifyDeviceResetArgs resetArgs;
4426 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
4427 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
4428 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4429
4430 // Ensure the display is rotated.
4431 prepareDisplay(DISPLAY_ORIENTATION_90);
4432
4433 NotifyMotionArgs args;
4434
4435 // Verify that the coordinates are rotated.
4436 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4437 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4438 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4439 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4440 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4441 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4442 ASSERT_EQ(-20, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X));
4443 ASSERT_EQ(10, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
4444
4445 // Enable Pointer Capture.
4446 mFakePolicy->setPointerCapture(true);
4447 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
4448 NotifyPointerCaptureChangedArgs captureArgs;
4449 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
4450 ASSERT_TRUE(captureArgs.request.enable);
4451
4452 // Move and verify rotation is not applied.
4453 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4454 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4455 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4456 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4457 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4458 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4459 ASSERT_EQ(10, args.pointerCoords[0].getX());
4460 ASSERT_EQ(20, args.pointerCoords[0].getY());
4461}
4462
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004463TEST_F(CursorInputMapperTest, ConfigureDisplayId_NoAssociatedViewport) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004464 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004465
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004466 // Set up the default display.
4467 prepareDisplay(DISPLAY_ORIENTATION_90);
4468
4469 // Set up the secondary display as the display on which the pointer should be shown.
4470 // The InputDevice is not associated with any display.
4471 prepareSecondaryDisplay();
4472 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
Garfield Tan888a6a42020-01-09 11:39:16 -08004473 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
4474
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004475 mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004476 mFakePointerController->setPosition(100, 200);
4477 mFakePointerController->setButtonState(0);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004478
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004479 // Ensure input events are generated for the secondary display.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004480 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4481 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4482 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004483 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan739dca42022-09-09 20:12:01 +00004484 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4485 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(SECONDARY_DISPLAY_ID),
4486 WithCoords(110.0f, 220.0f))));
Michael Wright17db18e2020-06-26 20:51:44 +01004487 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004488}
4489
4490TEST_F(CursorInputMapperTest, ConfigureDisplayId_WithAssociatedViewport) {
4491 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4492
4493 // Set up the default display.
4494 prepareDisplay(DISPLAY_ORIENTATION_90);
4495
4496 // Set up the secondary display as the display on which the pointer should be shown,
4497 // and associate the InputDevice with the secondary display.
4498 prepareSecondaryDisplay();
4499 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
4500 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, SECONDARY_DISPLAY_UNIQUE_ID);
4501 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
4502
4503 mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
4504 mFakePointerController->setPosition(100, 200);
4505 mFakePointerController->setButtonState(0);
4506
4507 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4508 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4509 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4510 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan739dca42022-09-09 20:12:01 +00004511 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4512 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(SECONDARY_DISPLAY_ID),
4513 WithCoords(110.0f, 220.0f))));
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004514 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
4515}
4516
4517TEST_F(CursorInputMapperTest, ConfigureDisplayId_IgnoresEventsForMismatchedPointerDisplay) {
4518 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4519
4520 // Set up the default display as the display on which the pointer should be shown.
4521 prepareDisplay(DISPLAY_ORIENTATION_90);
4522 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
4523
4524 // Associate the InputDevice with the secondary display.
4525 prepareSecondaryDisplay();
4526 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, SECONDARY_DISPLAY_UNIQUE_ID);
4527 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
4528
4529 // The mapper should not generate any events because it is associated with a display that is
4530 // different from the pointer display.
4531 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4532 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4533 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4534 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004535}
4536
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00004537// --- BluetoothCursorInputMapperTest ---
4538
4539class BluetoothCursorInputMapperTest : public CursorInputMapperTest {
4540protected:
4541 void SetUp() override {
4542 InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL, BUS_BLUETOOTH);
4543
4544 mFakePointerController = std::make_shared<FakePointerController>();
4545 mFakePolicy->setPointerController(mFakePointerController);
4546 }
4547};
4548
4549TEST_F(BluetoothCursorInputMapperTest, TimestampSmoothening) {
4550 addConfigurationProperty("cursor.mode", "pointer");
4551 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4552
4553 nsecs_t kernelEventTime = ARBITRARY_TIME;
4554 nsecs_t expectedEventTime = ARBITRARY_TIME;
4555 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
4556 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
4557 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4558 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4559 WithEventTime(expectedEventTime))));
4560
4561 // Process several events that come in quick succession, according to their timestamps.
4562 for (int i = 0; i < 3; i++) {
4563 constexpr static nsecs_t delta = ms2ns(1);
4564 static_assert(delta < MIN_BLUETOOTH_TIMESTAMP_DELTA);
4565 kernelEventTime += delta;
4566 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
4567
4568 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
4569 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
4570 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4571 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4572 WithEventTime(expectedEventTime))));
4573 }
4574}
4575
4576TEST_F(BluetoothCursorInputMapperTest, TimestampSmootheningIsCapped) {
4577 addConfigurationProperty("cursor.mode", "pointer");
4578 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4579
4580 nsecs_t expectedEventTime = ARBITRARY_TIME;
4581 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4582 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4583 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4584 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4585 WithEventTime(expectedEventTime))));
4586
4587 // Process several events with the same timestamp from the kernel.
4588 // Ensure that we do not generate events too far into the future.
4589 constexpr static int32_t numEvents =
4590 MAX_BLUETOOTH_SMOOTHING_DELTA / MIN_BLUETOOTH_TIMESTAMP_DELTA;
4591 for (int i = 0; i < numEvents; i++) {
4592 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
4593
4594 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4595 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4596 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4597 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4598 WithEventTime(expectedEventTime))));
4599 }
4600
4601 // By processing more events with the same timestamp, we should not generate events with a
4602 // timestamp that is more than the specified max time delta from the timestamp at its injection.
4603 const nsecs_t cappedEventTime = ARBITRARY_TIME + MAX_BLUETOOTH_SMOOTHING_DELTA;
4604 for (int i = 0; i < 3; i++) {
4605 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4606 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4607 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4608 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4609 WithEventTime(cappedEventTime))));
4610 }
4611}
4612
4613TEST_F(BluetoothCursorInputMapperTest, TimestampSmootheningNotUsed) {
4614 addConfigurationProperty("cursor.mode", "pointer");
4615 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4616
4617 nsecs_t kernelEventTime = ARBITRARY_TIME;
4618 nsecs_t expectedEventTime = ARBITRARY_TIME;
4619 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
4620 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
4621 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4622 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4623 WithEventTime(expectedEventTime))));
4624
4625 // If the next event has a timestamp that is sufficiently spaced out so that Bluetooth timestamp
4626 // smoothening is not needed, its timestamp is not affected.
4627 kernelEventTime += MAX_BLUETOOTH_SMOOTHING_DELTA + ms2ns(1);
4628 expectedEventTime = kernelEventTime;
4629
4630 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
4631 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
4632 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4633 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4634 WithEventTime(expectedEventTime))));
4635}
4636
Michael Wrightd02c5b62014-02-10 15:10:22 -08004637// --- TouchInputMapperTest ---
4638
4639class TouchInputMapperTest : public InputMapperTest {
4640protected:
4641 static const int32_t RAW_X_MIN;
4642 static const int32_t RAW_X_MAX;
4643 static const int32_t RAW_Y_MIN;
4644 static const int32_t RAW_Y_MAX;
4645 static const int32_t RAW_TOUCH_MIN;
4646 static const int32_t RAW_TOUCH_MAX;
4647 static const int32_t RAW_TOOL_MIN;
4648 static const int32_t RAW_TOOL_MAX;
4649 static const int32_t RAW_PRESSURE_MIN;
4650 static const int32_t RAW_PRESSURE_MAX;
4651 static const int32_t RAW_ORIENTATION_MIN;
4652 static const int32_t RAW_ORIENTATION_MAX;
4653 static const int32_t RAW_DISTANCE_MIN;
4654 static const int32_t RAW_DISTANCE_MAX;
4655 static const int32_t RAW_TILT_MIN;
4656 static const int32_t RAW_TILT_MAX;
4657 static const int32_t RAW_ID_MIN;
4658 static const int32_t RAW_ID_MAX;
4659 static const int32_t RAW_SLOT_MIN;
4660 static const int32_t RAW_SLOT_MAX;
4661 static const float X_PRECISION;
4662 static const float Y_PRECISION;
Santos Cordonfa5cf462017-04-05 10:37:00 -07004663 static const float X_PRECISION_VIRTUAL;
4664 static const float Y_PRECISION_VIRTUAL;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004665
4666 static const float GEOMETRIC_SCALE;
Jason Gerecke489fda82012-09-07 17:19:40 -07004667 static const TouchAffineTransformation AFFINE_TRANSFORM;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004668
4669 static const VirtualKeyDefinition VIRTUAL_KEYS[2];
4670
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07004671 const std::string UNIQUE_ID = "local:0";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004672 const std::string SECONDARY_UNIQUE_ID = "local:1";
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07004673
Michael Wrightd02c5b62014-02-10 15:10:22 -08004674 enum Axes {
4675 POSITION = 1 << 0,
4676 TOUCH = 1 << 1,
4677 TOOL = 1 << 2,
4678 PRESSURE = 1 << 3,
4679 ORIENTATION = 1 << 4,
4680 MINOR = 1 << 5,
4681 ID = 1 << 6,
4682 DISTANCE = 1 << 7,
4683 TILT = 1 << 8,
4684 SLOT = 1 << 9,
4685 TOOL_TYPE = 1 << 10,
4686 };
4687
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004688 void prepareDisplay(int32_t orientation, std::optional<uint8_t> port = NO_PORT);
4689 void prepareSecondaryDisplay(ViewportType type, std::optional<uint8_t> port = NO_PORT);
Santos Cordonfa5cf462017-04-05 10:37:00 -07004690 void prepareVirtualDisplay(int32_t orientation);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004691 void prepareVirtualKeys();
Jason Gerecke489fda82012-09-07 17:19:40 -07004692 void prepareLocationCalibration();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004693 int32_t toRawX(float displayX);
4694 int32_t toRawY(float displayY);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07004695 int32_t toRotatedRawX(float displayX);
4696 int32_t toRotatedRawY(float displayY);
Jason Gerecke489fda82012-09-07 17:19:40 -07004697 float toCookedX(float rawX, float rawY);
4698 float toCookedY(float rawX, float rawY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004699 float toDisplayX(int32_t rawX);
Santos Cordonfa5cf462017-04-05 10:37:00 -07004700 float toDisplayX(int32_t rawX, int32_t displayWidth);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004701 float toDisplayY(int32_t rawY);
Santos Cordonfa5cf462017-04-05 10:37:00 -07004702 float toDisplayY(int32_t rawY, int32_t displayHeight);
4703
Michael Wrightd02c5b62014-02-10 15:10:22 -08004704};
4705
4706const int32_t TouchInputMapperTest::RAW_X_MIN = 25;
4707const int32_t TouchInputMapperTest::RAW_X_MAX = 1019;
4708const int32_t TouchInputMapperTest::RAW_Y_MIN = 30;
4709const int32_t TouchInputMapperTest::RAW_Y_MAX = 1009;
4710const int32_t TouchInputMapperTest::RAW_TOUCH_MIN = 0;
4711const int32_t TouchInputMapperTest::RAW_TOUCH_MAX = 31;
4712const int32_t TouchInputMapperTest::RAW_TOOL_MIN = 0;
4713const int32_t TouchInputMapperTest::RAW_TOOL_MAX = 15;
Michael Wrightaa449c92017-12-13 21:21:43 +00004714const int32_t TouchInputMapperTest::RAW_PRESSURE_MIN = 0;
4715const int32_t TouchInputMapperTest::RAW_PRESSURE_MAX = 255;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004716const int32_t TouchInputMapperTest::RAW_ORIENTATION_MIN = -7;
4717const int32_t TouchInputMapperTest::RAW_ORIENTATION_MAX = 7;
4718const int32_t TouchInputMapperTest::RAW_DISTANCE_MIN = 0;
4719const int32_t TouchInputMapperTest::RAW_DISTANCE_MAX = 7;
4720const int32_t TouchInputMapperTest::RAW_TILT_MIN = 0;
4721const int32_t TouchInputMapperTest::RAW_TILT_MAX = 150;
4722const int32_t TouchInputMapperTest::RAW_ID_MIN = 0;
4723const int32_t TouchInputMapperTest::RAW_ID_MAX = 9;
4724const int32_t TouchInputMapperTest::RAW_SLOT_MIN = 0;
4725const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9;
4726const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH;
4727const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT;
Santos Cordonfa5cf462017-04-05 10:37:00 -07004728const float TouchInputMapperTest::X_PRECISION_VIRTUAL =
4729 float(RAW_X_MAX - RAW_X_MIN + 1) / VIRTUAL_DISPLAY_WIDTH;
4730const float TouchInputMapperTest::Y_PRECISION_VIRTUAL =
4731 float(RAW_Y_MAX - RAW_Y_MIN + 1) / VIRTUAL_DISPLAY_HEIGHT;
Jason Gerecke489fda82012-09-07 17:19:40 -07004732const TouchAffineTransformation TouchInputMapperTest::AFFINE_TRANSFORM =
4733 TouchAffineTransformation(1, -2, 3, -4, 5, -6);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004734
4735const float TouchInputMapperTest::GEOMETRIC_SCALE =
4736 avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN + 1),
4737 float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN + 1));
4738
4739const VirtualKeyDefinition TouchInputMapperTest::VIRTUAL_KEYS[2] = {
4740 { KEY_HOME, 60, DISPLAY_HEIGHT + 15, 20, 20 },
4741 { KEY_MENU, DISPLAY_HEIGHT - 60, DISPLAY_WIDTH + 15, 20, 20 },
4742};
4743
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004744void TouchInputMapperTest::prepareDisplay(int32_t orientation, std::optional<uint8_t> port) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01004745 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation, UNIQUE_ID,
4746 port, ViewportType::INTERNAL);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004747}
4748
4749void TouchInputMapperTest::prepareSecondaryDisplay(ViewportType type, std::optional<uint8_t> port) {
4750 setDisplayInfoAndReconfigure(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
4751 DISPLAY_ORIENTATION_0, SECONDARY_UNIQUE_ID, port, type);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004752}
4753
Santos Cordonfa5cf462017-04-05 10:37:00 -07004754void TouchInputMapperTest::prepareVirtualDisplay(int32_t orientation) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01004755 setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH, VIRTUAL_DISPLAY_HEIGHT,
4756 orientation, VIRTUAL_DISPLAY_UNIQUE_ID, NO_PORT,
4757 ViewportType::VIRTUAL);
Santos Cordonfa5cf462017-04-05 10:37:00 -07004758}
4759
Michael Wrightd02c5b62014-02-10 15:10:22 -08004760void TouchInputMapperTest::prepareVirtualKeys() {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004761 mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[0]);
4762 mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[1]);
4763 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
4764 mFakeEventHub->addKey(EVENTHUB_ID, KEY_MENU, 0, AKEYCODE_MENU, POLICY_FLAG_WAKE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004765}
4766
Jason Gerecke489fda82012-09-07 17:19:40 -07004767void TouchInputMapperTest::prepareLocationCalibration() {
4768 mFakePolicy->setTouchAffineTransformation(AFFINE_TRANSFORM);
4769}
4770
Michael Wrightd02c5b62014-02-10 15:10:22 -08004771int32_t TouchInputMapperTest::toRawX(float displayX) {
4772 return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH + RAW_X_MIN);
4773}
4774
4775int32_t TouchInputMapperTest::toRawY(float displayY) {
4776 return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT + RAW_Y_MIN);
4777}
4778
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07004779int32_t TouchInputMapperTest::toRotatedRawX(float displayX) {
4780 return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_HEIGHT + RAW_X_MIN);
4781}
4782
4783int32_t TouchInputMapperTest::toRotatedRawY(float displayY) {
4784 return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_WIDTH + RAW_Y_MIN);
4785}
4786
Jason Gerecke489fda82012-09-07 17:19:40 -07004787float TouchInputMapperTest::toCookedX(float rawX, float rawY) {
4788 AFFINE_TRANSFORM.applyTo(rawX, rawY);
4789 return rawX;
4790}
4791
4792float TouchInputMapperTest::toCookedY(float rawX, float rawY) {
4793 AFFINE_TRANSFORM.applyTo(rawX, rawY);
4794 return rawY;
4795}
4796
Michael Wrightd02c5b62014-02-10 15:10:22 -08004797float TouchInputMapperTest::toDisplayX(int32_t rawX) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07004798 return toDisplayX(rawX, DISPLAY_WIDTH);
4799}
4800
4801float TouchInputMapperTest::toDisplayX(int32_t rawX, int32_t displayWidth) {
4802 return float(rawX - RAW_X_MIN) * displayWidth / (RAW_X_MAX - RAW_X_MIN + 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004803}
4804
4805float TouchInputMapperTest::toDisplayY(int32_t rawY) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07004806 return toDisplayY(rawY, DISPLAY_HEIGHT);
4807}
4808
4809float TouchInputMapperTest::toDisplayY(int32_t rawY, int32_t displayHeight) {
4810 return float(rawY - RAW_Y_MIN) * displayHeight / (RAW_Y_MAX - RAW_Y_MIN + 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004811}
4812
4813
4814// --- SingleTouchInputMapperTest ---
4815
4816class SingleTouchInputMapperTest : public TouchInputMapperTest {
4817protected:
4818 void prepareButtons();
4819 void prepareAxes(int axes);
4820
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004821 void processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
4822 void processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
4823 void processUp(SingleTouchInputMapper& mappery);
4824 void processPressure(SingleTouchInputMapper& mapper, int32_t pressure);
4825 void processToolMajor(SingleTouchInputMapper& mapper, int32_t toolMajor);
4826 void processDistance(SingleTouchInputMapper& mapper, int32_t distance);
4827 void processTilt(SingleTouchInputMapper& mapper, int32_t tiltX, int32_t tiltY);
4828 void processKey(SingleTouchInputMapper& mapper, int32_t code, int32_t value);
4829 void processSync(SingleTouchInputMapper& mapper);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004830};
4831
4832void SingleTouchInputMapperTest::prepareButtons() {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004833 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004834}
4835
4836void SingleTouchInputMapperTest::prepareAxes(int axes) {
4837 if (axes & POSITION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004838 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
4839 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004840 }
4841 if (axes & PRESSURE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004842 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MIN,
4843 RAW_PRESSURE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004844 }
4845 if (axes & TOOL) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004846 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TOOL_WIDTH, RAW_TOOL_MIN, RAW_TOOL_MAX, 0,
4847 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004848 }
4849 if (axes & DISTANCE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004850 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_DISTANCE, RAW_DISTANCE_MIN,
4851 RAW_DISTANCE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004852 }
4853 if (axes & TILT) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004854 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_X, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
4855 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_Y, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004856 }
4857}
4858
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004859void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004860 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
4861 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
4862 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004863}
4864
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004865void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004866 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
4867 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004868}
4869
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004870void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004871 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004872}
4873
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004874void SingleTouchInputMapperTest::processPressure(SingleTouchInputMapper& mapper, int32_t pressure) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004875 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_PRESSURE, pressure);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004876}
4877
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004878void SingleTouchInputMapperTest::processToolMajor(SingleTouchInputMapper& mapper,
4879 int32_t toolMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004880 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TOOL_WIDTH, toolMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004881}
4882
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004883void SingleTouchInputMapperTest::processDistance(SingleTouchInputMapper& mapper, int32_t distance) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004884 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_DISTANCE, distance);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004885}
4886
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004887void SingleTouchInputMapperTest::processTilt(SingleTouchInputMapper& mapper, int32_t tiltX,
4888 int32_t tiltY) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004889 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_X, tiltX);
4890 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_Y, tiltY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004891}
4892
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004893void SingleTouchInputMapperTest::processKey(SingleTouchInputMapper& mapper, int32_t code,
4894 int32_t value) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004895 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004896}
4897
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004898void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004899 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004900}
4901
Michael Wrightd02c5b62014-02-10 15:10:22 -08004902TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndNotACursor_ReturnsPointer) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004903 prepareButtons();
4904 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004905 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004906
Harry Cutts16a24cc2022-10-26 15:22:19 +00004907 ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004908}
4909
Michael Wrightd02c5b62014-02-10 15:10:22 -08004910TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004911 prepareButtons();
4912 prepareAxes(POSITION);
4913 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004914 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004915
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004916 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004917}
4918
4919TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004920 addConfigurationProperty("touch.deviceType", "touchScreen");
4921 prepareDisplay(DISPLAY_ORIENTATION_0);
4922 prepareButtons();
4923 prepareAxes(POSITION);
4924 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004925 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004926
4927 // Unknown key.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004928 ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004929
4930 // Virtual key is down.
4931 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
4932 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
4933 processDown(mapper, x, y);
4934 processSync(mapper);
4935 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
4936
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004937 ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004938
4939 // Virtual key is up.
4940 processUp(mapper);
4941 processSync(mapper);
4942 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
4943
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004944 ASSERT_EQ(AKEY_STATE_UP, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004945}
4946
4947TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004948 addConfigurationProperty("touch.deviceType", "touchScreen");
4949 prepareDisplay(DISPLAY_ORIENTATION_0);
4950 prepareButtons();
4951 prepareAxes(POSITION);
4952 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004953 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004954
4955 // Unknown key.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004956 ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004957
4958 // Virtual key is down.
4959 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
4960 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
4961 processDown(mapper, x, y);
4962 processSync(mapper);
4963 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
4964
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004965 ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004966
4967 // Virtual key is up.
4968 processUp(mapper);
4969 processSync(mapper);
4970 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
4971
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004972 ASSERT_EQ(AKEY_STATE_UP, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004973}
4974
4975TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004976 addConfigurationProperty("touch.deviceType", "touchScreen");
4977 prepareDisplay(DISPLAY_ORIENTATION_0);
4978 prepareButtons();
4979 prepareAxes(POSITION);
4980 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004981 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004982
Michael Wrightd02c5b62014-02-10 15:10:22 -08004983 uint8_t flags[2] = { 0, 0 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07004984 ASSERT_TRUE(
4985 mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, {AKEYCODE_HOME, AKEYCODE_A}, flags));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004986 ASSERT_TRUE(flags[0]);
4987 ASSERT_FALSE(flags[1]);
4988}
4989
4990TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004991 addConfigurationProperty("touch.deviceType", "touchScreen");
4992 prepareDisplay(DISPLAY_ORIENTATION_0);
4993 prepareButtons();
4994 prepareAxes(POSITION);
4995 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004996 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004997
arthurhungdcef2dc2020-08-11 14:47:50 +08004998 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004999
5000 NotifyKeyArgs args;
5001
5002 // Press virtual key.
5003 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5004 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5005 processDown(mapper, x, y);
5006 processSync(mapper);
5007
5008 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
5009 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
5010 ASSERT_EQ(DEVICE_ID, args.deviceId);
5011 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
5012 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
5013 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
5014 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
5015 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
5016 ASSERT_EQ(KEY_HOME, args.scanCode);
5017 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
5018 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
5019
5020 // Release virtual key.
5021 processUp(mapper);
5022 processSync(mapper);
5023
5024 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
5025 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
5026 ASSERT_EQ(DEVICE_ID, args.deviceId);
5027 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
5028 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
5029 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
5030 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
5031 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
5032 ASSERT_EQ(KEY_HOME, args.scanCode);
5033 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
5034 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
5035
5036 // Should not have sent any motions.
5037 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5038}
5039
5040TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005041 addConfigurationProperty("touch.deviceType", "touchScreen");
5042 prepareDisplay(DISPLAY_ORIENTATION_0);
5043 prepareButtons();
5044 prepareAxes(POSITION);
5045 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005046 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005047
arthurhungdcef2dc2020-08-11 14:47:50 +08005048 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005049
5050 NotifyKeyArgs keyArgs;
5051
5052 // Press virtual key.
5053 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5054 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5055 processDown(mapper, x, y);
5056 processSync(mapper);
5057
5058 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5059 ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
5060 ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
5061 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
5062 ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
5063 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5064 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, keyArgs.flags);
5065 ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
5066 ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
5067 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
5068 ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
5069
5070 // Move out of bounds. This should generate a cancel and a pointer down since we moved
5071 // into the display area.
5072 y -= 100;
5073 processMove(mapper, x, y);
5074 processSync(mapper);
5075
5076 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5077 ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
5078 ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
5079 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
5080 ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
5081 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5082 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
5083 | AKEY_EVENT_FLAG_CANCELED, keyArgs.flags);
5084 ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
5085 ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
5086 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
5087 ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
5088
5089 NotifyMotionArgs motionArgs;
5090 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5091 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5092 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5093 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5094 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5095 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5096 ASSERT_EQ(0, motionArgs.flags);
5097 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5098 ASSERT_EQ(0, motionArgs.buttonState);
5099 ASSERT_EQ(0, motionArgs.edgeFlags);
5100 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5101 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5102 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5103 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5104 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5105 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5106 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5107 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5108
5109 // Keep moving out of bounds. Should generate a pointer move.
5110 y -= 50;
5111 processMove(mapper, x, y);
5112 processSync(mapper);
5113
5114 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5115 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5116 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5117 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5118 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5119 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5120 ASSERT_EQ(0, motionArgs.flags);
5121 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5122 ASSERT_EQ(0, motionArgs.buttonState);
5123 ASSERT_EQ(0, motionArgs.edgeFlags);
5124 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5125 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5126 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5127 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5128 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5129 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5130 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5131 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5132
5133 // Release out of bounds. Should generate a pointer up.
5134 processUp(mapper);
5135 processSync(mapper);
5136
5137 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5138 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5139 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5140 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5141 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5142 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5143 ASSERT_EQ(0, motionArgs.flags);
5144 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5145 ASSERT_EQ(0, motionArgs.buttonState);
5146 ASSERT_EQ(0, motionArgs.edgeFlags);
5147 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5148 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5149 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5150 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5151 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5152 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5153 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5154 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5155
5156 // Should not have sent any more keys or motions.
5157 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5158 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5159}
5160
5161TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005162 addConfigurationProperty("touch.deviceType", "touchScreen");
5163 prepareDisplay(DISPLAY_ORIENTATION_0);
5164 prepareButtons();
5165 prepareAxes(POSITION);
5166 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005167 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005168
arthurhungdcef2dc2020-08-11 14:47:50 +08005169 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005170
5171 NotifyMotionArgs motionArgs;
5172
5173 // Initially go down out of bounds.
5174 int32_t x = -10;
5175 int32_t y = -10;
5176 processDown(mapper, x, y);
5177 processSync(mapper);
5178
5179 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5180
5181 // Move into the display area. Should generate a pointer down.
5182 x = 50;
5183 y = 75;
5184 processMove(mapper, x, y);
5185 processSync(mapper);
5186
5187 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5188 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5189 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5190 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5191 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5192 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5193 ASSERT_EQ(0, motionArgs.flags);
5194 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5195 ASSERT_EQ(0, motionArgs.buttonState);
5196 ASSERT_EQ(0, motionArgs.edgeFlags);
5197 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5198 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5199 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5200 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5201 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5202 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5203 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5204 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5205
5206 // Release. Should generate a pointer up.
5207 processUp(mapper);
5208 processSync(mapper);
5209
5210 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5211 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5212 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5213 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5214 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5215 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5216 ASSERT_EQ(0, motionArgs.flags);
5217 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5218 ASSERT_EQ(0, motionArgs.buttonState);
5219 ASSERT_EQ(0, motionArgs.edgeFlags);
5220 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5221 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5222 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5223 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5224 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5225 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5226 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5227 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5228
5229 // Should not have sent any more keys or motions.
5230 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5231 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5232}
5233
Santos Cordonfa5cf462017-04-05 10:37:00 -07005234TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture_VirtualDisplay) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005235 addConfigurationProperty("touch.deviceType", "touchScreen");
5236 addConfigurationProperty("touch.displayId", VIRTUAL_DISPLAY_UNIQUE_ID);
5237
5238 prepareVirtualDisplay(DISPLAY_ORIENTATION_0);
5239 prepareButtons();
5240 prepareAxes(POSITION);
5241 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005242 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Santos Cordonfa5cf462017-04-05 10:37:00 -07005243
arthurhungdcef2dc2020-08-11 14:47:50 +08005244 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005245
5246 NotifyMotionArgs motionArgs;
5247
5248 // Down.
5249 int32_t x = 100;
5250 int32_t y = 125;
5251 processDown(mapper, x, y);
5252 processSync(mapper);
5253
5254 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5255 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5256 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5257 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
5258 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5259 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5260 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5261 ASSERT_EQ(0, motionArgs.flags);
5262 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5263 ASSERT_EQ(0, motionArgs.buttonState);
5264 ASSERT_EQ(0, motionArgs.edgeFlags);
5265 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5266 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5267 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5268 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5269 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
5270 1, 0, 0, 0, 0, 0, 0, 0));
5271 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
5272 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
5273 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5274
5275 // Move.
5276 x += 50;
5277 y += 75;
5278 processMove(mapper, x, y);
5279 processSync(mapper);
5280
5281 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5282 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5283 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5284 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
5285 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5286 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5287 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5288 ASSERT_EQ(0, motionArgs.flags);
5289 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5290 ASSERT_EQ(0, motionArgs.buttonState);
5291 ASSERT_EQ(0, motionArgs.edgeFlags);
5292 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5293 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5294 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5295 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5296 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
5297 1, 0, 0, 0, 0, 0, 0, 0));
5298 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
5299 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
5300 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5301
5302 // Up.
5303 processUp(mapper);
5304 processSync(mapper);
5305
5306 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5307 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5308 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5309 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
5310 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5311 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5312 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5313 ASSERT_EQ(0, motionArgs.flags);
5314 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5315 ASSERT_EQ(0, motionArgs.buttonState);
5316 ASSERT_EQ(0, motionArgs.edgeFlags);
5317 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5318 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5319 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5320 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5321 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
5322 1, 0, 0, 0, 0, 0, 0, 0));
5323 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
5324 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
5325 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5326
5327 // Should not have sent any more keys or motions.
5328 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5329 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5330}
5331
Michael Wrightd02c5b62014-02-10 15:10:22 -08005332TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005333 addConfigurationProperty("touch.deviceType", "touchScreen");
5334 prepareDisplay(DISPLAY_ORIENTATION_0);
5335 prepareButtons();
5336 prepareAxes(POSITION);
5337 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005338 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005339
arthurhungdcef2dc2020-08-11 14:47:50 +08005340 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005341
5342 NotifyMotionArgs motionArgs;
5343
5344 // Down.
5345 int32_t x = 100;
5346 int32_t y = 125;
5347 processDown(mapper, x, y);
5348 processSync(mapper);
5349
5350 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5351 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5352 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5353 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5354 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5355 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5356 ASSERT_EQ(0, motionArgs.flags);
5357 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5358 ASSERT_EQ(0, motionArgs.buttonState);
5359 ASSERT_EQ(0, motionArgs.edgeFlags);
5360 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5361 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5362 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5363 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5364 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5365 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5366 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5367 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5368
5369 // Move.
5370 x += 50;
5371 y += 75;
5372 processMove(mapper, x, y);
5373 processSync(mapper);
5374
5375 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5376 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5377 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5378 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5379 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5380 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5381 ASSERT_EQ(0, motionArgs.flags);
5382 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5383 ASSERT_EQ(0, motionArgs.buttonState);
5384 ASSERT_EQ(0, motionArgs.edgeFlags);
5385 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5386 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5387 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5388 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5389 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5390 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5391 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5392 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5393
5394 // Up.
5395 processUp(mapper);
5396 processSync(mapper);
5397
5398 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5399 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5400 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5401 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5402 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5403 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5404 ASSERT_EQ(0, motionArgs.flags);
5405 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5406 ASSERT_EQ(0, motionArgs.buttonState);
5407 ASSERT_EQ(0, motionArgs.edgeFlags);
5408 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5409 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5410 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5411 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5412 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5413 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5414 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5415 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5416
5417 // Should not have sent any more keys or motions.
5418 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5419 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5420}
5421
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005422TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_DoesNotRotateMotions) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005423 addConfigurationProperty("touch.deviceType", "touchScreen");
5424 prepareButtons();
5425 prepareAxes(POSITION);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005426 // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
5427 // need to be rotated. Touchscreens are orientation-aware by default.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005428 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005429
5430 NotifyMotionArgs args;
5431
5432 // Rotation 90.
5433 prepareDisplay(DISPLAY_ORIENTATION_90);
5434 processDown(mapper, toRawX(50), toRawY(75));
5435 processSync(mapper);
5436
5437 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5438 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5439 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5440
5441 processUp(mapper);
5442 processSync(mapper);
5443 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5444}
5445
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005446TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_RotatesMotions) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005447 addConfigurationProperty("touch.deviceType", "touchScreen");
5448 prepareButtons();
5449 prepareAxes(POSITION);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005450 // Since InputReader works in the un-rotated coordinate space, only devices that are not
5451 // orientation-aware are affected by display rotation.
5452 addConfigurationProperty("touch.orientationAware", "0");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005453 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005454
5455 NotifyMotionArgs args;
5456
5457 // Rotation 0.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005458 clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005459 prepareDisplay(DISPLAY_ORIENTATION_0);
5460 processDown(mapper, toRawX(50), toRawY(75));
5461 processSync(mapper);
5462
5463 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5464 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5465 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5466
5467 processUp(mapper);
5468 processSync(mapper);
5469 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5470
5471 // Rotation 90.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005472 clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005473 prepareDisplay(DISPLAY_ORIENTATION_90);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005474 processDown(mapper, toRawX(75), RAW_Y_MAX - toRawY(50) + RAW_Y_MIN);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005475 processSync(mapper);
5476
5477 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5478 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5479 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5480
5481 processUp(mapper);
5482 processSync(mapper);
5483 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5484
5485 // Rotation 180.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005486 clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005487 prepareDisplay(DISPLAY_ORIENTATION_180);
5488 processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
5489 processSync(mapper);
5490
5491 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5492 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5493 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5494
5495 processUp(mapper);
5496 processSync(mapper);
5497 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5498
5499 // Rotation 270.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005500 clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005501 prepareDisplay(DISPLAY_ORIENTATION_270);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005502 processDown(mapper, RAW_X_MAX - toRawX(75) + RAW_X_MIN, toRawY(50));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005503 processSync(mapper);
5504
5505 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5506 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5507 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5508
5509 processUp(mapper);
5510 processSync(mapper);
5511 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5512}
5513
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005514TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation0_RotatesMotions) {
5515 addConfigurationProperty("touch.deviceType", "touchScreen");
5516 prepareButtons();
5517 prepareAxes(POSITION);
5518 addConfigurationProperty("touch.orientationAware", "1");
5519 addConfigurationProperty("touch.orientation", "ORIENTATION_0");
5520 clearViewports();
5521 prepareDisplay(DISPLAY_ORIENTATION_0);
5522 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5523 NotifyMotionArgs args;
5524
5525 // Orientation 0.
5526 processDown(mapper, toRawX(50), toRawY(75));
5527 processSync(mapper);
5528
5529 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5530 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5531 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5532
5533 processUp(mapper);
5534 processSync(mapper);
5535 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5536}
5537
5538TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation90_RotatesMotions) {
5539 addConfigurationProperty("touch.deviceType", "touchScreen");
5540 prepareButtons();
5541 prepareAxes(POSITION);
5542 addConfigurationProperty("touch.orientationAware", "1");
5543 addConfigurationProperty("touch.orientation", "ORIENTATION_90");
5544 clearViewports();
5545 prepareDisplay(DISPLAY_ORIENTATION_0);
5546 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5547 NotifyMotionArgs args;
5548
5549 // Orientation 90.
5550 processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
5551 processSync(mapper);
5552
5553 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5554 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5555 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5556
5557 processUp(mapper);
5558 processSync(mapper);
5559 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5560}
5561
5562TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation180_RotatesMotions) {
5563 addConfigurationProperty("touch.deviceType", "touchScreen");
5564 prepareButtons();
5565 prepareAxes(POSITION);
5566 addConfigurationProperty("touch.orientationAware", "1");
5567 addConfigurationProperty("touch.orientation", "ORIENTATION_180");
5568 clearViewports();
5569 prepareDisplay(DISPLAY_ORIENTATION_0);
5570 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5571 NotifyMotionArgs args;
5572
5573 // Orientation 180.
5574 processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
5575 processSync(mapper);
5576
5577 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5578 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5579 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5580
5581 processUp(mapper);
5582 processSync(mapper);
5583 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5584}
5585
5586TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation270_RotatesMotions) {
5587 addConfigurationProperty("touch.deviceType", "touchScreen");
5588 prepareButtons();
5589 prepareAxes(POSITION);
5590 addConfigurationProperty("touch.orientationAware", "1");
5591 addConfigurationProperty("touch.orientation", "ORIENTATION_270");
5592 clearViewports();
5593 prepareDisplay(DISPLAY_ORIENTATION_0);
5594 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5595 NotifyMotionArgs args;
5596
5597 // Orientation 270.
5598 processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
5599 processSync(mapper);
5600
5601 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5602 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5603 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5604
5605 processUp(mapper);
5606 processSync(mapper);
5607 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5608}
5609
5610TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationSpecified_RotatesMotionWithDisplay) {
5611 addConfigurationProperty("touch.deviceType", "touchScreen");
5612 prepareButtons();
5613 prepareAxes(POSITION);
5614 // Since InputReader works in the un-rotated coordinate space, only devices that are not
5615 // orientation-aware are affected by display rotation.
5616 addConfigurationProperty("touch.orientationAware", "0");
5617 addConfigurationProperty("touch.orientation", "ORIENTATION_90");
5618 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5619
5620 NotifyMotionArgs args;
5621
5622 // Orientation 90, Rotation 0.
5623 clearViewports();
5624 prepareDisplay(DISPLAY_ORIENTATION_0);
5625 processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
5626 processSync(mapper);
5627
5628 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5629 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5630 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5631
5632 processUp(mapper);
5633 processSync(mapper);
5634 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5635
5636 // Orientation 90, Rotation 90.
5637 clearViewports();
5638 prepareDisplay(DISPLAY_ORIENTATION_90);
5639 processDown(mapper, toRotatedRawX(50), toRotatedRawY(75));
5640 processSync(mapper);
5641
5642 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5643 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5644 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5645
5646 processUp(mapper);
5647 processSync(mapper);
5648 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5649
5650 // Orientation 90, Rotation 180.
5651 clearViewports();
5652 prepareDisplay(DISPLAY_ORIENTATION_180);
5653 processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
5654 processSync(mapper);
5655
5656 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5657 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5658 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5659
5660 processUp(mapper);
5661 processSync(mapper);
5662 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5663
5664 // Orientation 90, Rotation 270.
5665 clearViewports();
5666 prepareDisplay(DISPLAY_ORIENTATION_270);
5667 processDown(mapper, RAW_X_MAX - toRotatedRawX(50) + RAW_X_MIN,
5668 RAW_Y_MAX - toRotatedRawY(75) + RAW_Y_MIN);
5669 processSync(mapper);
5670
5671 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5672 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5673 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5674
5675 processUp(mapper);
5676 processSync(mapper);
5677 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5678}
5679
Michael Wrightd02c5b62014-02-10 15:10:22 -08005680TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005681 addConfigurationProperty("touch.deviceType", "touchScreen");
5682 prepareDisplay(DISPLAY_ORIENTATION_0);
5683 prepareButtons();
5684 prepareAxes(POSITION | PRESSURE | TOOL | DISTANCE | TILT);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005685 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005686
5687 // These calculations are based on the input device calibration documentation.
5688 int32_t rawX = 100;
5689 int32_t rawY = 200;
5690 int32_t rawPressure = 10;
5691 int32_t rawToolMajor = 12;
5692 int32_t rawDistance = 2;
5693 int32_t rawTiltX = 30;
5694 int32_t rawTiltY = 110;
5695
5696 float x = toDisplayX(rawX);
5697 float y = toDisplayY(rawY);
5698 float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
5699 float size = float(rawToolMajor) / RAW_TOOL_MAX;
5700 float tool = float(rawToolMajor) * GEOMETRIC_SCALE;
5701 float distance = float(rawDistance);
5702
5703 float tiltCenter = (RAW_TILT_MAX + RAW_TILT_MIN) * 0.5f;
5704 float tiltScale = M_PI / 180;
5705 float tiltXAngle = (rawTiltX - tiltCenter) * tiltScale;
5706 float tiltYAngle = (rawTiltY - tiltCenter) * tiltScale;
5707 float orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
5708 float tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
5709
5710 processDown(mapper, rawX, rawY);
5711 processPressure(mapper, rawPressure);
5712 processToolMajor(mapper, rawToolMajor);
5713 processDistance(mapper, rawDistance);
5714 processTilt(mapper, rawTiltX, rawTiltY);
5715 processSync(mapper);
5716
5717 NotifyMotionArgs args;
5718 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5719 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
5720 x, y, pressure, size, tool, tool, tool, tool, orientation, distance));
5721 ASSERT_EQ(tilt, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TILT));
5722}
5723
Jason Gerecke489fda82012-09-07 17:19:40 -07005724TEST_F(SingleTouchInputMapperTest, Process_XYAxes_AffineCalibration) {
Jason Gerecke489fda82012-09-07 17:19:40 -07005725 addConfigurationProperty("touch.deviceType", "touchScreen");
5726 prepareDisplay(DISPLAY_ORIENTATION_0);
5727 prepareLocationCalibration();
5728 prepareButtons();
5729 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005730 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Jason Gerecke489fda82012-09-07 17:19:40 -07005731
5732 int32_t rawX = 100;
5733 int32_t rawY = 200;
5734
5735 float x = toDisplayX(toCookedX(rawX, rawY));
5736 float y = toDisplayY(toCookedY(rawX, rawY));
5737
5738 processDown(mapper, rawX, rawY);
5739 processSync(mapper);
5740
5741 NotifyMotionArgs args;
5742 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5743 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
5744 x, y, 1, 0, 0, 0, 0, 0, 0, 0));
5745}
5746
Michael Wrightd02c5b62014-02-10 15:10:22 -08005747TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005748 addConfigurationProperty("touch.deviceType", "touchScreen");
5749 prepareDisplay(DISPLAY_ORIENTATION_0);
5750 prepareButtons();
5751 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005752 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005753
5754 NotifyMotionArgs motionArgs;
5755 NotifyKeyArgs keyArgs;
5756
5757 processDown(mapper, 100, 200);
5758 processSync(mapper);
5759 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5760 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5761 ASSERT_EQ(0, motionArgs.buttonState);
5762
5763 // press BTN_LEFT, release BTN_LEFT
5764 processKey(mapper, BTN_LEFT, 1);
5765 processSync(mapper);
5766 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5767 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5768 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
5769
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005770 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5771 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5772 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
5773
Michael Wrightd02c5b62014-02-10 15:10:22 -08005774 processKey(mapper, BTN_LEFT, 0);
5775 processSync(mapper);
5776 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005777 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005778 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005779
5780 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005781 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005782 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005783
5784 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
5785 processKey(mapper, BTN_RIGHT, 1);
5786 processKey(mapper, BTN_MIDDLE, 1);
5787 processSync(mapper);
5788 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5789 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5790 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
5791 motionArgs.buttonState);
5792
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005793 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5794 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5795 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
5796
5797 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5798 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5799 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
5800 motionArgs.buttonState);
5801
Michael Wrightd02c5b62014-02-10 15:10:22 -08005802 processKey(mapper, BTN_RIGHT, 0);
5803 processSync(mapper);
5804 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005805 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005806 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005807
5808 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005809 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005810 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005811
5812 processKey(mapper, BTN_MIDDLE, 0);
5813 processSync(mapper);
5814 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005815 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005816 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005817
5818 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005819 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005820 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005821
5822 // press BTN_BACK, release BTN_BACK
5823 processKey(mapper, BTN_BACK, 1);
5824 processSync(mapper);
5825 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5826 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5827 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005828
Michael Wrightd02c5b62014-02-10 15:10:22 -08005829 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005830 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005831 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
5832
5833 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5834 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5835 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005836
5837 processKey(mapper, BTN_BACK, 0);
5838 processSync(mapper);
5839 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005840 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005841 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005842
5843 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005844 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005845 ASSERT_EQ(0, motionArgs.buttonState);
5846
Michael Wrightd02c5b62014-02-10 15:10:22 -08005847 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5848 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5849 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
5850
5851 // press BTN_SIDE, release BTN_SIDE
5852 processKey(mapper, BTN_SIDE, 1);
5853 processSync(mapper);
5854 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5855 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5856 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005857
Michael Wrightd02c5b62014-02-10 15:10:22 -08005858 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005859 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005860 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
5861
5862 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5863 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5864 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005865
5866 processKey(mapper, BTN_SIDE, 0);
5867 processSync(mapper);
5868 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005869 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005870 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005871
5872 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005873 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005874 ASSERT_EQ(0, motionArgs.buttonState);
5875
Michael Wrightd02c5b62014-02-10 15:10:22 -08005876 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5877 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5878 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
5879
5880 // press BTN_FORWARD, release BTN_FORWARD
5881 processKey(mapper, BTN_FORWARD, 1);
5882 processSync(mapper);
5883 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5884 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5885 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005886
Michael Wrightd02c5b62014-02-10 15:10:22 -08005887 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005888 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005889 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
5890
5891 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5892 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5893 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005894
5895 processKey(mapper, BTN_FORWARD, 0);
5896 processSync(mapper);
5897 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005898 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005899 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005900
5901 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005902 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005903 ASSERT_EQ(0, motionArgs.buttonState);
5904
Michael Wrightd02c5b62014-02-10 15:10:22 -08005905 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5906 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5907 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
5908
5909 // press BTN_EXTRA, release BTN_EXTRA
5910 processKey(mapper, BTN_EXTRA, 1);
5911 processSync(mapper);
5912 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5913 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5914 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005915
Michael Wrightd02c5b62014-02-10 15:10:22 -08005916 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005917 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005918 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
5919
5920 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5921 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5922 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005923
5924 processKey(mapper, BTN_EXTRA, 0);
5925 processSync(mapper);
5926 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005927 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005928 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005929
5930 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005931 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005932 ASSERT_EQ(0, motionArgs.buttonState);
5933
Michael Wrightd02c5b62014-02-10 15:10:22 -08005934 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5935 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5936 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
5937
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005938 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5939
Michael Wrightd02c5b62014-02-10 15:10:22 -08005940 // press BTN_STYLUS, release BTN_STYLUS
5941 processKey(mapper, BTN_STYLUS, 1);
5942 processSync(mapper);
5943 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5944 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005945 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
5946
5947 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5948 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5949 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005950
5951 processKey(mapper, BTN_STYLUS, 0);
5952 processSync(mapper);
5953 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005954 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005955 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005956
5957 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005958 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005959 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005960
5961 // press BTN_STYLUS2, release BTN_STYLUS2
5962 processKey(mapper, BTN_STYLUS2, 1);
5963 processSync(mapper);
5964 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5965 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005966 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
5967
5968 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5969 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5970 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005971
5972 processKey(mapper, BTN_STYLUS2, 0);
5973 processSync(mapper);
5974 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005975 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005976 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005977
5978 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005979 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08005980 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005981
5982 // release touch
5983 processUp(mapper);
5984 processSync(mapper);
5985 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5986 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5987 ASSERT_EQ(0, motionArgs.buttonState);
5988}
5989
5990TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005991 addConfigurationProperty("touch.deviceType", "touchScreen");
5992 prepareDisplay(DISPLAY_ORIENTATION_0);
5993 prepareButtons();
5994 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005995 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005996
5997 NotifyMotionArgs motionArgs;
5998
5999 // default tool type is finger
6000 processDown(mapper, 100, 200);
6001 processSync(mapper);
6002 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6003 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6004 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6005
6006 // eraser
6007 processKey(mapper, BTN_TOOL_RUBBER, 1);
6008 processSync(mapper);
6009 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6010 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6011 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
6012
6013 // stylus
6014 processKey(mapper, BTN_TOOL_RUBBER, 0);
6015 processKey(mapper, BTN_TOOL_PEN, 1);
6016 processSync(mapper);
6017 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6018 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6019 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6020
6021 // brush
6022 processKey(mapper, BTN_TOOL_PEN, 0);
6023 processKey(mapper, BTN_TOOL_BRUSH, 1);
6024 processSync(mapper);
6025 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6026 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6027 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6028
6029 // pencil
6030 processKey(mapper, BTN_TOOL_BRUSH, 0);
6031 processKey(mapper, BTN_TOOL_PENCIL, 1);
6032 processSync(mapper);
6033 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6034 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6035 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6036
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08006037 // air-brush
Michael Wrightd02c5b62014-02-10 15:10:22 -08006038 processKey(mapper, BTN_TOOL_PENCIL, 0);
6039 processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
6040 processSync(mapper);
6041 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6042 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6043 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6044
6045 // mouse
6046 processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
6047 processKey(mapper, BTN_TOOL_MOUSE, 1);
6048 processSync(mapper);
6049 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6050 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6051 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
6052
6053 // lens
6054 processKey(mapper, BTN_TOOL_MOUSE, 0);
6055 processKey(mapper, BTN_TOOL_LENS, 1);
6056 processSync(mapper);
6057 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6058 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6059 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
6060
6061 // double-tap
6062 processKey(mapper, BTN_TOOL_LENS, 0);
6063 processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
6064 processSync(mapper);
6065 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6066 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6067 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6068
6069 // triple-tap
6070 processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
6071 processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
6072 processSync(mapper);
6073 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6074 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6075 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6076
6077 // quad-tap
6078 processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
6079 processKey(mapper, BTN_TOOL_QUADTAP, 1);
6080 processSync(mapper);
6081 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6082 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6083 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6084
6085 // finger
6086 processKey(mapper, BTN_TOOL_QUADTAP, 0);
6087 processKey(mapper, BTN_TOOL_FINGER, 1);
6088 processSync(mapper);
6089 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6090 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6091 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6092
6093 // stylus trumps finger
6094 processKey(mapper, BTN_TOOL_PEN, 1);
6095 processSync(mapper);
6096 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6097 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6098 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6099
6100 // eraser trumps stylus
6101 processKey(mapper, BTN_TOOL_RUBBER, 1);
6102 processSync(mapper);
6103 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6104 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6105 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
6106
6107 // mouse trumps eraser
6108 processKey(mapper, BTN_TOOL_MOUSE, 1);
6109 processSync(mapper);
6110 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6111 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6112 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
6113
6114 // back to default tool type
6115 processKey(mapper, BTN_TOOL_MOUSE, 0);
6116 processKey(mapper, BTN_TOOL_RUBBER, 0);
6117 processKey(mapper, BTN_TOOL_PEN, 0);
6118 processKey(mapper, BTN_TOOL_FINGER, 0);
6119 processSync(mapper);
6120 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6121 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6122 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6123}
6124
6125TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006126 addConfigurationProperty("touch.deviceType", "touchScreen");
6127 prepareDisplay(DISPLAY_ORIENTATION_0);
6128 prepareButtons();
6129 prepareAxes(POSITION);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006130 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_FINGER, 0, AKEYCODE_UNKNOWN, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006131 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006132
6133 NotifyMotionArgs motionArgs;
6134
6135 // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
6136 processKey(mapper, BTN_TOOL_FINGER, 1);
6137 processMove(mapper, 100, 200);
6138 processSync(mapper);
6139 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6140 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6141 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6142 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6143
6144 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6145 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6146 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6147 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6148
6149 // move a little
6150 processMove(mapper, 150, 250);
6151 processSync(mapper);
6152 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6153 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6154 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6155 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6156
6157 // down when BTN_TOUCH is pressed, pressure defaults to 1
6158 processKey(mapper, BTN_TOUCH, 1);
6159 processSync(mapper);
6160 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6161 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6162 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6163 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6164
6165 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6166 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6167 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6168 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6169
6170 // up when BTN_TOUCH is released, hover restored
6171 processKey(mapper, BTN_TOUCH, 0);
6172 processSync(mapper);
6173 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6174 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6175 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6176 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6177
6178 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6179 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6180 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6181 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6182
6183 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6184 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6185 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6186 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6187
6188 // exit hover when pointer goes away
6189 processKey(mapper, BTN_TOOL_FINGER, 0);
6190 processSync(mapper);
6191 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6192 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6193 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6194 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6195}
6196
6197TEST_F(SingleTouchInputMapperTest, Process_WhenAbsPressureIsPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006198 addConfigurationProperty("touch.deviceType", "touchScreen");
6199 prepareDisplay(DISPLAY_ORIENTATION_0);
6200 prepareButtons();
6201 prepareAxes(POSITION | PRESSURE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006202 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006203
6204 NotifyMotionArgs motionArgs;
6205
6206 // initially hovering because pressure is 0
6207 processDown(mapper, 100, 200);
6208 processPressure(mapper, 0);
6209 processSync(mapper);
6210 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6211 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6212 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6213 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6214
6215 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6216 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6217 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6218 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6219
6220 // move a little
6221 processMove(mapper, 150, 250);
6222 processSync(mapper);
6223 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6224 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6225 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6226 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6227
6228 // down when pressure is non-zero
6229 processPressure(mapper, RAW_PRESSURE_MAX);
6230 processSync(mapper);
6231 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6232 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6233 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6234 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6235
6236 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6237 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6238 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6239 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6240
6241 // up when pressure becomes 0, hover restored
6242 processPressure(mapper, 0);
6243 processSync(mapper);
6244 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6245 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6246 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6247 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6248
6249 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6250 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6251 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6252 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6253
6254 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6255 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6256 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6257 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6258
6259 // exit hover when pointer goes away
6260 processUp(mapper);
6261 processSync(mapper);
6262 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6263 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6264 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6265 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6266}
6267
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00006268TEST_F(SingleTouchInputMapperTest, Reset_CancelsOngoingGesture) {
6269 addConfigurationProperty("touch.deviceType", "touchScreen");
6270 prepareDisplay(DISPLAY_ORIENTATION_0);
6271 prepareButtons();
6272 prepareAxes(POSITION | PRESSURE);
6273 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6274
6275 // Touch down.
6276 processDown(mapper, 100, 200);
6277 processPressure(mapper, 1);
6278 processSync(mapper);
6279 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6280 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
6281
6282 // Reset the mapper. This should cancel the ongoing gesture.
6283 resetMapper(mapper, ARBITRARY_TIME);
6284 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6285 WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
6286
6287 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6288}
6289
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006290TEST_F(SingleTouchInputMapperTest, Reset_RecreatesTouchState) {
6291 addConfigurationProperty("touch.deviceType", "touchScreen");
6292 prepareDisplay(DISPLAY_ORIENTATION_0);
6293 prepareButtons();
6294 prepareAxes(POSITION | PRESSURE);
6295 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6296
6297 // Set the initial state for the touch pointer.
6298 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_X, 100);
6299 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_Y, 200);
6300 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MAX);
6301 mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1);
6302
6303 // Reset the mapper. When the mapper is reset, we expect it to attempt to recreate the touch
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00006304 // state by reading the current axis values. Since there was no ongoing gesture, calling reset
6305 // does not generate any events.
6306 resetMapper(mapper, ARBITRARY_TIME);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006307
6308 // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
6309 // the recreated touch state to generate a down event.
6310 processSync(mapper);
6311 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6312 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
6313
6314 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6315}
6316
lilinnan687e58f2022-07-19 16:00:50 +08006317TEST_F(SingleTouchInputMapperTest,
6318 Process_WhenViewportDisplayIdChanged_TouchIsCanceledAndDeviceIsReset) {
6319 addConfigurationProperty("touch.deviceType", "touchScreen");
6320 prepareDisplay(DISPLAY_ORIENTATION_0);
6321 prepareButtons();
6322 prepareAxes(POSITION);
6323 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6324 NotifyMotionArgs motionArgs;
6325
6326 // Down.
Prabir Pradhan3e5ec702022-07-29 16:26:24 +00006327 processDown(mapper, 100, 200);
lilinnan687e58f2022-07-19 16:00:50 +08006328 processSync(mapper);
6329
6330 // We should receive a down event
6331 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6332 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6333
6334 // Change display id
6335 clearViewports();
6336 prepareSecondaryDisplay(ViewportType::INTERNAL);
6337
6338 // We should receive a cancel event
6339 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6340 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
6341 // Then receive reset called
6342 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6343}
6344
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006345TEST_F(SingleTouchInputMapperTest,
6346 Process_WhenViewportActiveStatusChanged_TouchIsCanceledAndDeviceIsReset) {
6347 addConfigurationProperty("touch.deviceType", "touchScreen");
6348 prepareDisplay(DISPLAY_ORIENTATION_0);
6349 prepareButtons();
6350 prepareAxes(POSITION);
6351 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6352 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6353 NotifyMotionArgs motionArgs;
6354
6355 // Start a new gesture.
6356 processDown(mapper, 100, 200);
6357 processSync(mapper);
6358 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6359 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6360
6361 // Make the viewport inactive. This will put the device in disabled mode.
6362 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
6363 viewport->isActive = false;
6364 mFakePolicy->updateViewport(*viewport);
6365 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
6366
6367 // We should receive a cancel event for the ongoing gesture.
6368 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6369 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
6370 // Then we should be notified that the device was reset.
6371 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6372
6373 // No events are generated while the viewport is inactive.
6374 processMove(mapper, 101, 201);
6375 processSync(mapper);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006376 processUp(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006377 processSync(mapper);
6378 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6379
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006380 // Start a new gesture while the viewport is still inactive.
6381 processDown(mapper, 300, 400);
6382 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_X, 300);
6383 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_Y, 400);
6384 mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1);
6385 processSync(mapper);
6386
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006387 // Make the viewport active again. The device should resume processing events.
6388 viewport->isActive = true;
6389 mFakePolicy->updateViewport(*viewport);
6390 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
6391
6392 // The device is reset because it changes back to direct mode, without generating any events.
6393 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6394 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6395
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006396 // In the next sync, the touch state that was recreated when the device was reset is reported.
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006397 processSync(mapper);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006398 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6399 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006400
6401 // No more events.
6402 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6403 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
6404}
6405
Prabir Pradhan211ba622022-10-31 21:09:21 +00006406TEST_F(SingleTouchInputMapperTest, ButtonIsReleasedOnTouchUp) {
6407 addConfigurationProperty("touch.deviceType", "touchScreen");
6408 prepareDisplay(DISPLAY_ORIENTATION_0);
6409 prepareButtons();
6410 prepareAxes(POSITION);
6411 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6412 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6413
6414 // Press a stylus button.
6415 processKey(mapper, BTN_STYLUS, 1);
6416 processSync(mapper);
6417
6418 // Start a touch gesture and ensure the BUTTON_PRESS event is generated.
6419 processDown(mapper, 100, 200);
6420 processSync(mapper);
6421 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6422 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
6423 WithCoords(toDisplayX(100), toDisplayY(200)),
6424 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
6425 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6426 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
6427 WithCoords(toDisplayX(100), toDisplayY(200)),
6428 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
6429
6430 // Release the touch gesture. Ensure that the BUTTON_RELEASE event is generated even though
6431 // the button has not actually been released, since there will be no pointers through which the
6432 // button state can be reported. The event is generated at the location of the pointer before
6433 // it went up.
6434 processUp(mapper);
6435 processSync(mapper);
6436 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6437 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
6438 WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
6439 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6440 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
6441 WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
6442}
6443
Prabir Pradhan5632d622021-09-06 07:57:20 -07006444// --- TouchDisplayProjectionTest ---
6445
6446class TouchDisplayProjectionTest : public SingleTouchInputMapperTest {
6447public:
6448 // The values inside DisplayViewport are expected to be pre-rotated. This updates the current
6449 // DisplayViewport to pre-rotate the values. The viewport's physical display will be set to the
6450 // rotated equivalent of the given un-rotated physical display bounds.
6451 void configurePhysicalDisplay(int32_t orientation, Rect naturalPhysicalDisplay) {
6452 uint32_t inverseRotationFlags;
6453 auto width = DISPLAY_WIDTH;
6454 auto height = DISPLAY_HEIGHT;
6455 switch (orientation) {
6456 case DISPLAY_ORIENTATION_90:
6457 inverseRotationFlags = ui::Transform::ROT_270;
6458 std::swap(width, height);
6459 break;
6460 case DISPLAY_ORIENTATION_180:
6461 inverseRotationFlags = ui::Transform::ROT_180;
6462 break;
6463 case DISPLAY_ORIENTATION_270:
6464 inverseRotationFlags = ui::Transform::ROT_90;
6465 std::swap(width, height);
6466 break;
6467 case DISPLAY_ORIENTATION_0:
6468 inverseRotationFlags = ui::Transform::ROT_0;
6469 break;
6470 default:
6471 FAIL() << "Invalid orientation: " << orientation;
6472 }
6473
6474 const ui::Transform rotation(inverseRotationFlags, width, height);
6475 const Rect rotatedPhysicalDisplay = rotation.transform(naturalPhysicalDisplay);
6476
6477 std::optional<DisplayViewport> internalViewport =
6478 *mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
6479 DisplayViewport& v = *internalViewport;
6480 v.displayId = DISPLAY_ID;
6481 v.orientation = orientation;
6482
6483 v.logicalLeft = 0;
6484 v.logicalTop = 0;
6485 v.logicalRight = 100;
6486 v.logicalBottom = 100;
6487
6488 v.physicalLeft = rotatedPhysicalDisplay.left;
6489 v.physicalTop = rotatedPhysicalDisplay.top;
6490 v.physicalRight = rotatedPhysicalDisplay.right;
6491 v.physicalBottom = rotatedPhysicalDisplay.bottom;
6492
6493 v.deviceWidth = width;
6494 v.deviceHeight = height;
6495
6496 v.isActive = true;
6497 v.uniqueId = UNIQUE_ID;
6498 v.type = ViewportType::INTERNAL;
6499 mFakePolicy->updateViewport(v);
6500 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
6501 }
6502
6503 void assertReceivedMove(const Point& point) {
6504 NotifyMotionArgs motionArgs;
6505 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6506 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6507 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6508 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], point.x, point.y,
6509 1, 0, 0, 0, 0, 0, 0, 0));
6510 }
6511};
6512
6513TEST_F(TouchDisplayProjectionTest, IgnoresTouchesOutsidePhysicalDisplay) {
6514 addConfigurationProperty("touch.deviceType", "touchScreen");
6515 prepareDisplay(DISPLAY_ORIENTATION_0);
6516
6517 prepareButtons();
6518 prepareAxes(POSITION);
6519 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6520
6521 NotifyMotionArgs motionArgs;
6522
6523 // Configure the DisplayViewport such that the logical display maps to a subsection of
6524 // the display panel called the physical display. Here, the physical display is bounded by the
6525 // points (10, 20) and (70, 160) inside the display space, which is of the size 400 x 800.
6526 static const Rect kPhysicalDisplay{10, 20, 70, 160};
6527 static const std::array<Point, 6> kPointsOutsidePhysicalDisplay{
6528 {{-10, -10}, {0, 0}, {5, 100}, {50, 15}, {75, 100}, {50, 165}}};
6529
6530 for (auto orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90, DISPLAY_ORIENTATION_180,
6531 DISPLAY_ORIENTATION_270}) {
6532 configurePhysicalDisplay(orientation, kPhysicalDisplay);
6533
6534 // Touches outside the physical display should be ignored, and should not generate any
6535 // events. Ensure touches at the following points that lie outside of the physical display
6536 // area do not generate any events.
6537 for (const auto& point : kPointsOutsidePhysicalDisplay) {
6538 processDown(mapper, toRawX(point.x), toRawY(point.y));
6539 processSync(mapper);
6540 processUp(mapper);
6541 processSync(mapper);
6542 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled())
6543 << "Unexpected event generated for touch outside physical display at point: "
6544 << point.x << ", " << point.y;
6545 }
6546 }
6547}
6548
6549TEST_F(TouchDisplayProjectionTest, EmitsTouchDownAfterEnteringPhysicalDisplay) {
6550 addConfigurationProperty("touch.deviceType", "touchScreen");
6551 prepareDisplay(DISPLAY_ORIENTATION_0);
6552
6553 prepareButtons();
6554 prepareAxes(POSITION);
6555 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6556
6557 NotifyMotionArgs motionArgs;
6558
6559 // Configure the DisplayViewport such that the logical display maps to a subsection of
6560 // the display panel called the physical display. Here, the physical display is bounded by the
6561 // points (10, 20) and (70, 160) inside the display space, which is of the size 400 x 800.
6562 static const Rect kPhysicalDisplay{10, 20, 70, 160};
6563
6564 for (auto orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90, DISPLAY_ORIENTATION_180,
6565 DISPLAY_ORIENTATION_270}) {
6566 configurePhysicalDisplay(orientation, kPhysicalDisplay);
6567
6568 // Touches that start outside the physical display should be ignored until it enters the
6569 // physical display bounds, at which point it should generate a down event. Start a touch at
6570 // the point (5, 100), which is outside the physical display bounds.
6571 static const Point kOutsidePoint{5, 100};
6572 processDown(mapper, toRawX(kOutsidePoint.x), toRawY(kOutsidePoint.y));
6573 processSync(mapper);
6574 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6575
6576 // Move the touch into the physical display area. This should generate a pointer down.
6577 processMove(mapper, toRawX(11), toRawY(21));
6578 processSync(mapper);
6579 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6580 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6581 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6582 ASSERT_NO_FATAL_FAILURE(
6583 assertPointerCoords(motionArgs.pointerCoords[0], 11, 21, 1, 0, 0, 0, 0, 0, 0, 0));
6584
6585 // Move the touch inside the physical display area. This should generate a pointer move.
6586 processMove(mapper, toRawX(69), toRawY(159));
6587 processSync(mapper);
6588 assertReceivedMove({69, 159});
6589
6590 // Move outside the physical display area. Since the pointer is already down, this should
6591 // now continue generating events.
6592 processMove(mapper, toRawX(kOutsidePoint.x), toRawY(kOutsidePoint.y));
6593 processSync(mapper);
6594 assertReceivedMove(kOutsidePoint);
6595
6596 // Release. This should generate a pointer up.
6597 processUp(mapper);
6598 processSync(mapper);
6599 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6600 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6601 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], kOutsidePoint.x,
6602 kOutsidePoint.y, 1, 0, 0, 0, 0, 0, 0, 0));
6603
6604 // Ensure no more events were generated.
6605 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6606 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6607 }
6608}
6609
Michael Wrightd02c5b62014-02-10 15:10:22 -08006610// --- MultiTouchInputMapperTest ---
6611
6612class MultiTouchInputMapperTest : public TouchInputMapperTest {
6613protected:
6614 void prepareAxes(int axes);
6615
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006616 void processPosition(MultiTouchInputMapper& mapper, int32_t x, int32_t y);
6617 void processTouchMajor(MultiTouchInputMapper& mapper, int32_t touchMajor);
6618 void processTouchMinor(MultiTouchInputMapper& mapper, int32_t touchMinor);
6619 void processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor);
6620 void processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor);
6621 void processOrientation(MultiTouchInputMapper& mapper, int32_t orientation);
6622 void processPressure(MultiTouchInputMapper& mapper, int32_t pressure);
6623 void processDistance(MultiTouchInputMapper& mapper, int32_t distance);
6624 void processId(MultiTouchInputMapper& mapper, int32_t id);
6625 void processSlot(MultiTouchInputMapper& mapper, int32_t slot);
6626 void processToolType(MultiTouchInputMapper& mapper, int32_t toolType);
6627 void processKey(MultiTouchInputMapper& mapper, int32_t code, int32_t value);
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00006628 void processHidUsage(MultiTouchInputMapper& mapper, int32_t usageCode, int32_t value);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006629 void processMTSync(MultiTouchInputMapper& mapper);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00006630 void processSync(MultiTouchInputMapper& mapper, nsecs_t eventTime = ARBITRARY_TIME,
6631 nsecs_t readTime = READ_TIME);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006632};
6633
6634void MultiTouchInputMapperTest::prepareAxes(int axes) {
6635 if (axes & POSITION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006636 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
6637 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006638 }
6639 if (axes & TOUCH) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006640 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN,
6641 RAW_TOUCH_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006642 if (axes & MINOR) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006643 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN,
6644 RAW_TOUCH_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006645 }
6646 }
6647 if (axes & TOOL) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006648 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
6649 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006650 if (axes & MINOR) {
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08006651 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006652 RAW_TOOL_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006653 }
6654 }
6655 if (axes & ORIENTATION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006656 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_ORIENTATION, RAW_ORIENTATION_MIN,
6657 RAW_ORIENTATION_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006658 }
6659 if (axes & PRESSURE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006660 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_PRESSURE, RAW_PRESSURE_MIN,
6661 RAW_PRESSURE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006662 }
6663 if (axes & DISTANCE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006664 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_DISTANCE, RAW_DISTANCE_MIN,
6665 RAW_DISTANCE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006666 }
6667 if (axes & ID) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006668 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX, 0,
6669 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006670 }
6671 if (axes & SLOT) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006672 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX, 0, 0);
6673 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006674 }
6675 if (axes & TOOL_TYPE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006676 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOOL_TYPE, 0, MT_TOOL_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006677 }
6678}
6679
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006680void MultiTouchInputMapperTest::processPosition(MultiTouchInputMapper& mapper, int32_t x,
6681 int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00006682 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_X, x);
6683 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006684}
6685
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006686void MultiTouchInputMapperTest::processTouchMajor(MultiTouchInputMapper& mapper,
6687 int32_t touchMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00006688 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, touchMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006689}
6690
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006691void MultiTouchInputMapperTest::processTouchMinor(MultiTouchInputMapper& mapper,
6692 int32_t touchMinor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00006693 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, touchMinor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006694}
6695
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006696void MultiTouchInputMapperTest::processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00006697 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_WIDTH_MAJOR, toolMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006698}
6699
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006700void MultiTouchInputMapperTest::processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00006701 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_WIDTH_MINOR, toolMinor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006702}
6703
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006704void MultiTouchInputMapperTest::processOrientation(MultiTouchInputMapper& mapper,
6705 int32_t orientation) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00006706 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_ORIENTATION, orientation);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006707}
6708
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006709void MultiTouchInputMapperTest::processPressure(MultiTouchInputMapper& mapper, int32_t pressure) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00006710 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_PRESSURE, pressure);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006711}
6712
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006713void MultiTouchInputMapperTest::processDistance(MultiTouchInputMapper& mapper, int32_t distance) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00006714 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_DISTANCE, distance);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006715}
6716
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006717void MultiTouchInputMapperTest::processId(MultiTouchInputMapper& mapper, int32_t id) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00006718 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TRACKING_ID, id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006719}
6720
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006721void MultiTouchInputMapperTest::processSlot(MultiTouchInputMapper& mapper, int32_t slot) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00006722 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_SLOT, slot);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006723}
6724
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006725void MultiTouchInputMapperTest::processToolType(MultiTouchInputMapper& mapper, int32_t toolType) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00006726 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOOL_TYPE, toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006727}
6728
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006729void MultiTouchInputMapperTest::processKey(MultiTouchInputMapper& mapper, int32_t code,
6730 int32_t value) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00006731 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006732}
6733
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00006734void MultiTouchInputMapperTest::processHidUsage(MultiTouchInputMapper& mapper, int32_t usageCode,
6735 int32_t value) {
6736 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, usageCode);
6737 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UNKNOWN, value);
6738}
6739
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006740void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00006741 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_MT_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006742}
6743
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00006744void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper& mapper, nsecs_t eventTime,
6745 nsecs_t readTime) {
6746 process(mapper, eventTime, readTime, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006747}
6748
Michael Wrightd02c5b62014-02-10 15:10:22 -08006749TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006750 addConfigurationProperty("touch.deviceType", "touchScreen");
6751 prepareDisplay(DISPLAY_ORIENTATION_0);
6752 prepareAxes(POSITION);
6753 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006754 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006755
arthurhungdcef2dc2020-08-11 14:47:50 +08006756 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006757
6758 NotifyMotionArgs motionArgs;
6759
6760 // Two fingers down at once.
6761 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
6762 processPosition(mapper, x1, y1);
6763 processMTSync(mapper);
6764 processPosition(mapper, x2, y2);
6765 processMTSync(mapper);
6766 processSync(mapper);
6767
6768 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6769 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6770 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6771 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6772 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6773 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6774 ASSERT_EQ(0, motionArgs.flags);
6775 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6776 ASSERT_EQ(0, motionArgs.buttonState);
6777 ASSERT_EQ(0, motionArgs.edgeFlags);
6778 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6779 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6780 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6781 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6782 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6783 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6784 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6785 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6786
6787 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6788 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6789 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6790 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6791 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08006792 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006793 ASSERT_EQ(0, motionArgs.flags);
6794 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6795 ASSERT_EQ(0, motionArgs.buttonState);
6796 ASSERT_EQ(0, motionArgs.edgeFlags);
6797 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
6798 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6799 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6800 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6801 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
6802 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6803 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6804 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6805 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6806 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6807 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6808 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6809
6810 // Move.
6811 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
6812 processPosition(mapper, x1, y1);
6813 processMTSync(mapper);
6814 processPosition(mapper, x2, y2);
6815 processMTSync(mapper);
6816 processSync(mapper);
6817
6818 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6819 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6820 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6821 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6822 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6823 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6824 ASSERT_EQ(0, motionArgs.flags);
6825 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6826 ASSERT_EQ(0, motionArgs.buttonState);
6827 ASSERT_EQ(0, motionArgs.edgeFlags);
6828 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
6829 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6830 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6831 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6832 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
6833 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6834 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6835 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6836 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6837 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6838 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6839 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6840
6841 // First finger up.
6842 x2 += 15; y2 -= 20;
6843 processPosition(mapper, x2, y2);
6844 processMTSync(mapper);
6845 processSync(mapper);
6846
6847 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6848 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6849 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6850 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6851 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08006852 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006853 ASSERT_EQ(0, motionArgs.flags);
6854 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6855 ASSERT_EQ(0, motionArgs.buttonState);
6856 ASSERT_EQ(0, motionArgs.edgeFlags);
6857 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
6858 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6859 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6860 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6861 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
6862 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6863 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6864 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6865 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6866 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6867 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6868 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6869
6870 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6871 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6872 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6873 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6874 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6875 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6876 ASSERT_EQ(0, motionArgs.flags);
6877 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6878 ASSERT_EQ(0, motionArgs.buttonState);
6879 ASSERT_EQ(0, motionArgs.edgeFlags);
6880 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6881 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
6882 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6883 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6884 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6885 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6886 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6887 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6888
6889 // Move.
6890 x2 += 20; y2 -= 25;
6891 processPosition(mapper, x2, y2);
6892 processMTSync(mapper);
6893 processSync(mapper);
6894
6895 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6896 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6897 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6898 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6899 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6900 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6901 ASSERT_EQ(0, motionArgs.flags);
6902 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6903 ASSERT_EQ(0, motionArgs.buttonState);
6904 ASSERT_EQ(0, motionArgs.edgeFlags);
6905 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6906 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
6907 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6908 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6909 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6910 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6911 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6912 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6913
6914 // New finger down.
6915 int32_t x3 = 700, y3 = 300;
6916 processPosition(mapper, x2, y2);
6917 processMTSync(mapper);
6918 processPosition(mapper, x3, y3);
6919 processMTSync(mapper);
6920 processSync(mapper);
6921
6922 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6923 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6924 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6925 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6926 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08006927 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006928 ASSERT_EQ(0, motionArgs.flags);
6929 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6930 ASSERT_EQ(0, motionArgs.buttonState);
6931 ASSERT_EQ(0, motionArgs.edgeFlags);
6932 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
6933 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6934 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6935 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6936 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
6937 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6938 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6939 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6940 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6941 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6942 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6943 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6944
6945 // Second finger up.
6946 x3 += 30; y3 -= 20;
6947 processPosition(mapper, x3, y3);
6948 processMTSync(mapper);
6949 processSync(mapper);
6950
6951 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6952 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6953 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6954 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6955 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08006956 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006957 ASSERT_EQ(0, motionArgs.flags);
6958 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6959 ASSERT_EQ(0, motionArgs.buttonState);
6960 ASSERT_EQ(0, motionArgs.edgeFlags);
6961 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
6962 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6963 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6964 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6965 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
6966 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6967 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6968 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6969 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6970 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6971 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6972 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6973
6974 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6975 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6976 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6977 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6978 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6979 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6980 ASSERT_EQ(0, motionArgs.flags);
6981 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6982 ASSERT_EQ(0, motionArgs.buttonState);
6983 ASSERT_EQ(0, motionArgs.edgeFlags);
6984 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6985 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6986 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6987 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6988 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6989 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6990 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6991 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6992
6993 // Last finger up.
6994 processMTSync(mapper);
6995 processSync(mapper);
6996
6997 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6998 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6999 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7000 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7001 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7002 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7003 ASSERT_EQ(0, motionArgs.flags);
7004 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7005 ASSERT_EQ(0, motionArgs.buttonState);
7006 ASSERT_EQ(0, motionArgs.edgeFlags);
7007 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7008 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7009 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7010 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7011 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7012 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7013 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7014 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7015
7016 // Should not have sent any more keys or motions.
7017 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7018 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7019}
7020
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08007021TEST_F(MultiTouchInputMapperTest, AxisResolution_IsPopulated) {
7022 addConfigurationProperty("touch.deviceType", "touchScreen");
7023 prepareDisplay(DISPLAY_ORIENTATION_0);
7024
7025 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
7026 /*fuzz*/ 0, /*resolution*/ 10);
7027 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
7028 /*fuzz*/ 0, /*resolution*/ 11);
7029 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
7030 /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 12);
7031 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
7032 /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 13);
7033 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
7034 /*flat*/ 0, /*flat*/ 0, /*resolution*/ 14);
7035 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
7036 /*flat*/ 0, /*flat*/ 0, /*resolution*/ 15);
7037
7038 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
7039
7040 // X and Y axes
7041 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_X, 10 / X_PRECISION);
7042 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_Y, 11 / Y_PRECISION);
7043 // Touch major and minor
7044 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR, 12 * GEOMETRIC_SCALE);
7045 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR, 13 * GEOMETRIC_SCALE);
7046 // Tool major and minor
7047 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR, 14 * GEOMETRIC_SCALE);
7048 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR, 15 * GEOMETRIC_SCALE);
7049}
7050
7051TEST_F(MultiTouchInputMapperTest, TouchMajorAndMinorAxes_DoNotAppearIfNotSupported) {
7052 addConfigurationProperty("touch.deviceType", "touchScreen");
7053 prepareDisplay(DISPLAY_ORIENTATION_0);
7054
7055 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
7056 /*fuzz*/ 0, /*resolution*/ 10);
7057 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
7058 /*fuzz*/ 0, /*resolution*/ 11);
7059
7060 // We do not add ABS_MT_TOUCH_MAJOR / MINOR or ABS_MT_WIDTH_MAJOR / MINOR axes
7061
7062 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
7063
7064 // Touch major and minor
7065 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR);
7066 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR);
7067 // Tool major and minor
7068 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR);
7069 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR);
7070}
7071
Michael Wrightd02c5b62014-02-10 15:10:22 -08007072TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007073 addConfigurationProperty("touch.deviceType", "touchScreen");
7074 prepareDisplay(DISPLAY_ORIENTATION_0);
7075 prepareAxes(POSITION | ID);
7076 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007077 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007078
arthurhungdcef2dc2020-08-11 14:47:50 +08007079 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007080
7081 NotifyMotionArgs motionArgs;
7082
7083 // Two fingers down at once.
7084 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
7085 processPosition(mapper, x1, y1);
7086 processId(mapper, 1);
7087 processMTSync(mapper);
7088 processPosition(mapper, x2, y2);
7089 processId(mapper, 2);
7090 processMTSync(mapper);
7091 processSync(mapper);
7092
7093 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7094 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7095 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7096 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7097 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7098 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7099 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7100
7101 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007102 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007103 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7104 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7105 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7106 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7107 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7108 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7109 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7110 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7111 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7112
7113 // Move.
7114 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
7115 processPosition(mapper, x1, y1);
7116 processId(mapper, 1);
7117 processMTSync(mapper);
7118 processPosition(mapper, x2, y2);
7119 processId(mapper, 2);
7120 processMTSync(mapper);
7121 processSync(mapper);
7122
7123 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7124 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7125 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7126 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7127 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7128 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7129 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7130 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7131 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7132 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7133 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7134
7135 // First finger up.
7136 x2 += 15; y2 -= 20;
7137 processPosition(mapper, x2, y2);
7138 processId(mapper, 2);
7139 processMTSync(mapper);
7140 processSync(mapper);
7141
7142 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007143 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007144 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7145 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7146 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7147 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7148 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7149 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7150 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7151 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7152 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7153
7154 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7155 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7156 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7157 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7158 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7159 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7160 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7161
7162 // Move.
7163 x2 += 20; y2 -= 25;
7164 processPosition(mapper, x2, y2);
7165 processId(mapper, 2);
7166 processMTSync(mapper);
7167 processSync(mapper);
7168
7169 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7170 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7171 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7172 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7173 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7174 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7175 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7176
7177 // New finger down.
7178 int32_t x3 = 700, y3 = 300;
7179 processPosition(mapper, x2, y2);
7180 processId(mapper, 2);
7181 processMTSync(mapper);
7182 processPosition(mapper, x3, y3);
7183 processId(mapper, 3);
7184 processMTSync(mapper);
7185 processSync(mapper);
7186
7187 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007188 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007189 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7190 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7191 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7192 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7193 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7194 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7195 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7196 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7197 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7198
7199 // Second finger up.
7200 x3 += 30; y3 -= 20;
7201 processPosition(mapper, x3, y3);
7202 processId(mapper, 3);
7203 processMTSync(mapper);
7204 processSync(mapper);
7205
7206 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007207 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007208 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7209 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7210 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7211 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7212 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7213 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7214 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7215 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7216 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7217
7218 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7219 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7220 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7221 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7222 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7223 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7224 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7225
7226 // Last finger up.
7227 processMTSync(mapper);
7228 processSync(mapper);
7229
7230 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7231 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7232 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7233 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7234 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7235 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7236 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7237
7238 // Should not have sent any more keys or motions.
7239 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7240 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7241}
7242
7243TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithSlots) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007244 addConfigurationProperty("touch.deviceType", "touchScreen");
7245 prepareDisplay(DISPLAY_ORIENTATION_0);
7246 prepareAxes(POSITION | ID | SLOT);
7247 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007248 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007249
arthurhungdcef2dc2020-08-11 14:47:50 +08007250 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007251
7252 NotifyMotionArgs motionArgs;
7253
7254 // Two fingers down at once.
7255 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
7256 processPosition(mapper, x1, y1);
7257 processId(mapper, 1);
7258 processSlot(mapper, 1);
7259 processPosition(mapper, x2, y2);
7260 processId(mapper, 2);
7261 processSync(mapper);
7262
7263 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7264 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7265 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7266 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7267 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7268 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7269 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7270
7271 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007272 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007273 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7274 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7275 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7276 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7277 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7278 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7279 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7280 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7281 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7282
7283 // Move.
7284 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
7285 processSlot(mapper, 0);
7286 processPosition(mapper, x1, y1);
7287 processSlot(mapper, 1);
7288 processPosition(mapper, x2, y2);
7289 processSync(mapper);
7290
7291 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7292 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7293 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7294 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7295 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7296 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7297 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7298 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7299 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7300 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7301 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7302
7303 // First finger up.
7304 x2 += 15; y2 -= 20;
7305 processSlot(mapper, 0);
7306 processId(mapper, -1);
7307 processSlot(mapper, 1);
7308 processPosition(mapper, x2, y2);
7309 processSync(mapper);
7310
7311 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007312 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007313 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7314 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7315 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7316 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7317 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7318 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7319 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7320 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7321 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7322
7323 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7324 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7325 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7326 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7327 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7328 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7329 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7330
7331 // Move.
7332 x2 += 20; y2 -= 25;
7333 processPosition(mapper, x2, y2);
7334 processSync(mapper);
7335
7336 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7337 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7338 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7339 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7340 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7341 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7342 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7343
7344 // New finger down.
7345 int32_t x3 = 700, y3 = 300;
7346 processPosition(mapper, x2, y2);
7347 processSlot(mapper, 0);
7348 processId(mapper, 3);
7349 processPosition(mapper, x3, y3);
7350 processSync(mapper);
7351
7352 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007353 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007354 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7355 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7356 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7357 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7358 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7359 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7360 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7361 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7362 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7363
7364 // Second finger up.
7365 x3 += 30; y3 -= 20;
7366 processSlot(mapper, 1);
7367 processId(mapper, -1);
7368 processSlot(mapper, 0);
7369 processPosition(mapper, x3, y3);
7370 processSync(mapper);
7371
7372 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007373 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007374 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7375 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7376 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7377 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7378 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7379 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7380 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7381 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7382 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7383
7384 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7385 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7386 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7387 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7388 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7389 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7390 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7391
7392 // Last finger up.
7393 processId(mapper, -1);
7394 processSync(mapper);
7395
7396 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7397 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7398 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7399 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7400 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7401 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7402 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7403
7404 // Should not have sent any more keys or motions.
7405 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7406 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7407}
7408
7409TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007410 addConfigurationProperty("touch.deviceType", "touchScreen");
7411 prepareDisplay(DISPLAY_ORIENTATION_0);
7412 prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR | DISTANCE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007413 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007414
7415 // These calculations are based on the input device calibration documentation.
7416 int32_t rawX = 100;
7417 int32_t rawY = 200;
7418 int32_t rawTouchMajor = 7;
7419 int32_t rawTouchMinor = 6;
7420 int32_t rawToolMajor = 9;
7421 int32_t rawToolMinor = 8;
7422 int32_t rawPressure = 11;
7423 int32_t rawDistance = 0;
7424 int32_t rawOrientation = 3;
7425 int32_t id = 5;
7426
7427 float x = toDisplayX(rawX);
7428 float y = toDisplayY(rawY);
7429 float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
7430 float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
7431 float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
7432 float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
7433 float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
7434 float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
7435 float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2;
7436 float distance = float(rawDistance);
7437
7438 processPosition(mapper, rawX, rawY);
7439 processTouchMajor(mapper, rawTouchMajor);
7440 processTouchMinor(mapper, rawTouchMinor);
7441 processToolMajor(mapper, rawToolMajor);
7442 processToolMinor(mapper, rawToolMinor);
7443 processPressure(mapper, rawPressure);
7444 processOrientation(mapper, rawOrientation);
7445 processDistance(mapper, rawDistance);
7446 processId(mapper, id);
7447 processMTSync(mapper);
7448 processSync(mapper);
7449
7450 NotifyMotionArgs args;
7451 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
7452 ASSERT_EQ(0, args.pointerProperties[0].id);
7453 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
7454 x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor,
7455 orientation, distance));
7456}
7457
7458TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007459 addConfigurationProperty("touch.deviceType", "touchScreen");
7460 prepareDisplay(DISPLAY_ORIENTATION_0);
7461 prepareAxes(POSITION | TOUCH | TOOL | MINOR);
7462 addConfigurationProperty("touch.size.calibration", "geometric");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007463 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007464
7465 // These calculations are based on the input device calibration documentation.
7466 int32_t rawX = 100;
7467 int32_t rawY = 200;
7468 int32_t rawTouchMajor = 140;
7469 int32_t rawTouchMinor = 120;
7470 int32_t rawToolMajor = 180;
7471 int32_t rawToolMinor = 160;
7472
7473 float x = toDisplayX(rawX);
7474 float y = toDisplayY(rawY);
7475 float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
7476 float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
7477 float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
7478 float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
7479 float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
7480
7481 processPosition(mapper, rawX, rawY);
7482 processTouchMajor(mapper, rawTouchMajor);
7483 processTouchMinor(mapper, rawTouchMinor);
7484 processToolMajor(mapper, rawToolMajor);
7485 processToolMinor(mapper, rawToolMinor);
7486 processMTSync(mapper);
7487 processSync(mapper);
7488
7489 NotifyMotionArgs args;
7490 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
7491 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
7492 x, y, 1.0f, size, touchMajor, touchMinor, toolMajor, toolMinor, 0, 0));
7493}
7494
7495TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_SummedLinearCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007496 addConfigurationProperty("touch.deviceType", "touchScreen");
7497 prepareDisplay(DISPLAY_ORIENTATION_0);
7498 prepareAxes(POSITION | TOUCH | TOOL);
7499 addConfigurationProperty("touch.size.calibration", "diameter");
7500 addConfigurationProperty("touch.size.scale", "10");
7501 addConfigurationProperty("touch.size.bias", "160");
7502 addConfigurationProperty("touch.size.isSummed", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007503 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007504
7505 // These calculations are based on the input device calibration documentation.
7506 // Note: We only provide a single common touch/tool value because the device is assumed
7507 // not to emit separate values for each pointer (isSummed = 1).
7508 int32_t rawX = 100;
7509 int32_t rawY = 200;
7510 int32_t rawX2 = 150;
7511 int32_t rawY2 = 250;
7512 int32_t rawTouchMajor = 5;
7513 int32_t rawToolMajor = 8;
7514
7515 float x = toDisplayX(rawX);
7516 float y = toDisplayY(rawY);
7517 float x2 = toDisplayX(rawX2);
7518 float y2 = toDisplayY(rawY2);
7519 float size = float(rawTouchMajor) / 2 / RAW_TOUCH_MAX;
7520 float touch = float(rawTouchMajor) / 2 * 10.0f + 160.0f;
7521 float tool = float(rawToolMajor) / 2 * 10.0f + 160.0f;
7522
7523 processPosition(mapper, rawX, rawY);
7524 processTouchMajor(mapper, rawTouchMajor);
7525 processToolMajor(mapper, rawToolMajor);
7526 processMTSync(mapper);
7527 processPosition(mapper, rawX2, rawY2);
7528 processTouchMajor(mapper, rawTouchMajor);
7529 processToolMajor(mapper, rawToolMajor);
7530 processMTSync(mapper);
7531 processSync(mapper);
7532
7533 NotifyMotionArgs args;
7534 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
7535 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
7536
7537 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007538 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007539 ASSERT_EQ(size_t(2), args.pointerCount);
7540 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
7541 x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
7542 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1],
7543 x2, y2, 1.0f, size, touch, touch, tool, tool, 0, 0));
7544}
7545
7546TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_AreaCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007547 addConfigurationProperty("touch.deviceType", "touchScreen");
7548 prepareDisplay(DISPLAY_ORIENTATION_0);
7549 prepareAxes(POSITION | TOUCH | TOOL);
7550 addConfigurationProperty("touch.size.calibration", "area");
7551 addConfigurationProperty("touch.size.scale", "43");
7552 addConfigurationProperty("touch.size.bias", "3");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007553 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007554
7555 // These calculations are based on the input device calibration documentation.
7556 int32_t rawX = 100;
7557 int32_t rawY = 200;
7558 int32_t rawTouchMajor = 5;
7559 int32_t rawToolMajor = 8;
7560
7561 float x = toDisplayX(rawX);
7562 float y = toDisplayY(rawY);
7563 float size = float(rawTouchMajor) / RAW_TOUCH_MAX;
7564 float touch = sqrtf(rawTouchMajor) * 43.0f + 3.0f;
7565 float tool = sqrtf(rawToolMajor) * 43.0f + 3.0f;
7566
7567 processPosition(mapper, rawX, rawY);
7568 processTouchMajor(mapper, rawTouchMajor);
7569 processToolMajor(mapper, rawToolMajor);
7570 processMTSync(mapper);
7571 processSync(mapper);
7572
7573 NotifyMotionArgs args;
7574 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
7575 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
7576 x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
7577}
7578
7579TEST_F(MultiTouchInputMapperTest, Process_PressureAxis_AmplitudeCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007580 addConfigurationProperty("touch.deviceType", "touchScreen");
7581 prepareDisplay(DISPLAY_ORIENTATION_0);
7582 prepareAxes(POSITION | PRESSURE);
7583 addConfigurationProperty("touch.pressure.calibration", "amplitude");
7584 addConfigurationProperty("touch.pressure.scale", "0.01");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007585 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007586
Michael Wrightaa449c92017-12-13 21:21:43 +00007587 InputDeviceInfo info;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007588 mapper.populateDeviceInfo(&info);
Michael Wrightaa449c92017-12-13 21:21:43 +00007589 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
7590 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TOUCHSCREEN,
7591 0.0f, RAW_PRESSURE_MAX * 0.01, 0.0f, 0.0f));
7592
Michael Wrightd02c5b62014-02-10 15:10:22 -08007593 // These calculations are based on the input device calibration documentation.
7594 int32_t rawX = 100;
7595 int32_t rawY = 200;
7596 int32_t rawPressure = 60;
7597
7598 float x = toDisplayX(rawX);
7599 float y = toDisplayY(rawY);
7600 float pressure = float(rawPressure) * 0.01f;
7601
7602 processPosition(mapper, rawX, rawY);
7603 processPressure(mapper, rawPressure);
7604 processMTSync(mapper);
7605 processSync(mapper);
7606
7607 NotifyMotionArgs args;
7608 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
7609 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
7610 x, y, pressure, 0, 0, 0, 0, 0, 0, 0));
7611}
7612
7613TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007614 addConfigurationProperty("touch.deviceType", "touchScreen");
7615 prepareDisplay(DISPLAY_ORIENTATION_0);
7616 prepareAxes(POSITION | ID | SLOT);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007617 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007618
7619 NotifyMotionArgs motionArgs;
7620 NotifyKeyArgs keyArgs;
7621
7622 processId(mapper, 1);
7623 processPosition(mapper, 100, 200);
7624 processSync(mapper);
7625 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7626 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7627 ASSERT_EQ(0, motionArgs.buttonState);
7628
7629 // press BTN_LEFT, release BTN_LEFT
7630 processKey(mapper, BTN_LEFT, 1);
7631 processSync(mapper);
7632 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7633 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7634 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
7635
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007636 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7637 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7638 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
7639
Michael Wrightd02c5b62014-02-10 15:10:22 -08007640 processKey(mapper, BTN_LEFT, 0);
7641 processSync(mapper);
7642 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007643 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007644 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007645
7646 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007647 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007648 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007649
7650 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
7651 processKey(mapper, BTN_RIGHT, 1);
7652 processKey(mapper, BTN_MIDDLE, 1);
7653 processSync(mapper);
7654 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7655 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7656 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
7657 motionArgs.buttonState);
7658
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007659 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7660 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7661 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
7662
7663 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7664 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7665 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
7666 motionArgs.buttonState);
7667
Michael Wrightd02c5b62014-02-10 15:10:22 -08007668 processKey(mapper, BTN_RIGHT, 0);
7669 processSync(mapper);
7670 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007671 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007672 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007673
7674 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007675 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007676 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007677
7678 processKey(mapper, BTN_MIDDLE, 0);
7679 processSync(mapper);
7680 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007681 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007682 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007683
7684 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007685 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007686 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007687
7688 // press BTN_BACK, release BTN_BACK
7689 processKey(mapper, BTN_BACK, 1);
7690 processSync(mapper);
7691 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7692 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
7693 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007694
Michael Wrightd02c5b62014-02-10 15:10:22 -08007695 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007696 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007697 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
7698
7699 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7700 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7701 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007702
7703 processKey(mapper, BTN_BACK, 0);
7704 processSync(mapper);
7705 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007706 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007707 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007708
7709 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007710 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007711 ASSERT_EQ(0, motionArgs.buttonState);
7712
Michael Wrightd02c5b62014-02-10 15:10:22 -08007713 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7714 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
7715 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
7716
7717 // press BTN_SIDE, release BTN_SIDE
7718 processKey(mapper, BTN_SIDE, 1);
7719 processSync(mapper);
7720 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7721 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
7722 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007723
Michael Wrightd02c5b62014-02-10 15:10:22 -08007724 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007725 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007726 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
7727
7728 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7729 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7730 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007731
7732 processKey(mapper, BTN_SIDE, 0);
7733 processSync(mapper);
7734 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007735 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007736 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007737
7738 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007739 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007740 ASSERT_EQ(0, motionArgs.buttonState);
7741
Michael Wrightd02c5b62014-02-10 15:10:22 -08007742 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7743 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
7744 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
7745
7746 // press BTN_FORWARD, release BTN_FORWARD
7747 processKey(mapper, BTN_FORWARD, 1);
7748 processSync(mapper);
7749 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7750 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
7751 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007752
Michael Wrightd02c5b62014-02-10 15:10:22 -08007753 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007754 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007755 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
7756
7757 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7758 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7759 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007760
7761 processKey(mapper, BTN_FORWARD, 0);
7762 processSync(mapper);
7763 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007764 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007765 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007766
7767 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007768 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007769 ASSERT_EQ(0, motionArgs.buttonState);
7770
Michael Wrightd02c5b62014-02-10 15:10:22 -08007771 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7772 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
7773 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
7774
7775 // press BTN_EXTRA, release BTN_EXTRA
7776 processKey(mapper, BTN_EXTRA, 1);
7777 processSync(mapper);
7778 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7779 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
7780 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007781
Michael Wrightd02c5b62014-02-10 15:10:22 -08007782 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007783 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007784 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
7785
7786 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7787 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7788 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007789
7790 processKey(mapper, BTN_EXTRA, 0);
7791 processSync(mapper);
7792 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007793 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007794 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007795
7796 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007797 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007798 ASSERT_EQ(0, motionArgs.buttonState);
7799
Michael Wrightd02c5b62014-02-10 15:10:22 -08007800 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7801 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
7802 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
7803
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007804 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7805
Michael Wrightd02c5b62014-02-10 15:10:22 -08007806 // press BTN_STYLUS, release BTN_STYLUS
7807 processKey(mapper, BTN_STYLUS, 1);
7808 processSync(mapper);
7809 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7810 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007811 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
7812
7813 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7814 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7815 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007816
7817 processKey(mapper, BTN_STYLUS, 0);
7818 processSync(mapper);
7819 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007820 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007821 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007822
7823 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007824 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007825 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007826
7827 // press BTN_STYLUS2, release BTN_STYLUS2
7828 processKey(mapper, BTN_STYLUS2, 1);
7829 processSync(mapper);
7830 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7831 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007832 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
7833
7834 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7835 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7836 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007837
7838 processKey(mapper, BTN_STYLUS2, 0);
7839 processSync(mapper);
7840 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007841 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007842 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007843
7844 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007845 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007846 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007847
7848 // release touch
7849 processId(mapper, -1);
7850 processSync(mapper);
7851 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7852 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7853 ASSERT_EQ(0, motionArgs.buttonState);
7854}
7855
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00007856TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleMappedStylusButtons) {
7857 addConfigurationProperty("touch.deviceType", "touchScreen");
7858 prepareDisplay(DISPLAY_ORIENTATION_0);
7859 prepareAxes(POSITION | ID | SLOT);
7860 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
7861
7862 mFakeEventHub->addKey(EVENTHUB_ID, BTN_A, 0, AKEYCODE_STYLUS_BUTTON_PRIMARY, 0);
7863 mFakeEventHub->addKey(EVENTHUB_ID, 0, 0xabcd, AKEYCODE_STYLUS_BUTTON_SECONDARY, 0);
7864
7865 // Touch down.
7866 processId(mapper, 1);
7867 processPosition(mapper, 100, 200);
7868 processSync(mapper);
7869 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7870 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithButtonState(0))));
7871
7872 // Press and release button mapped to the primary stylus button.
7873 processKey(mapper, BTN_A, 1);
7874 processSync(mapper);
7875 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7876 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7877 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
7878 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7879 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
7880 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
7881
7882 processKey(mapper, BTN_A, 0);
7883 processSync(mapper);
7884 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7885 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithButtonState(0))));
7886 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7887 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
7888
7889 // Press and release the HID usage mapped to the secondary stylus button.
7890 processHidUsage(mapper, 0xabcd, 1);
7891 processSync(mapper);
7892 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7893 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7894 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY))));
7895 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7896 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
7897 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY))));
7898
7899 processHidUsage(mapper, 0xabcd, 0);
7900 processSync(mapper);
7901 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7902 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithButtonState(0))));
7903 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7904 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
7905
7906 // Release touch.
7907 processId(mapper, -1);
7908 processSync(mapper);
7909 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7910 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
7911}
7912
Michael Wrightd02c5b62014-02-10 15:10:22 -08007913TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007914 addConfigurationProperty("touch.deviceType", "touchScreen");
7915 prepareDisplay(DISPLAY_ORIENTATION_0);
7916 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007917 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007918
7919 NotifyMotionArgs motionArgs;
7920
7921 // default tool type is finger
7922 processId(mapper, 1);
7923 processPosition(mapper, 100, 200);
7924 processSync(mapper);
7925 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7926 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7927 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7928
7929 // eraser
7930 processKey(mapper, BTN_TOOL_RUBBER, 1);
7931 processSync(mapper);
7932 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7933 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7934 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
7935
7936 // stylus
7937 processKey(mapper, BTN_TOOL_RUBBER, 0);
7938 processKey(mapper, BTN_TOOL_PEN, 1);
7939 processSync(mapper);
7940 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7941 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7942 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
7943
7944 // brush
7945 processKey(mapper, BTN_TOOL_PEN, 0);
7946 processKey(mapper, BTN_TOOL_BRUSH, 1);
7947 processSync(mapper);
7948 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7949 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7950 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
7951
7952 // pencil
7953 processKey(mapper, BTN_TOOL_BRUSH, 0);
7954 processKey(mapper, BTN_TOOL_PENCIL, 1);
7955 processSync(mapper);
7956 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7957 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7958 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
7959
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08007960 // air-brush
Michael Wrightd02c5b62014-02-10 15:10:22 -08007961 processKey(mapper, BTN_TOOL_PENCIL, 0);
7962 processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
7963 processSync(mapper);
7964 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7965 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7966 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
7967
7968 // mouse
7969 processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
7970 processKey(mapper, BTN_TOOL_MOUSE, 1);
7971 processSync(mapper);
7972 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7973 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7974 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
7975
7976 // lens
7977 processKey(mapper, BTN_TOOL_MOUSE, 0);
7978 processKey(mapper, BTN_TOOL_LENS, 1);
7979 processSync(mapper);
7980 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7981 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7982 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
7983
7984 // double-tap
7985 processKey(mapper, BTN_TOOL_LENS, 0);
7986 processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
7987 processSync(mapper);
7988 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7989 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7990 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7991
7992 // triple-tap
7993 processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
7994 processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
7995 processSync(mapper);
7996 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7997 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7998 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7999
8000 // quad-tap
8001 processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
8002 processKey(mapper, BTN_TOOL_QUADTAP, 1);
8003 processSync(mapper);
8004 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8005 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8006 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8007
8008 // finger
8009 processKey(mapper, BTN_TOOL_QUADTAP, 0);
8010 processKey(mapper, BTN_TOOL_FINGER, 1);
8011 processSync(mapper);
8012 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8013 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8014 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8015
8016 // stylus trumps finger
8017 processKey(mapper, BTN_TOOL_PEN, 1);
8018 processSync(mapper);
8019 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8020 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8021 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8022
8023 // eraser trumps stylus
8024 processKey(mapper, BTN_TOOL_RUBBER, 1);
8025 processSync(mapper);
8026 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8027 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8028 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
8029
8030 // mouse trumps eraser
8031 processKey(mapper, BTN_TOOL_MOUSE, 1);
8032 processSync(mapper);
8033 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8034 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8035 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
8036
8037 // MT tool type trumps BTN tool types: MT_TOOL_FINGER
8038 processToolType(mapper, MT_TOOL_FINGER); // this is the first time we send MT_TOOL_TYPE
8039 processSync(mapper);
8040 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8041 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8042 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8043
8044 // MT tool type trumps BTN tool types: MT_TOOL_PEN
8045 processToolType(mapper, MT_TOOL_PEN);
8046 processSync(mapper);
8047 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8048 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8049 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8050
8051 // back to default tool type
8052 processToolType(mapper, -1); // use a deliberately undefined tool type, for testing
8053 processKey(mapper, BTN_TOOL_MOUSE, 0);
8054 processKey(mapper, BTN_TOOL_RUBBER, 0);
8055 processKey(mapper, BTN_TOOL_PEN, 0);
8056 processKey(mapper, BTN_TOOL_FINGER, 0);
8057 processSync(mapper);
8058 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8059 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8060 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8061}
8062
8063TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008064 addConfigurationProperty("touch.deviceType", "touchScreen");
8065 prepareDisplay(DISPLAY_ORIENTATION_0);
8066 prepareAxes(POSITION | ID | SLOT);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008067 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008068 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008069
8070 NotifyMotionArgs motionArgs;
8071
8072 // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
8073 processId(mapper, 1);
8074 processPosition(mapper, 100, 200);
8075 processSync(mapper);
8076 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8077 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8078 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8079 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8080
8081 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8082 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8083 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8084 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8085
8086 // move a little
8087 processPosition(mapper, 150, 250);
8088 processSync(mapper);
8089 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8090 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8091 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8092 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8093
8094 // down when BTN_TOUCH is pressed, pressure defaults to 1
8095 processKey(mapper, BTN_TOUCH, 1);
8096 processSync(mapper);
8097 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8098 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8099 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8100 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8101
8102 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8103 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8104 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8105 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
8106
8107 // up when BTN_TOUCH is released, hover restored
8108 processKey(mapper, BTN_TOUCH, 0);
8109 processSync(mapper);
8110 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8111 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8112 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8113 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
8114
8115 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8116 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8117 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8118 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8119
8120 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8121 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8122 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8123 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8124
8125 // exit hover when pointer goes away
8126 processId(mapper, -1);
8127 processSync(mapper);
8128 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8129 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8130 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8131 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8132}
8133
8134TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTPressureIsPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008135 addConfigurationProperty("touch.deviceType", "touchScreen");
8136 prepareDisplay(DISPLAY_ORIENTATION_0);
8137 prepareAxes(POSITION | ID | SLOT | PRESSURE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008138 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008139
8140 NotifyMotionArgs motionArgs;
8141
8142 // initially hovering because pressure is 0
8143 processId(mapper, 1);
8144 processPosition(mapper, 100, 200);
8145 processPressure(mapper, 0);
8146 processSync(mapper);
8147 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8148 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8149 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8150 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8151
8152 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8153 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8154 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8155 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8156
8157 // move a little
8158 processPosition(mapper, 150, 250);
8159 processSync(mapper);
8160 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8161 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8162 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8163 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8164
8165 // down when pressure becomes non-zero
8166 processPressure(mapper, RAW_PRESSURE_MAX);
8167 processSync(mapper);
8168 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8169 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8170 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8171 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8172
8173 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8174 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8175 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8176 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
8177
8178 // up when pressure becomes 0, hover restored
8179 processPressure(mapper, 0);
8180 processSync(mapper);
8181 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8182 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8183 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8184 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
8185
8186 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8187 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8188 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8189 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8190
8191 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8192 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8193 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8194 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8195
8196 // exit hover when pointer goes away
8197 processId(mapper, -1);
8198 processSync(mapper);
8199 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8200 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8201 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8202 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8203}
8204
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008205/**
8206 * Set the input device port <--> display port associations, and check that the
8207 * events are routed to the display that matches the display port.
8208 * This can be checked by looking at the displayId of the resulting NotifyMotionArgs.
8209 */
8210TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayPort) {
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008211 const std::string usb2 = "USB2";
8212 const uint8_t hdmi1 = 0;
8213 const uint8_t hdmi2 = 1;
8214 const std::string secondaryUniqueId = "uniqueId2";
Michael Wrightfe3de7d2020-07-02 19:05:30 +01008215 constexpr ViewportType type = ViewportType::EXTERNAL;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008216
8217 addConfigurationProperty("touch.deviceType", "touchScreen");
8218 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008219 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008220
8221 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
8222 mFakePolicy->addInputPortAssociation(usb2, hdmi2);
8223
8224 // We are intentionally not adding the viewport for display 1 yet. Since the port association
8225 // for this input device is specified, and the matching viewport is not present,
8226 // the input device should be disabled (at the mapper level).
8227
8228 // Add viewport for display 2 on hdmi2
8229 prepareSecondaryDisplay(type, hdmi2);
8230 // Send a touch event
8231 processPosition(mapper, 100, 100);
8232 processSync(mapper);
8233 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8234
8235 // Add viewport for display 1 on hdmi1
8236 prepareDisplay(DISPLAY_ORIENTATION_0, hdmi1);
8237 // Send a touch event again
8238 processPosition(mapper, 100, 100);
8239 processSync(mapper);
8240
8241 NotifyMotionArgs args;
8242 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8243 ASSERT_EQ(DISPLAY_ID, args.displayId);
8244}
Michael Wrightd02c5b62014-02-10 15:10:22 -08008245
Arthur Hung6d5b4b22022-01-21 07:21:10 +00008246TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayUniqueId) {
8247 addConfigurationProperty("touch.deviceType", "touchScreen");
8248 prepareAxes(POSITION);
8249 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8250
8251 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
8252
8253 prepareDisplay(DISPLAY_ORIENTATION_0);
8254 prepareVirtualDisplay(DISPLAY_ORIENTATION_0);
8255
8256 // Send a touch event
8257 processPosition(mapper, 100, 100);
8258 processSync(mapper);
8259
8260 NotifyMotionArgs args;
8261 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8262 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
8263}
8264
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008265TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
Garfield Tan888a6a42020-01-09 11:39:16 -08008266 // Setup for second display.
Michael Wright17db18e2020-06-26 20:51:44 +01008267 std::shared_ptr<FakePointerController> fakePointerController =
8268 std::make_shared<FakePointerController>();
Garfield Tan888a6a42020-01-09 11:39:16 -08008269 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008270 fakePointerController->setPosition(100, 200);
8271 fakePointerController->setButtonState(0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00008272 mFakePolicy->setPointerController(fakePointerController);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008273
Garfield Tan888a6a42020-01-09 11:39:16 -08008274 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
Michael Wrightfe3de7d2020-07-02 19:05:30 +01008275 prepareSecondaryDisplay(ViewportType::EXTERNAL);
Garfield Tan888a6a42020-01-09 11:39:16 -08008276
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008277 prepareDisplay(DISPLAY_ORIENTATION_0);
8278 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008279 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008280
Harry Cutts16a24cc2022-10-26 15:22:19 +00008281 // Check source is a touchpad that would obtain the PointerController.
8282 ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008283
8284 NotifyMotionArgs motionArgs;
8285 processPosition(mapper, 100, 100);
8286 processSync(mapper);
8287
8288 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8289 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8290 ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
8291}
8292
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00008293/**
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008294 * Ensure that the readTime is set to the SYN_REPORT value when processing touch events.
8295 */
8296TEST_F(MultiTouchInputMapperTest, Process_SendsReadTime) {
8297 addConfigurationProperty("touch.deviceType", "touchScreen");
8298 prepareAxes(POSITION);
8299 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8300
8301 prepareDisplay(DISPLAY_ORIENTATION_0);
8302 process(mapper, 10, 11 /*readTime*/, EV_ABS, ABS_MT_TRACKING_ID, 1);
8303 process(mapper, 15, 16 /*readTime*/, EV_ABS, ABS_MT_POSITION_X, 100);
8304 process(mapper, 20, 21 /*readTime*/, EV_ABS, ABS_MT_POSITION_Y, 100);
8305 process(mapper, 25, 26 /*readTime*/, EV_SYN, SYN_REPORT, 0);
8306
8307 NotifyMotionArgs args;
8308 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8309 ASSERT_EQ(26, args.readTime);
8310
8311 process(mapper, 30, 31 /*readTime*/, EV_ABS, ABS_MT_POSITION_X, 110);
8312 process(mapper, 30, 32 /*readTime*/, EV_ABS, ABS_MT_POSITION_Y, 220);
8313 process(mapper, 30, 33 /*readTime*/, EV_SYN, SYN_REPORT, 0);
8314
8315 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8316 ASSERT_EQ(33, args.readTime);
8317}
8318
8319/**
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00008320 * When the viewport is not active (isActive=false), the touch mapper should be disabled and the
8321 * events should not be delivered to the listener.
8322 */
8323TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreDropped) {
8324 addConfigurationProperty("touch.deviceType", "touchScreen");
Yuncheol Heo50c19b12022-11-02 20:33:08 -07008325 // Don't set touch.enableForInactiveViewport to verify the default behavior.
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00008326 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
8327 DISPLAY_ORIENTATION_0, false /*isActive*/, UNIQUE_ID, NO_PORT,
8328 ViewportType::INTERNAL);
8329 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8330 prepareAxes(POSITION);
8331 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8332
8333 NotifyMotionArgs motionArgs;
8334 processPosition(mapper, 100, 100);
8335 processSync(mapper);
8336
8337 mFakeListener->assertNotifyMotionWasNotCalled();
8338}
8339
Yuncheol Heo50c19b12022-11-02 20:33:08 -07008340/**
8341 * When the viewport is not active (isActive=false) and touch.enableForInactiveViewport is true,
8342 * the touch mapper can process the events and the events can be delivered to the listener.
8343 */
8344TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreProcessed) {
8345 addConfigurationProperty("touch.deviceType", "touchScreen");
8346 addConfigurationProperty("touch.enableForInactiveViewport", "1");
8347 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
8348 DISPLAY_ORIENTATION_0, false /*isActive*/, UNIQUE_ID, NO_PORT,
8349 ViewportType::INTERNAL);
8350 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8351 prepareAxes(POSITION);
8352 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8353
8354 NotifyMotionArgs motionArgs;
8355 processPosition(mapper, 100, 100);
8356 processSync(mapper);
8357
8358 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8359 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8360}
8361
Garfield Tanc734e4f2021-01-15 20:01:39 -08008362TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_AbortTouches) {
8363 addConfigurationProperty("touch.deviceType", "touchScreen");
Yuncheol Heo50c19b12022-11-02 20:33:08 -07008364 addConfigurationProperty("touch.enableForInactiveViewport", "0");
Garfield Tanc734e4f2021-01-15 20:01:39 -08008365 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
8366 DISPLAY_ORIENTATION_0, true /*isActive*/, UNIQUE_ID, NO_PORT,
8367 ViewportType::INTERNAL);
8368 std::optional<DisplayViewport> optionalDisplayViewport =
8369 mFakePolicy->getDisplayViewportByUniqueId(UNIQUE_ID);
8370 ASSERT_TRUE(optionalDisplayViewport.has_value());
8371 DisplayViewport displayViewport = *optionalDisplayViewport;
8372
8373 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8374 prepareAxes(POSITION);
8375 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8376
8377 // Finger down
8378 int32_t x = 100, y = 100;
8379 processPosition(mapper, x, y);
8380 processSync(mapper);
8381
8382 NotifyMotionArgs motionArgs;
8383 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8384 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8385
8386 // Deactivate display viewport
8387 displayViewport.isActive = false;
8388 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
8389 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8390
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00008391 // The ongoing touch should be canceled immediately
8392 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8393 EXPECT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
8394
8395 // Finger move is ignored
Garfield Tanc734e4f2021-01-15 20:01:39 -08008396 x += 10, y += 10;
8397 processPosition(mapper, x, y);
8398 processSync(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00008399 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
Garfield Tanc734e4f2021-01-15 20:01:39 -08008400
8401 // Reactivate display viewport
8402 displayViewport.isActive = true;
8403 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
8404 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8405
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00008406 // Finger move again starts new gesture
Garfield Tanc734e4f2021-01-15 20:01:39 -08008407 x += 10, y += 10;
8408 processPosition(mapper, x, y);
8409 processSync(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00008410 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8411 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Garfield Tanc734e4f2021-01-15 20:01:39 -08008412}
8413
Arthur Hung7c645402019-01-25 17:45:42 +08008414TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) {
8415 // Setup the first touch screen device.
Arthur Hung7c645402019-01-25 17:45:42 +08008416 prepareAxes(POSITION | ID | SLOT);
8417 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008418 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung7c645402019-01-25 17:45:42 +08008419
8420 // Create the second touch screen device, and enable multi fingers.
8421 const std::string USB2 = "USB2";
arthurhungdcef2dc2020-08-11 14:47:50 +08008422 const std::string DEVICE_NAME2 = "TOUCHSCREEN2";
Arthur Hung2c9a3342019-07-23 14:18:59 +08008423 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008424 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
arthurhungdcef2dc2020-08-11 14:47:50 +08008425 std::shared_ptr<InputDevice> device2 =
8426 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07008427 ftl::Flags<InputDeviceClass>(0));
arthurhungdcef2dc2020-08-11 14:47:50 +08008428
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008429 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
8430 0 /*flat*/, 0 /*fuzz*/);
8431 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
8432 0 /*flat*/, 0 /*fuzz*/);
8433 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX,
8434 0 /*flat*/, 0 /*fuzz*/);
8435 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX,
8436 0 /*flat*/, 0 /*fuzz*/);
8437 mFakeEventHub->setAbsoluteAxisValue(SECOND_EVENTHUB_ID, ABS_MT_SLOT, 0 /*value*/);
8438 mFakeEventHub->addConfigurationProperty(SECOND_EVENTHUB_ID, String8("touch.deviceType"),
8439 String8("touchScreen"));
Arthur Hung7c645402019-01-25 17:45:42 +08008440
8441 // Setup the second touch screen device.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008442 MultiTouchInputMapper& mapper2 = device2->addMapper<MultiTouchInputMapper>(SECOND_EVENTHUB_ID);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07008443 std::list<NotifyArgs> unused =
8444 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
8445 0 /*changes*/);
8446 unused += device2->reset(ARBITRARY_TIME);
Arthur Hung7c645402019-01-25 17:45:42 +08008447
8448 // Setup PointerController.
Michael Wright17db18e2020-06-26 20:51:44 +01008449 std::shared_ptr<FakePointerController> fakePointerController =
8450 std::make_shared<FakePointerController>();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00008451 mFakePolicy->setPointerController(fakePointerController);
Arthur Hung7c645402019-01-25 17:45:42 +08008452
8453 // Setup policy for associated displays and show touches.
8454 const uint8_t hdmi1 = 0;
8455 const uint8_t hdmi2 = 1;
8456 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
8457 mFakePolicy->addInputPortAssociation(USB2, hdmi2);
8458 mFakePolicy->setShowTouches(true);
8459
8460 // Create displays.
8461 prepareDisplay(DISPLAY_ORIENTATION_0, hdmi1);
Michael Wrightfe3de7d2020-07-02 19:05:30 +01008462 prepareSecondaryDisplay(ViewportType::EXTERNAL, hdmi2);
Arthur Hung7c645402019-01-25 17:45:42 +08008463
8464 // Default device will reconfigure above, need additional reconfiguration for another device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07008465 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
8466 InputReaderConfiguration::CHANGE_DISPLAY_INFO |
8467 InputReaderConfiguration::CHANGE_SHOW_TOUCHES);
Arthur Hung7c645402019-01-25 17:45:42 +08008468
8469 // Two fingers down at default display.
8470 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
8471 processPosition(mapper, x1, y1);
8472 processId(mapper, 1);
8473 processSlot(mapper, 1);
8474 processPosition(mapper, x2, y2);
8475 processId(mapper, 2);
8476 processSync(mapper);
8477
8478 std::map<int32_t, std::vector<int32_t>>::const_iterator iter =
8479 fakePointerController->getSpots().find(DISPLAY_ID);
8480 ASSERT_TRUE(iter != fakePointerController->getSpots().end());
8481 ASSERT_EQ(size_t(2), iter->second.size());
8482
8483 // Two fingers down at second display.
8484 processPosition(mapper2, x1, y1);
8485 processId(mapper2, 1);
8486 processSlot(mapper2, 1);
8487 processPosition(mapper2, x2, y2);
8488 processId(mapper2, 2);
8489 processSync(mapper2);
8490
8491 iter = fakePointerController->getSpots().find(SECONDARY_DISPLAY_ID);
8492 ASSERT_TRUE(iter != fakePointerController->getSpots().end());
8493 ASSERT_EQ(size_t(2), iter->second.size());
Prabir Pradhan197e0862022-07-01 14:28:00 +00008494
8495 // Disable the show touches configuration and ensure the spots are cleared.
8496 mFakePolicy->setShowTouches(false);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07008497 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
8498 InputReaderConfiguration::CHANGE_SHOW_TOUCHES);
Prabir Pradhan197e0862022-07-01 14:28:00 +00008499
8500 ASSERT_TRUE(fakePointerController->getSpots().empty());
Arthur Hung7c645402019-01-25 17:45:42 +08008501}
8502
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06008503TEST_F(MultiTouchInputMapperTest, VideoFrames_ReceivedByListener) {
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06008504 prepareAxes(POSITION);
8505 addConfigurationProperty("touch.deviceType", "touchScreen");
8506 prepareDisplay(DISPLAY_ORIENTATION_0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008507 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06008508
8509 NotifyMotionArgs motionArgs;
8510 // Unrotated video frame
8511 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
8512 std::vector<TouchVideoFrame> frames{frame};
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008513 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06008514 processPosition(mapper, 100, 200);
8515 processSync(mapper);
8516 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8517 ASSERT_EQ(frames, motionArgs.videoFrames);
8518
8519 // Subsequent touch events should not have any videoframes
8520 // This is implemented separately in FakeEventHub,
8521 // but that should match the behaviour of TouchVideoDevice.
8522 processPosition(mapper, 200, 200);
8523 processSync(mapper);
8524 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8525 ASSERT_EQ(std::vector<TouchVideoFrame>(), motionArgs.videoFrames);
8526}
8527
Prabir Pradhanc14266f2021-05-12 15:56:24 -07008528TEST_F(MultiTouchInputMapperTest, VideoFrames_AreNotRotated) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06008529 prepareAxes(POSITION);
8530 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008531 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06008532 // Unrotated video frame
8533 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
8534 NotifyMotionArgs motionArgs;
8535
8536 // Test all 4 orientations
8537 for (int32_t orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90,
Prabir Pradhanc14266f2021-05-12 15:56:24 -07008538 DISPLAY_ORIENTATION_180, DISPLAY_ORIENTATION_270}) {
8539 SCOPED_TRACE("Orientation " + StringPrintf("%i", orientation));
8540 clearViewports();
8541 prepareDisplay(orientation);
8542 std::vector<TouchVideoFrame> frames{frame};
8543 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
8544 processPosition(mapper, 100, 200);
8545 processSync(mapper);
8546 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8547 ASSERT_EQ(frames, motionArgs.videoFrames);
8548 }
8549}
8550
8551TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_AreRotated) {
8552 prepareAxes(POSITION);
8553 addConfigurationProperty("touch.deviceType", "touchScreen");
8554 // Since InputReader works in the un-rotated coordinate space, only devices that are not
8555 // orientation-aware are affected by display rotation.
8556 addConfigurationProperty("touch.orientationAware", "0");
8557 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8558 // Unrotated video frame
8559 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
8560 NotifyMotionArgs motionArgs;
8561
8562 // Test all 4 orientations
8563 for (int32_t orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90,
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06008564 DISPLAY_ORIENTATION_180, DISPLAY_ORIENTATION_270}) {
8565 SCOPED_TRACE("Orientation " + StringPrintf("%i", orientation));
8566 clearViewports();
8567 prepareDisplay(orientation);
8568 std::vector<TouchVideoFrame> frames{frame};
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008569 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06008570 processPosition(mapper, 100, 200);
8571 processSync(mapper);
8572 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Prabir Pradhanc14266f2021-05-12 15:56:24 -07008573 // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
8574 // compared to the display. This is so that when the window transform (which contains the
8575 // display rotation) is applied later by InputDispatcher, the coordinates end up in the
8576 // window's coordinate space.
8577 frames[0].rotate(getInverseRotation(orientation));
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06008578 ASSERT_EQ(frames, motionArgs.videoFrames);
lilinnan687e58f2022-07-19 16:00:50 +08008579
8580 // Release finger.
8581 processSync(mapper);
8582 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06008583 }
8584}
8585
Prabir Pradhanc14266f2021-05-12 15:56:24 -07008586TEST_F(MultiTouchInputMapperTest, VideoFrames_MultipleFramesAreNotRotated) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06008587 prepareAxes(POSITION);
8588 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008589 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06008590 // Unrotated video frames. There's no rule that they must all have the same dimensions,
8591 // so mix these.
8592 TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
8593 TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
8594 TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
8595 std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
8596 NotifyMotionArgs motionArgs;
8597
8598 prepareDisplay(DISPLAY_ORIENTATION_90);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008599 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06008600 processPosition(mapper, 100, 200);
8601 processSync(mapper);
8602 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Prabir Pradhanc14266f2021-05-12 15:56:24 -07008603 ASSERT_EQ(frames, motionArgs.videoFrames);
8604}
8605
8606TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_MultipleFramesAreRotated) {
8607 prepareAxes(POSITION);
8608 addConfigurationProperty("touch.deviceType", "touchScreen");
8609 // Since InputReader works in the un-rotated coordinate space, only devices that are not
8610 // orientation-aware are affected by display rotation.
8611 addConfigurationProperty("touch.orientationAware", "0");
8612 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8613 // Unrotated video frames. There's no rule that they must all have the same dimensions,
8614 // so mix these.
8615 TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
8616 TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
8617 TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
8618 std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
8619 NotifyMotionArgs motionArgs;
8620
8621 prepareDisplay(DISPLAY_ORIENTATION_90);
8622 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
8623 processPosition(mapper, 100, 200);
8624 processSync(mapper);
8625 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8626 std::for_each(frames.begin(), frames.end(), [](TouchVideoFrame& frame) {
8627 // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
8628 // compared to the display. This is so that when the window transform (which contains the
8629 // display rotation) is applied later by InputDispatcher, the coordinates end up in the
8630 // window's coordinate space.
8631 frame.rotate(getInverseRotation(DISPLAY_ORIENTATION_90));
8632 });
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06008633 ASSERT_EQ(frames, motionArgs.videoFrames);
8634}
8635
Arthur Hung9da14732019-09-02 16:16:58 +08008636/**
8637 * If we had defined port associations, but the viewport is not ready, the touch device would be
8638 * expected to be disabled, and it should be enabled after the viewport has found.
8639 */
8640TEST_F(MultiTouchInputMapperTest, Configure_EnabledForAssociatedDisplay) {
Arthur Hung9da14732019-09-02 16:16:58 +08008641 constexpr uint8_t hdmi2 = 1;
8642 const std::string secondaryUniqueId = "uniqueId2";
Michael Wrightfe3de7d2020-07-02 19:05:30 +01008643 constexpr ViewportType type = ViewportType::EXTERNAL;
Arthur Hung9da14732019-09-02 16:16:58 +08008644
8645 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi2);
8646
8647 addConfigurationProperty("touch.deviceType", "touchScreen");
8648 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008649 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung9da14732019-09-02 16:16:58 +08008650
8651 ASSERT_EQ(mDevice->isEnabled(), false);
8652
8653 // Add display on hdmi2, the device should be enabled and can receive touch event.
8654 prepareSecondaryDisplay(type, hdmi2);
8655 ASSERT_EQ(mDevice->isEnabled(), true);
8656
8657 // Send a touch event.
8658 processPosition(mapper, 100, 100);
8659 processSync(mapper);
8660
8661 NotifyMotionArgs args;
8662 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8663 ASSERT_EQ(SECONDARY_DISPLAY_ID, args.displayId);
8664}
8665
Arthur Hung421eb1c2020-01-16 00:09:42 +08008666TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleSingleTouch) {
Arthur Hung421eb1c2020-01-16 00:09:42 +08008667 addConfigurationProperty("touch.deviceType", "touchScreen");
8668 prepareDisplay(DISPLAY_ORIENTATION_0);
8669 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008670 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung421eb1c2020-01-16 00:09:42 +08008671
8672 NotifyMotionArgs motionArgs;
8673
8674 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
8675 // finger down
8676 processId(mapper, 1);
8677 processPosition(mapper, x1, y1);
8678 processSync(mapper);
8679 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8680 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8681 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8682
8683 // finger move
8684 processId(mapper, 1);
8685 processPosition(mapper, x2, y2);
8686 processSync(mapper);
8687 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8688 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8689 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8690
8691 // finger up.
8692 processId(mapper, -1);
8693 processSync(mapper);
8694 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8695 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8696 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8697
8698 // new finger down
8699 processId(mapper, 1);
8700 processPosition(mapper, x3, y3);
8701 processSync(mapper);
8702 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8703 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8704 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8705}
8706
8707/**
arthurhungcc7f9802020-04-30 17:55:40 +08008708 * Test single touch should be canceled when received the MT_TOOL_PALM event, and the following
8709 * MOVE and UP events should be ignored.
Arthur Hung421eb1c2020-01-16 00:09:42 +08008710 */
arthurhungcc7f9802020-04-30 17:55:40 +08008711TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_SinglePointer) {
Arthur Hung421eb1c2020-01-16 00:09:42 +08008712 addConfigurationProperty("touch.deviceType", "touchScreen");
8713 prepareDisplay(DISPLAY_ORIENTATION_0);
8714 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008715 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung421eb1c2020-01-16 00:09:42 +08008716
8717 NotifyMotionArgs motionArgs;
8718
8719 // default tool type is finger
8720 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
arthurhungcc7f9802020-04-30 17:55:40 +08008721 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08008722 processPosition(mapper, x1, y1);
8723 processSync(mapper);
8724 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8725 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8726 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8727
8728 // Tool changed to MT_TOOL_PALM expect sending the cancel event.
8729 processToolType(mapper, MT_TOOL_PALM);
8730 processSync(mapper);
8731 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8732 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
8733
8734 // Ignore the following MOVE and UP events if had detect a palm event.
arthurhungcc7f9802020-04-30 17:55:40 +08008735 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08008736 processPosition(mapper, x2, y2);
8737 processSync(mapper);
8738 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8739
8740 // finger up.
arthurhungcc7f9802020-04-30 17:55:40 +08008741 processId(mapper, INVALID_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08008742 processSync(mapper);
8743 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8744
8745 // new finger down
arthurhungcc7f9802020-04-30 17:55:40 +08008746 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08008747 processToolType(mapper, MT_TOOL_FINGER);
Arthur Hung421eb1c2020-01-16 00:09:42 +08008748 processPosition(mapper, x3, y3);
8749 processSync(mapper);
8750 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8751 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8752 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8753}
8754
arthurhungbf89a482020-04-17 17:37:55 +08008755/**
arthurhungcc7f9802020-04-30 17:55:40 +08008756 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event from some finger,
8757 * and the rest active fingers could still be allowed to receive the events
arthurhungbf89a482020-04-17 17:37:55 +08008758 */
arthurhungcc7f9802020-04-30 17:55:40 +08008759TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_TwoPointers) {
arthurhungbf89a482020-04-17 17:37:55 +08008760 addConfigurationProperty("touch.deviceType", "touchScreen");
8761 prepareDisplay(DISPLAY_ORIENTATION_0);
8762 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
8763 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8764
8765 NotifyMotionArgs motionArgs;
8766
8767 // default tool type is finger
arthurhungcc7f9802020-04-30 17:55:40 +08008768 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220;
8769 processId(mapper, FIRST_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +08008770 processPosition(mapper, x1, y1);
8771 processSync(mapper);
8772 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8773 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8774 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8775
8776 // Second finger down.
arthurhungcc7f9802020-04-30 17:55:40 +08008777 processSlot(mapper, SECOND_SLOT);
8778 processId(mapper, SECOND_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +08008779 processPosition(mapper, x2, y2);
arthurhungcc7f9802020-04-30 17:55:40 +08008780 processSync(mapper);
8781 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008782 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08008783 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
8784
8785 // If the tool type of the first finger changes to MT_TOOL_PALM,
8786 // we expect to receive ACTION_POINTER_UP with cancel flag.
8787 processSlot(mapper, FIRST_SLOT);
8788 processId(mapper, FIRST_TRACKING_ID);
8789 processToolType(mapper, MT_TOOL_PALM);
8790 processSync(mapper);
8791 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008792 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08008793 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
8794
8795 // The following MOVE events of second finger should be processed.
8796 processSlot(mapper, SECOND_SLOT);
8797 processId(mapper, SECOND_TRACKING_ID);
8798 processPosition(mapper, x2 + 1, y2 + 1);
8799 processSync(mapper);
8800 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8801 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8802 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
8803
8804 // First finger up. It used to be in palm mode, and we already generated ACTION_POINTER_UP for
8805 // it. Second finger receive move.
8806 processSlot(mapper, FIRST_SLOT);
8807 processId(mapper, INVALID_TRACKING_ID);
8808 processSync(mapper);
8809 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8810 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8811 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
8812
8813 // Second finger keeps moving.
8814 processSlot(mapper, SECOND_SLOT);
8815 processId(mapper, SECOND_TRACKING_ID);
8816 processPosition(mapper, x2 + 2, y2 + 2);
8817 processSync(mapper);
8818 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8819 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8820 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
8821
8822 // Second finger up.
8823 processId(mapper, INVALID_TRACKING_ID);
8824 processSync(mapper);
8825 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8826 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8827 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
8828}
8829
8830/**
8831 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event, if only 1 finger
8832 * is active, it should send CANCEL after receiving the MT_TOOL_PALM event.
8833 */
8834TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_ShouldCancelWhenAllTouchIsPalm) {
8835 addConfigurationProperty("touch.deviceType", "touchScreen");
8836 prepareDisplay(DISPLAY_ORIENTATION_0);
8837 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
8838 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8839
8840 NotifyMotionArgs motionArgs;
8841
8842 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
8843 // First finger down.
8844 processId(mapper, FIRST_TRACKING_ID);
8845 processPosition(mapper, x1, y1);
8846 processSync(mapper);
8847 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8848 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8849 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8850
8851 // Second finger down.
8852 processSlot(mapper, SECOND_SLOT);
8853 processId(mapper, SECOND_TRACKING_ID);
8854 processPosition(mapper, x2, y2);
arthurhungbf89a482020-04-17 17:37:55 +08008855 processSync(mapper);
8856 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008857 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
arthurhungbf89a482020-04-17 17:37:55 +08008858 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8859
arthurhungcc7f9802020-04-30 17:55:40 +08008860 // If the tool type of the first finger changes to MT_TOOL_PALM,
8861 // we expect to receive ACTION_POINTER_UP with cancel flag.
8862 processSlot(mapper, FIRST_SLOT);
8863 processId(mapper, FIRST_TRACKING_ID);
8864 processToolType(mapper, MT_TOOL_PALM);
8865 processSync(mapper);
8866 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008867 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08008868 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
8869
8870 // Second finger keeps moving.
8871 processSlot(mapper, SECOND_SLOT);
8872 processId(mapper, SECOND_TRACKING_ID);
8873 processPosition(mapper, x2 + 1, y2 + 1);
8874 processSync(mapper);
8875 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8876 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8877
8878 // second finger becomes palm, receive cancel due to only 1 finger is active.
8879 processId(mapper, SECOND_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +08008880 processToolType(mapper, MT_TOOL_PALM);
8881 processSync(mapper);
8882 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8883 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
8884
arthurhungcc7f9802020-04-30 17:55:40 +08008885 // third finger down.
8886 processSlot(mapper, THIRD_SLOT);
8887 processId(mapper, THIRD_TRACKING_ID);
8888 processToolType(mapper, MT_TOOL_FINGER);
arthurhungbf89a482020-04-17 17:37:55 +08008889 processPosition(mapper, x3, y3);
8890 processSync(mapper);
arthurhungbf89a482020-04-17 17:37:55 +08008891 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8892 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8893 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
arthurhungcc7f9802020-04-30 17:55:40 +08008894 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
8895
8896 // third finger move
8897 processId(mapper, THIRD_TRACKING_ID);
8898 processPosition(mapper, x3 + 1, y3 + 1);
8899 processSync(mapper);
8900 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8901 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8902
8903 // first finger up, third finger receive move.
8904 processSlot(mapper, FIRST_SLOT);
8905 processId(mapper, INVALID_TRACKING_ID);
8906 processSync(mapper);
8907 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8908 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8909 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
8910
8911 // second finger up, third finger receive move.
8912 processSlot(mapper, SECOND_SLOT);
8913 processId(mapper, INVALID_TRACKING_ID);
8914 processSync(mapper);
8915 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8916 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8917 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
8918
8919 // third finger up.
8920 processSlot(mapper, THIRD_SLOT);
8921 processId(mapper, INVALID_TRACKING_ID);
8922 processSync(mapper);
8923 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8924 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8925 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
8926}
8927
8928/**
8929 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event from some finger,
8930 * and the active finger could still be allowed to receive the events
8931 */
8932TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_KeepFirstPointer) {
8933 addConfigurationProperty("touch.deviceType", "touchScreen");
8934 prepareDisplay(DISPLAY_ORIENTATION_0);
8935 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
8936 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8937
8938 NotifyMotionArgs motionArgs;
8939
8940 // default tool type is finger
8941 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220;
8942 processId(mapper, FIRST_TRACKING_ID);
8943 processPosition(mapper, x1, y1);
8944 processSync(mapper);
8945 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8946 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8947 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8948
8949 // Second finger down.
8950 processSlot(mapper, SECOND_SLOT);
8951 processId(mapper, SECOND_TRACKING_ID);
8952 processPosition(mapper, x2, y2);
8953 processSync(mapper);
8954 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008955 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08008956 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8957
8958 // If the tool type of the second finger changes to MT_TOOL_PALM,
8959 // we expect to receive ACTION_POINTER_UP with cancel flag.
8960 processId(mapper, SECOND_TRACKING_ID);
8961 processToolType(mapper, MT_TOOL_PALM);
8962 processSync(mapper);
8963 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008964 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08008965 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
8966
8967 // The following MOVE event should be processed.
8968 processSlot(mapper, FIRST_SLOT);
8969 processId(mapper, FIRST_TRACKING_ID);
8970 processPosition(mapper, x1 + 1, y1 + 1);
8971 processSync(mapper);
8972 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8973 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8974 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
8975
8976 // second finger up.
8977 processSlot(mapper, SECOND_SLOT);
8978 processId(mapper, INVALID_TRACKING_ID);
8979 processSync(mapper);
8980 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8981 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8982
8983 // first finger keep moving
8984 processSlot(mapper, FIRST_SLOT);
8985 processId(mapper, FIRST_TRACKING_ID);
8986 processPosition(mapper, x1 + 2, y1 + 2);
8987 processSync(mapper);
8988 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8989 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8990
8991 // first finger up.
8992 processId(mapper, INVALID_TRACKING_ID);
8993 processSync(mapper);
8994 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8995 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8996 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
arthurhungbf89a482020-04-17 17:37:55 +08008997}
8998
Arthur Hung9ad18942021-06-19 02:04:46 +00008999/**
9000 * Test multi-touch should sent ACTION_POINTER_UP/ACTION_UP when received the INVALID_TRACKING_ID,
9001 * to prevent the driver side may send unexpected data after set tracking id as INVALID_TRACKING_ID
9002 * cause slot be valid again.
9003 */
9004TEST_F(MultiTouchInputMapperTest, Process_MultiTouch_WithInvalidTrackingId) {
9005 addConfigurationProperty("touch.deviceType", "touchScreen");
9006 prepareDisplay(DISPLAY_ORIENTATION_0);
9007 prepareAxes(POSITION | ID | SLOT | PRESSURE);
9008 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9009
9010 NotifyMotionArgs motionArgs;
9011
9012 constexpr int32_t x1 = 100, y1 = 200, x2 = 0, y2 = 0;
9013 // First finger down.
9014 processId(mapper, FIRST_TRACKING_ID);
9015 processPosition(mapper, x1, y1);
9016 processPressure(mapper, RAW_PRESSURE_MAX);
9017 processSync(mapper);
9018 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9019 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9020 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9021
9022 // First finger move.
9023 processId(mapper, FIRST_TRACKING_ID);
9024 processPosition(mapper, x1 + 1, y1 + 1);
9025 processPressure(mapper, RAW_PRESSURE_MAX);
9026 processSync(mapper);
9027 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9028 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9029 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9030
9031 // Second finger down.
9032 processSlot(mapper, SECOND_SLOT);
9033 processId(mapper, SECOND_TRACKING_ID);
9034 processPosition(mapper, x2, y2);
9035 processPressure(mapper, RAW_PRESSURE_MAX);
9036 processSync(mapper);
9037 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009038 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Arthur Hung9ad18942021-06-19 02:04:46 +00009039 ASSERT_EQ(uint32_t(2), motionArgs.pointerCount);
9040
9041 // second finger up with some unexpected data.
9042 processSlot(mapper, SECOND_SLOT);
9043 processId(mapper, INVALID_TRACKING_ID);
9044 processPosition(mapper, x2, y2);
9045 processSync(mapper);
9046 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009047 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Arthur Hung9ad18942021-06-19 02:04:46 +00009048 ASSERT_EQ(uint32_t(2), motionArgs.pointerCount);
9049
9050 // first finger up with some unexpected data.
9051 processSlot(mapper, FIRST_SLOT);
9052 processId(mapper, INVALID_TRACKING_ID);
9053 processPosition(mapper, x2, y2);
9054 processPressure(mapper, RAW_PRESSURE_MAX);
9055 processSync(mapper);
9056 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9057 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9058 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9059}
9060
Prabir Pradhanafabcde2022-09-27 19:32:43 +00009061TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState) {
9062 addConfigurationProperty("touch.deviceType", "touchScreen");
9063 prepareDisplay(DISPLAY_ORIENTATION_0);
9064 prepareAxes(POSITION | ID | SLOT | PRESSURE);
9065 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9066
9067 // First finger down.
9068 processId(mapper, FIRST_TRACKING_ID);
9069 processPosition(mapper, 100, 200);
9070 processPressure(mapper, RAW_PRESSURE_MAX);
9071 processSync(mapper);
9072 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9073 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
9074
9075 // Second finger down.
9076 processSlot(mapper, SECOND_SLOT);
9077 processId(mapper, SECOND_TRACKING_ID);
9078 processPosition(mapper, 300, 400);
9079 processPressure(mapper, RAW_PRESSURE_MAX);
9080 processSync(mapper);
9081 ASSERT_NO_FATAL_FAILURE(
9082 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(ACTION_POINTER_1_DOWN)));
9083
9084 // Reset the mapper. When the mapper is reset, we expect the current multi-touch state to be
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00009085 // preserved. Resetting should cancel the ongoing gesture.
9086 resetMapper(mapper, ARBITRARY_TIME);
9087 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9088 WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
Prabir Pradhanafabcde2022-09-27 19:32:43 +00009089
9090 // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
9091 // the existing touch state to generate a down event.
9092 processPosition(mapper, 301, 302);
9093 processSync(mapper);
9094 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9095 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
9096 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9097 AllOf(WithMotionAction(ACTION_POINTER_1_DOWN), WithPressure(1.f))));
9098
9099 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9100}
9101
9102TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState_NoPointersDown) {
9103 addConfigurationProperty("touch.deviceType", "touchScreen");
9104 prepareDisplay(DISPLAY_ORIENTATION_0);
9105 prepareAxes(POSITION | ID | SLOT | PRESSURE);
9106 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9107
9108 // First finger touches down and releases.
9109 processId(mapper, FIRST_TRACKING_ID);
9110 processPosition(mapper, 100, 200);
9111 processPressure(mapper, RAW_PRESSURE_MAX);
9112 processSync(mapper);
9113 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9114 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
9115 processId(mapper, INVALID_TRACKING_ID);
9116 processSync(mapper);
9117 ASSERT_NO_FATAL_FAILURE(
9118 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
9119
9120 // Reset the mapper. When the mapper is reset, we expect it to restore the latest
9121 // raw state where no pointers are down.
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00009122 resetMapper(mapper, ARBITRARY_TIME);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00009123 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9124
9125 // Send an empty sync frame. Since there are no pointers, no events are generated.
9126 processSync(mapper);
9127 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9128}
9129
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009130// --- MultiTouchInputMapperTest_ExternalDevice ---
9131
9132class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest {
9133protected:
Chris Yea52ade12020-08-27 16:49:20 -07009134 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009135};
9136
9137/**
9138 * Expect fallback to internal viewport if device is external and external viewport is not present.
9139 */
9140TEST_F(MultiTouchInputMapperTest_ExternalDevice, Viewports_Fallback) {
9141 prepareAxes(POSITION);
9142 addConfigurationProperty("touch.deviceType", "touchScreen");
9143 prepareDisplay(DISPLAY_ORIENTATION_0);
9144 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9145
9146 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
9147
9148 NotifyMotionArgs motionArgs;
9149
9150 // Expect the event to be sent to the internal viewport,
9151 // because an external viewport is not present.
9152 processPosition(mapper, 100, 100);
9153 processSync(mapper);
9154 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9155 ASSERT_EQ(ADISPLAY_ID_DEFAULT, motionArgs.displayId);
9156
9157 // Expect the event to be sent to the external viewport if it is present.
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009158 prepareSecondaryDisplay(ViewportType::EXTERNAL);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009159 processPosition(mapper, 100, 100);
9160 processSync(mapper);
9161 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9162 ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
9163}
Arthur Hung4197f6b2020-03-16 15:39:59 +08009164
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009165TEST_F(MultiTouchInputMapperTest, Process_TouchpadCapture) {
9166 // we need a pointer controller for mouse mode of touchpad (start pointer at 0,0)
9167 std::shared_ptr<FakePointerController> fakePointerController =
9168 std::make_shared<FakePointerController>();
9169 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
9170 fakePointerController->setPosition(0, 0);
9171 fakePointerController->setButtonState(0);
9172
9173 // prepare device and capture
9174 prepareDisplay(DISPLAY_ORIENTATION_0);
9175 prepareAxes(POSITION | ID | SLOT);
9176 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
9177 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
9178 mFakePolicy->setPointerCapture(true);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009179 mFakePolicy->setPointerController(fakePointerController);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009180 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9181
9182 // captured touchpad should be a touchpad source
9183 NotifyDeviceResetArgs resetArgs;
9184 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
9185 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
9186
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00009187 InputDeviceInfo deviceInfo = mDevice->getDeviceInfo();
Chris Yef74dc422020-09-02 22:41:50 -07009188
9189 const InputDeviceInfo::MotionRange* relRangeX =
9190 deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, AINPUT_SOURCE_TOUCHPAD);
9191 ASSERT_NE(relRangeX, nullptr);
9192 ASSERT_EQ(relRangeX->min, -(RAW_X_MAX - RAW_X_MIN));
9193 ASSERT_EQ(relRangeX->max, RAW_X_MAX - RAW_X_MIN);
9194 const InputDeviceInfo::MotionRange* relRangeY =
9195 deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, AINPUT_SOURCE_TOUCHPAD);
9196 ASSERT_NE(relRangeY, nullptr);
9197 ASSERT_EQ(relRangeY->min, -(RAW_Y_MAX - RAW_Y_MIN));
9198 ASSERT_EQ(relRangeY->max, RAW_Y_MAX - RAW_Y_MIN);
9199
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009200 // run captured pointer tests - note that this is unscaled, so input listener events should be
9201 // identical to what the hardware sends (accounting for any
9202 // calibration).
9203 // FINGER 0 DOWN
Chris Ye364fdb52020-08-05 15:07:56 -07009204 processSlot(mapper, 0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009205 processId(mapper, 1);
9206 processPosition(mapper, 100 + RAW_X_MIN, 100 + RAW_Y_MIN);
9207 processKey(mapper, BTN_TOUCH, 1);
9208 processSync(mapper);
9209
9210 // expect coord[0] to contain initial location of touch 0
9211 NotifyMotionArgs args;
9212 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9213 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
9214 ASSERT_EQ(1U, args.pointerCount);
9215 ASSERT_EQ(0, args.pointerProperties[0].id);
9216 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, args.source);
9217 ASSERT_NO_FATAL_FAILURE(
9218 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
9219
9220 // FINGER 1 DOWN
9221 processSlot(mapper, 1);
9222 processId(mapper, 2);
9223 processPosition(mapper, 560 + RAW_X_MIN, 154 + RAW_Y_MIN);
9224 processSync(mapper);
9225
9226 // expect coord[0] to contain previous location, coord[1] to contain new touch 1 location
9227 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009228 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009229 ASSERT_EQ(2U, args.pointerCount);
9230 ASSERT_EQ(0, args.pointerProperties[0].id);
9231 ASSERT_EQ(1, args.pointerProperties[1].id);
9232 ASSERT_NO_FATAL_FAILURE(
9233 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
9234 ASSERT_NO_FATAL_FAILURE(
9235 assertPointerCoords(args.pointerCoords[1], 560, 154, 1, 0, 0, 0, 0, 0, 0, 0));
9236
9237 // FINGER 1 MOVE
9238 processPosition(mapper, 540 + RAW_X_MIN, 690 + RAW_Y_MIN);
9239 processSync(mapper);
9240
9241 // expect coord[0] to contain previous location, coord[1] to contain new touch 1 location
9242 // from move
9243 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9244 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9245 ASSERT_NO_FATAL_FAILURE(
9246 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
9247 ASSERT_NO_FATAL_FAILURE(
9248 assertPointerCoords(args.pointerCoords[1], 540, 690, 1, 0, 0, 0, 0, 0, 0, 0));
9249
9250 // FINGER 0 MOVE
9251 processSlot(mapper, 0);
9252 processPosition(mapper, 50 + RAW_X_MIN, 800 + RAW_Y_MIN);
9253 processSync(mapper);
9254
9255 // expect coord[0] to contain new touch 0 location, coord[1] to contain previous location
9256 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9257 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9258 ASSERT_NO_FATAL_FAILURE(
9259 assertPointerCoords(args.pointerCoords[0], 50, 800, 1, 0, 0, 0, 0, 0, 0, 0));
9260 ASSERT_NO_FATAL_FAILURE(
9261 assertPointerCoords(args.pointerCoords[1], 540, 690, 1, 0, 0, 0, 0, 0, 0, 0));
9262
9263 // BUTTON DOWN
9264 processKey(mapper, BTN_LEFT, 1);
9265 processSync(mapper);
9266
9267 // touchinputmapper design sends a move before button press
9268 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9269 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9270 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9271 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
9272
9273 // BUTTON UP
9274 processKey(mapper, BTN_LEFT, 0);
9275 processSync(mapper);
9276
9277 // touchinputmapper design sends a move after button release
9278 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9279 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
9280 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9281 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9282
9283 // FINGER 0 UP
9284 processId(mapper, -1);
9285 processSync(mapper);
9286 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9287 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | 0x0000, args.action);
9288
9289 // FINGER 1 MOVE
9290 processSlot(mapper, 1);
9291 processPosition(mapper, 320 + RAW_X_MIN, 900 + RAW_Y_MIN);
9292 processSync(mapper);
9293
9294 // expect coord[0] to contain new location of touch 1, and properties[0].id to contain 1
9295 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9296 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9297 ASSERT_EQ(1U, args.pointerCount);
9298 ASSERT_EQ(1, args.pointerProperties[0].id);
9299 ASSERT_NO_FATAL_FAILURE(
9300 assertPointerCoords(args.pointerCoords[0], 320, 900, 1, 0, 0, 0, 0, 0, 0, 0));
9301
9302 // FINGER 1 UP
9303 processId(mapper, -1);
9304 processKey(mapper, BTN_TOUCH, 0);
9305 processSync(mapper);
9306 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9307 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
9308
Harry Cutts16a24cc2022-10-26 15:22:19 +00009309 // A non captured touchpad should have a mouse and touchpad source.
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009310 mFakePolicy->setPointerCapture(false);
9311 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
9312 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Harry Cutts16a24cc2022-10-26 15:22:19 +00009313 ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009314}
9315
9316TEST_F(MultiTouchInputMapperTest, Process_UnCapturedTouchpadPointer) {
9317 std::shared_ptr<FakePointerController> fakePointerController =
9318 std::make_shared<FakePointerController>();
9319 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
9320 fakePointerController->setPosition(0, 0);
9321 fakePointerController->setButtonState(0);
9322
9323 // prepare device and capture
9324 prepareDisplay(DISPLAY_ORIENTATION_0);
9325 prepareAxes(POSITION | ID | SLOT);
9326 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
9327 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009328 mFakePolicy->setPointerController(fakePointerController);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009329 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9330 // run uncaptured pointer tests - pushes out generic events
9331 // FINGER 0 DOWN
9332 processId(mapper, 3);
9333 processPosition(mapper, 100, 100);
9334 processKey(mapper, BTN_TOUCH, 1);
9335 processSync(mapper);
9336
9337 // start at (100,100), cursor should be at (0,0) * scale
9338 NotifyMotionArgs args;
9339 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9340 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
9341 ASSERT_NO_FATAL_FAILURE(
9342 assertPointerCoords(args.pointerCoords[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
9343
9344 // FINGER 0 MOVE
9345 processPosition(mapper, 200, 200);
9346 processSync(mapper);
9347
9348 // compute scaling to help with touch position checking
9349 float rawDiagonal = hypotf(RAW_X_MAX - RAW_X_MIN, RAW_Y_MAX - RAW_Y_MIN);
9350 float displayDiagonal = hypotf(DISPLAY_WIDTH, DISPLAY_HEIGHT);
9351 float scale =
9352 mFakePolicy->getPointerGestureMovementSpeedRatio() * displayDiagonal / rawDiagonal;
9353
9354 // translate from (100,100) -> (200,200), cursor should have changed to (100,100) * scale)
9355 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9356 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
9357 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 100 * scale, 100 * scale, 0,
9358 0, 0, 0, 0, 0, 0, 0));
9359}
9360
9361TEST_F(MultiTouchInputMapperTest, WhenCapturedAndNotCaptured_GetSources) {
9362 std::shared_ptr<FakePointerController> fakePointerController =
9363 std::make_shared<FakePointerController>();
9364
9365 prepareDisplay(DISPLAY_ORIENTATION_0);
9366 prepareAxes(POSITION | ID | SLOT);
9367 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009368 mFakePolicy->setPointerController(fakePointerController);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009369 mFakePolicy->setPointerCapture(false);
9370 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9371
Harry Cutts16a24cc2022-10-26 15:22:19 +00009372 // An uncaptured touchpad should be a pointer device, with additional touchpad source.
9373 ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009374
Harry Cutts16a24cc2022-10-26 15:22:19 +00009375 // A captured touchpad should just have a touchpad source.
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009376 mFakePolicy->setPointerCapture(true);
9377 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
9378 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
9379}
9380
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00009381// --- BluetoothMultiTouchInputMapperTest ---
9382
9383class BluetoothMultiTouchInputMapperTest : public MultiTouchInputMapperTest {
9384protected:
9385 void SetUp() override {
9386 InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL, BUS_BLUETOOTH);
9387 }
9388};
9389
9390TEST_F(BluetoothMultiTouchInputMapperTest, TimestampSmoothening) {
9391 addConfigurationProperty("touch.deviceType", "touchScreen");
9392 prepareDisplay(DISPLAY_ORIENTATION_0);
9393 prepareAxes(POSITION | ID | SLOT | PRESSURE);
9394 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9395
9396 nsecs_t kernelEventTime = ARBITRARY_TIME;
9397 nsecs_t expectedEventTime = ARBITRARY_TIME;
9398 // Touch down.
9399 processId(mapper, FIRST_TRACKING_ID);
9400 processPosition(mapper, 100, 200);
9401 processPressure(mapper, RAW_PRESSURE_MAX);
9402 processSync(mapper, ARBITRARY_TIME);
9403 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9404 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithEventTime(ARBITRARY_TIME))));
9405
9406 // Process several events that come in quick succession, according to their timestamps.
9407 for (int i = 0; i < 3; i++) {
9408 constexpr static nsecs_t delta = ms2ns(1);
9409 static_assert(delta < MIN_BLUETOOTH_TIMESTAMP_DELTA);
9410 kernelEventTime += delta;
9411 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
9412
9413 processPosition(mapper, 101 + i, 201 + i);
9414 processSync(mapper, kernelEventTime);
9415 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9416 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
9417 WithEventTime(expectedEventTime))));
9418 }
9419
9420 // Release the touch.
9421 processId(mapper, INVALID_TRACKING_ID);
9422 processPressure(mapper, RAW_PRESSURE_MIN);
9423 processSync(mapper, ARBITRARY_TIME + ms2ns(50));
9424 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9425 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
9426 WithEventTime(ARBITRARY_TIME + ms2ns(50)))));
9427}
9428
9429// --- MultiTouchPointerModeTest ---
9430
HQ Liue6983c72022-04-19 22:14:56 +00009431class MultiTouchPointerModeTest : public MultiTouchInputMapperTest {
9432protected:
9433 float mPointerMovementScale;
9434 float mPointerXZoomScale;
9435 void preparePointerMode(int xAxisResolution, int yAxisResolution) {
9436 addConfigurationProperty("touch.deviceType", "pointer");
9437 std::shared_ptr<FakePointerController> fakePointerController =
9438 std::make_shared<FakePointerController>();
9439 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
9440 fakePointerController->setPosition(0, 0);
9441 fakePointerController->setButtonState(0);
9442 prepareDisplay(DISPLAY_ORIENTATION_0);
9443
9444 prepareAxes(POSITION);
9445 prepareAbsoluteAxisResolution(xAxisResolution, yAxisResolution);
9446 // In order to enable swipe and freeform gesture in pointer mode, pointer capture
9447 // needs to be disabled, and the pointer gesture needs to be enabled.
9448 mFakePolicy->setPointerCapture(false);
9449 mFakePolicy->setPointerGestureEnabled(true);
9450 mFakePolicy->setPointerController(fakePointerController);
9451
9452 float rawDiagonal = hypotf(RAW_X_MAX - RAW_X_MIN, RAW_Y_MAX - RAW_Y_MIN);
9453 float displayDiagonal = hypotf(DISPLAY_WIDTH, DISPLAY_HEIGHT);
9454 mPointerMovementScale =
9455 mFakePolicy->getPointerGestureMovementSpeedRatio() * displayDiagonal / rawDiagonal;
9456 mPointerXZoomScale =
9457 mFakePolicy->getPointerGestureZoomSpeedRatio() * displayDiagonal / rawDiagonal;
9458 }
9459
9460 void prepareAbsoluteAxisResolution(int xAxisResolution, int yAxisResolution) {
9461 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
9462 /*flat*/ 0,
9463 /*fuzz*/ 0, /*resolution*/ xAxisResolution);
9464 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
9465 /*flat*/ 0,
9466 /*fuzz*/ 0, /*resolution*/ yAxisResolution);
9467 }
9468};
9469
9470/**
9471 * Two fingers down on a pointer mode touch pad. The width
9472 * of the two finger is larger than 1/4 of the touch pack diagnal length. However, it
9473 * is smaller than the fixed min physical length 30mm. Two fingers' distance must
9474 * be greater than the both value to be freeform gesture, so that after two
9475 * fingers start to move downwards, the gesture should be swipe.
9476 */
9477TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthSwipe) {
9478 // The min freeform gesture width is 25units/mm x 30mm = 750
9479 // which is greater than fraction of the diagnal length of the touchpad (349).
9480 // Thus, MaxSwipWidth is 750.
9481 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
9482 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9483 NotifyMotionArgs motionArgs;
9484
9485 // Two fingers down at once.
9486 // The two fingers are 450 units apart, expects the current gesture to be PRESS
9487 // Pointer's initial position is used the [0,0] coordinate.
9488 int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125;
9489
9490 processId(mapper, FIRST_TRACKING_ID);
9491 processPosition(mapper, x1, y1);
9492 processMTSync(mapper);
9493 processId(mapper, SECOND_TRACKING_ID);
9494 processPosition(mapper, x2, y2);
9495 processMTSync(mapper);
9496 processSync(mapper);
9497
9498 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9499 ASSERT_EQ(1U, motionArgs.pointerCount);
9500 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9501 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +00009502 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +00009503 ASSERT_NO_FATAL_FAILURE(
9504 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
9505
9506 // It should be recognized as a SWIPE gesture when two fingers start to move down,
9507 // that there should be 1 pointer.
9508 int32_t movingDistance = 200;
9509 y1 += movingDistance;
9510 y2 += movingDistance;
9511
9512 processId(mapper, FIRST_TRACKING_ID);
9513 processPosition(mapper, x1, y1);
9514 processMTSync(mapper);
9515 processId(mapper, SECOND_TRACKING_ID);
9516 processPosition(mapper, x2, y2);
9517 processMTSync(mapper);
9518 processSync(mapper);
9519
9520 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9521 ASSERT_EQ(1U, motionArgs.pointerCount);
9522 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9523 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +00009524 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +00009525 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
9526 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
9527 0, 0, 0, 0));
9528}
9529
9530/**
9531 * Two fingers down on a pointer mode touch pad. The width of the two finger is larger
9532 * than the minimum freeform gesture width, 30mm. However, it is smaller than 1/4 of
9533 * the touch pack diagnal length. Two fingers' distance must be greater than the both
9534 * value to be freeform gesture, so that after two fingers start to move downwards,
9535 * the gesture should be swipe.
9536 */
9537TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthLowResolutionSwipe) {
9538 // The min freeform gesture width is 5units/mm x 30mm = 150
9539 // which is greater than fraction of the diagnal length of the touchpad (349).
9540 // Thus, MaxSwipWidth is the fraction of the diagnal length, 349.
9541 preparePointerMode(5 /*xResolution*/, 5 /*yResolution*/);
9542 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9543 NotifyMotionArgs motionArgs;
9544
9545 // Two fingers down at once.
9546 // The two fingers are 250 units apart, expects the current gesture to be PRESS
9547 // Pointer's initial position is used the [0,0] coordinate.
9548 int32_t x1 = 100, y1 = 125, x2 = 350, y2 = 125;
9549
9550 processId(mapper, FIRST_TRACKING_ID);
9551 processPosition(mapper, x1, y1);
9552 processMTSync(mapper);
9553 processId(mapper, SECOND_TRACKING_ID);
9554 processPosition(mapper, x2, y2);
9555 processMTSync(mapper);
9556 processSync(mapper);
9557
9558 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9559 ASSERT_EQ(1U, motionArgs.pointerCount);
9560 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9561 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +00009562 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +00009563 ASSERT_NO_FATAL_FAILURE(
9564 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
9565
9566 // It should be recognized as a SWIPE gesture when two fingers start to move down,
9567 // and there should be 1 pointer.
9568 int32_t movingDistance = 200;
9569 y1 += movingDistance;
9570 y2 += movingDistance;
9571
9572 processId(mapper, FIRST_TRACKING_ID);
9573 processPosition(mapper, x1, y1);
9574 processMTSync(mapper);
9575 processId(mapper, SECOND_TRACKING_ID);
9576 processPosition(mapper, x2, y2);
9577 processMTSync(mapper);
9578 processSync(mapper);
9579
9580 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9581 ASSERT_EQ(1U, motionArgs.pointerCount);
9582 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9583 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +00009584 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +00009585 // New coordinate is the scaled relative coordinate from the initial coordinate.
9586 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
9587 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
9588 0, 0, 0, 0));
9589}
9590
9591/**
9592 * Touch the touch pad with two fingers with a distance wider than the minimum freeform
9593 * gesture width and 1/4 of the diagnal length of the touchpad. Expect to receive
9594 * freeform gestures after two fingers start to move downwards.
9595 */
9596TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) {
9597 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
9598 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9599
9600 NotifyMotionArgs motionArgs;
9601
9602 // Two fingers down at once. Wider than the max swipe width.
9603 // The gesture is expected to be PRESS, then transformed to FREEFORM
9604 int32_t x1 = 100, y1 = 125, x2 = 900, y2 = 125;
9605
9606 processId(mapper, FIRST_TRACKING_ID);
9607 processPosition(mapper, x1, y1);
9608 processMTSync(mapper);
9609 processId(mapper, SECOND_TRACKING_ID);
9610 processPosition(mapper, x2, y2);
9611 processMTSync(mapper);
9612 processSync(mapper);
9613
9614 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9615 ASSERT_EQ(1U, motionArgs.pointerCount);
9616 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9617 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +00009618 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +00009619 // One pointer for PRESS, and its coordinate is used as the origin for pointer coordinates.
9620 ASSERT_NO_FATAL_FAILURE(
9621 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
9622
9623 int32_t movingDistance = 200;
9624
9625 // Move two fingers down, expect a cancel event because gesture is changing to freeform,
9626 // then two down events for two pointers.
9627 y1 += movingDistance;
9628 y2 += movingDistance;
9629
9630 processId(mapper, FIRST_TRACKING_ID);
9631 processPosition(mapper, x1, y1);
9632 processMTSync(mapper);
9633 processId(mapper, SECOND_TRACKING_ID);
9634 processPosition(mapper, x2, y2);
9635 processMTSync(mapper);
9636 processSync(mapper);
9637
9638 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9639 // The previous PRESS gesture is cancelled, because it is transformed to freeform
9640 ASSERT_EQ(1U, motionArgs.pointerCount);
9641 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
9642 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9643 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9644 ASSERT_EQ(1U, motionArgs.pointerCount);
9645 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9646 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9647 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +00009648 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +00009649 ASSERT_EQ(2U, motionArgs.pointerCount);
9650 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN, motionArgs.action & AMOTION_EVENT_ACTION_MASK);
9651 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +00009652 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +00009653 // Two pointers' scaled relative coordinates from their initial centroid.
9654 // Initial y coordinates are 0 as y1 and y2 have the same value.
9655 float cookedX1 = (x1 - x2) / 2 * mPointerXZoomScale;
9656 float cookedX2 = (x2 - x1) / 2 * mPointerXZoomScale;
9657 // When pointers move, the new coordinates equal to the initial coordinates plus
9658 // scaled moving distance.
9659 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
9660 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
9661 0, 0, 0, 0));
9662 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], cookedX2,
9663 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
9664 0, 0, 0, 0));
9665
9666 // Move two fingers down again, expect one MOVE motion event.
9667 y1 += movingDistance;
9668 y2 += movingDistance;
9669
9670 processId(mapper, FIRST_TRACKING_ID);
9671 processPosition(mapper, x1, y1);
9672 processMTSync(mapper);
9673 processId(mapper, SECOND_TRACKING_ID);
9674 processPosition(mapper, x2, y2);
9675 processMTSync(mapper);
9676 processSync(mapper);
9677
9678 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9679 ASSERT_EQ(2U, motionArgs.pointerCount);
9680 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9681 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +00009682 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +00009683 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
9684 movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
9685 0, 0, 0, 0, 0));
9686 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], cookedX2,
9687 movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
9688 0, 0, 0, 0, 0));
9689}
9690
Harry Cutts39b7ca22022-10-05 15:55:48 +00009691TEST_F(MultiTouchPointerModeTest, TwoFingerSwipeOffsets) {
9692 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
9693 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9694 NotifyMotionArgs motionArgs;
9695
9696 // Place two fingers down.
9697 int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125;
9698
9699 processId(mapper, FIRST_TRACKING_ID);
9700 processPosition(mapper, x1, y1);
9701 processMTSync(mapper);
9702 processId(mapper, SECOND_TRACKING_ID);
9703 processPosition(mapper, x2, y2);
9704 processMTSync(mapper);
9705 processSync(mapper);
9706
9707 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9708 ASSERT_EQ(1U, motionArgs.pointerCount);
9709 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9710 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
9711 ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET));
9712 ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET));
9713
9714 // Move the two fingers down and to the left.
9715 int32_t movingDistance = 200;
9716 x1 -= movingDistance;
9717 y1 += movingDistance;
9718 x2 -= movingDistance;
9719 y2 += movingDistance;
9720
9721 processId(mapper, FIRST_TRACKING_ID);
9722 processPosition(mapper, x1, y1);
9723 processMTSync(mapper);
9724 processId(mapper, SECOND_TRACKING_ID);
9725 processPosition(mapper, x2, y2);
9726 processMTSync(mapper);
9727 processSync(mapper);
9728
9729 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9730 ASSERT_EQ(1U, motionArgs.pointerCount);
9731 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9732 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
9733 ASSERT_LT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET), 0);
9734 ASSERT_GT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET), 0);
9735}
9736
Prabir Pradhanb80b6c02022-11-02 20:05:13 +00009737TEST_F(MultiTouchPointerModeTest, WhenViewportActiveStatusChanged_PointerGestureIsReset) {
9738 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
9739 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
9740 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9741 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
9742
9743 // Start a stylus gesture.
9744 processKey(mapper, BTN_TOOL_PEN, 1);
9745 processId(mapper, FIRST_TRACKING_ID);
9746 processPosition(mapper, 100, 200);
9747 processSync(mapper);
9748 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9749 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
9750 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
9751 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
9752 // TODO(b/257078296): Pointer mode generates extra event.
9753 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9754 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
9755 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
9756 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
9757 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9758
9759 // Make the viewport inactive. This will put the device in disabled mode, and the ongoing stylus
9760 // gesture should be disabled.
9761 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
9762 viewport->isActive = false;
9763 mFakePolicy->updateViewport(*viewport);
9764 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
9765 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9766 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
9767 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
9768 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
9769 // TODO(b/257078296): Pointer mode generates extra event.
9770 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9771 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
9772 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
9773 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
9774 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9775}
9776
Arthur Hung6d5b4b22022-01-21 07:21:10 +00009777// --- JoystickInputMapperTest ---
9778
9779class JoystickInputMapperTest : public InputMapperTest {
9780protected:
9781 static const int32_t RAW_X_MIN;
9782 static const int32_t RAW_X_MAX;
9783 static const int32_t RAW_Y_MIN;
9784 static const int32_t RAW_Y_MAX;
9785
9786 void SetUp() override {
9787 InputMapperTest::SetUp(InputDeviceClass::JOYSTICK | InputDeviceClass::EXTERNAL);
9788 }
9789 void prepareAxes() {
9790 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
9791 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
9792 }
9793
9794 void processAxis(JoystickInputMapper& mapper, int32_t axis, int32_t value) {
9795 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, axis, value);
9796 }
9797
9798 void processSync(JoystickInputMapper& mapper) {
9799 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
9800 }
9801
9802 void prepareVirtualDisplay(int32_t orientation) {
9803 setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH,
9804 VIRTUAL_DISPLAY_HEIGHT, orientation, VIRTUAL_DISPLAY_UNIQUE_ID,
9805 NO_PORT, ViewportType::VIRTUAL);
9806 }
9807};
9808
9809const int32_t JoystickInputMapperTest::RAW_X_MIN = -32767;
9810const int32_t JoystickInputMapperTest::RAW_X_MAX = 32767;
9811const int32_t JoystickInputMapperTest::RAW_Y_MIN = -32767;
9812const int32_t JoystickInputMapperTest::RAW_Y_MAX = 32767;
9813
9814TEST_F(JoystickInputMapperTest, Configure_AssignsDisplayUniqueId) {
9815 prepareAxes();
9816 JoystickInputMapper& mapper = addMapperAndConfigure<JoystickInputMapper>();
9817
9818 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
9819
9820 prepareVirtualDisplay(DISPLAY_ORIENTATION_0);
9821
9822 // Send an axis event
9823 processAxis(mapper, ABS_X, 100);
9824 processSync(mapper);
9825
9826 NotifyMotionArgs args;
9827 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9828 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
9829
9830 // Send another axis event
9831 processAxis(mapper, ABS_Y, 100);
9832 processSync(mapper);
9833
9834 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9835 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
9836}
9837
Chris Ye1dd2e5c2021-04-04 23:12:41 -07009838// --- PeripheralControllerTest ---
Chris Yee2b1e5c2021-03-10 22:45:12 -08009839
Chris Ye1dd2e5c2021-04-04 23:12:41 -07009840class PeripheralControllerTest : public testing::Test {
Chris Yee2b1e5c2021-03-10 22:45:12 -08009841protected:
9842 static const char* DEVICE_NAME;
9843 static const char* DEVICE_LOCATION;
9844 static const int32_t DEVICE_ID;
9845 static const int32_t DEVICE_GENERATION;
9846 static const int32_t DEVICE_CONTROLLER_NUMBER;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07009847 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
Chris Yee2b1e5c2021-03-10 22:45:12 -08009848 static const int32_t EVENTHUB_ID;
9849
9850 std::shared_ptr<FakeEventHub> mFakeEventHub;
9851 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -07009852 std::unique_ptr<TestInputListener> mFakeListener;
Chris Yee2b1e5c2021-03-10 22:45:12 -08009853 std::unique_ptr<InstrumentedInputReader> mReader;
9854 std::shared_ptr<InputDevice> mDevice;
9855
Dominik Laskowski2f01d772022-03-23 16:01:29 -07009856 virtual void SetUp(ftl::Flags<InputDeviceClass> classes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -08009857 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07009858 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -07009859 mFakeListener = std::make_unique<TestInputListener>();
Chris Yee2b1e5c2021-03-10 22:45:12 -08009860 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -07009861 *mFakeListener);
Chris Yee2b1e5c2021-03-10 22:45:12 -08009862 mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes);
9863 }
9864
9865 void SetUp() override { SetUp(DEVICE_CLASSES); }
9866
9867 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -07009868 mFakeListener.reset();
Chris Yee2b1e5c2021-03-10 22:45:12 -08009869 mFakePolicy.clear();
9870 }
9871
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009872 std::list<NotifyArgs> configureDevice(uint32_t changes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -08009873 if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
9874 mReader->requestRefreshConfiguration(changes);
9875 mReader->loopOnce();
9876 }
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009877 return mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes);
Chris Yee2b1e5c2021-03-10 22:45:12 -08009878 }
9879
9880 std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
9881 const std::string& location, int32_t eventHubId,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07009882 ftl::Flags<InputDeviceClass> classes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -08009883 InputDeviceIdentifier identifier;
9884 identifier.name = name;
9885 identifier.location = location;
9886 std::shared_ptr<InputDevice> device =
9887 std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
9888 identifier);
9889 mReader->pushNextDevice(device);
9890 mFakeEventHub->addDevice(eventHubId, name, classes);
9891 mReader->loopOnce();
9892 return device;
9893 }
9894
9895 template <class T, typename... Args>
9896 T& addControllerAndConfigure(Args... args) {
9897 T& controller = mDevice->addController<T>(EVENTHUB_ID, args...);
9898
9899 return controller;
9900 }
9901};
9902
Chris Ye1dd2e5c2021-04-04 23:12:41 -07009903const char* PeripheralControllerTest::DEVICE_NAME = "device";
9904const char* PeripheralControllerTest::DEVICE_LOCATION = "BLUETOOTH";
9905const int32_t PeripheralControllerTest::DEVICE_ID = END_RESERVED_ID + 1000;
9906const int32_t PeripheralControllerTest::DEVICE_GENERATION = 2;
9907const int32_t PeripheralControllerTest::DEVICE_CONTROLLER_NUMBER = 0;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07009908const ftl::Flags<InputDeviceClass> PeripheralControllerTest::DEVICE_CLASSES =
9909 ftl::Flags<InputDeviceClass>(0); // not needed for current tests
Chris Ye1dd2e5c2021-04-04 23:12:41 -07009910const int32_t PeripheralControllerTest::EVENTHUB_ID = 1;
Chris Yee2b1e5c2021-03-10 22:45:12 -08009911
9912// --- BatteryControllerTest ---
Chris Ye1dd2e5c2021-04-04 23:12:41 -07009913class BatteryControllerTest : public PeripheralControllerTest {
Chris Yee2b1e5c2021-03-10 22:45:12 -08009914protected:
9915 void SetUp() override {
Chris Ye1dd2e5c2021-04-04 23:12:41 -07009916 PeripheralControllerTest::SetUp(DEVICE_CLASSES | InputDeviceClass::BATTERY);
Chris Yee2b1e5c2021-03-10 22:45:12 -08009917 }
9918};
9919
9920TEST_F(BatteryControllerTest, GetBatteryCapacity) {
Chris Ye1dd2e5c2021-04-04 23:12:41 -07009921 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -08009922
Harry Cuttsa5b71292022-11-28 12:56:17 +00009923 ASSERT_TRUE(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY));
9924 ASSERT_EQ(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY).value_or(-1),
9925 FakeEventHub::BATTERY_CAPACITY);
Chris Yee2b1e5c2021-03-10 22:45:12 -08009926}
9927
9928TEST_F(BatteryControllerTest, GetBatteryStatus) {
Chris Ye1dd2e5c2021-04-04 23:12:41 -07009929 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -08009930
Harry Cuttsa5b71292022-11-28 12:56:17 +00009931 ASSERT_TRUE(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY));
9932 ASSERT_EQ(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY).value_or(-1),
9933 FakeEventHub::BATTERY_STATUS);
Chris Yee2b1e5c2021-03-10 22:45:12 -08009934}
9935
9936// --- LightControllerTest ---
Chris Ye1dd2e5c2021-04-04 23:12:41 -07009937class LightControllerTest : public PeripheralControllerTest {
Chris Yee2b1e5c2021-03-10 22:45:12 -08009938protected:
Chris Ye1dd2e5c2021-04-04 23:12:41 -07009939 void SetUp() override {
9940 PeripheralControllerTest::SetUp(DEVICE_CLASSES | InputDeviceClass::LIGHT);
9941 }
Chris Yee2b1e5c2021-03-10 22:45:12 -08009942};
9943
Chris Ye85758332021-05-16 23:05:17 -07009944TEST_F(LightControllerTest, MonoLight) {
9945 RawLightInfo infoMono = {.id = 1,
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +00009946 .name = "mono_light",
Chris Ye85758332021-05-16 23:05:17 -07009947 .maxBrightness = 255,
9948 .flags = InputLightClass::BRIGHTNESS,
9949 .path = ""};
9950 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
Chris Yee2b1e5c2021-03-10 22:45:12 -08009951
Chris Ye1dd2e5c2021-04-04 23:12:41 -07009952 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -08009953 InputDeviceInfo info;
9954 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00009955 std::vector<InputDeviceLightInfo> lights = info.getLights();
9956 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +00009957 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
9958 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
9959
9960 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_BRIGHTNESS));
9961 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
9962}
9963
9964TEST_F(LightControllerTest, MonoKeyboardBacklight) {
9965 RawLightInfo infoMono = {.id = 1,
9966 .name = "mono_keyboard_backlight",
9967 .maxBrightness = 255,
9968 .flags = InputLightClass::BRIGHTNESS |
9969 InputLightClass::KEYBOARD_BACKLIGHT,
9970 .path = ""};
9971 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
9972
9973 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9974 InputDeviceInfo info;
9975 controller.populateDeviceInfo(&info);
9976 std::vector<InputDeviceLightInfo> lights = info.getLights();
9977 ASSERT_EQ(1U, lights.size());
9978 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
9979 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
Chris Yee2b1e5c2021-03-10 22:45:12 -08009980
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00009981 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_BRIGHTNESS));
9982 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
Chris Yee2b1e5c2021-03-10 22:45:12 -08009983}
9984
9985TEST_F(LightControllerTest, RGBLight) {
9986 RawLightInfo infoRed = {.id = 1,
9987 .name = "red",
9988 .maxBrightness = 255,
9989 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED,
9990 .path = ""};
9991 RawLightInfo infoGreen = {.id = 2,
9992 .name = "green",
9993 .maxBrightness = 255,
9994 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN,
9995 .path = ""};
9996 RawLightInfo infoBlue = {.id = 3,
9997 .name = "blue",
9998 .maxBrightness = 255,
9999 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE,
10000 .path = ""};
10001 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
10002 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
10003 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
10004
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010005 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010006 InputDeviceInfo info;
10007 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010008 std::vector<InputDeviceLightInfo> lights = info.getLights();
10009 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010010 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10011 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10012 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
10013
10014 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10015 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
10016}
10017
10018TEST_F(LightControllerTest, CorrectRGBKeyboardBacklight) {
10019 RawLightInfo infoRed = {.id = 1,
10020 .name = "red_keyboard_backlight",
10021 .maxBrightness = 255,
10022 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED |
10023 InputLightClass::KEYBOARD_BACKLIGHT,
10024 .path = ""};
10025 RawLightInfo infoGreen = {.id = 2,
10026 .name = "green_keyboard_backlight",
10027 .maxBrightness = 255,
10028 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN |
10029 InputLightClass::KEYBOARD_BACKLIGHT,
10030 .path = ""};
10031 RawLightInfo infoBlue = {.id = 3,
10032 .name = "blue_keyboard_backlight",
10033 .maxBrightness = 255,
10034 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE |
10035 InputLightClass::KEYBOARD_BACKLIGHT,
10036 .path = ""};
10037 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
10038 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
10039 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
10040
10041 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10042 InputDeviceInfo info;
10043 controller.populateDeviceInfo(&info);
10044 std::vector<InputDeviceLightInfo> lights = info.getLights();
10045 ASSERT_EQ(1U, lights.size());
10046 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
10047 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10048 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
10049
10050 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10051 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
10052}
10053
10054TEST_F(LightControllerTest, IncorrectRGBKeyboardBacklight) {
10055 RawLightInfo infoRed = {.id = 1,
10056 .name = "red",
10057 .maxBrightness = 255,
10058 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED,
10059 .path = ""};
10060 RawLightInfo infoGreen = {.id = 2,
10061 .name = "green",
10062 .maxBrightness = 255,
10063 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN,
10064 .path = ""};
10065 RawLightInfo infoBlue = {.id = 3,
10066 .name = "blue",
10067 .maxBrightness = 255,
10068 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE,
10069 .path = ""};
10070 RawLightInfo infoGlobal = {.id = 3,
10071 .name = "global_keyboard_backlight",
10072 .maxBrightness = 255,
10073 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GLOBAL |
10074 InputLightClass::KEYBOARD_BACKLIGHT,
10075 .path = ""};
10076 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
10077 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
10078 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
10079 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoGlobal));
10080
10081 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10082 InputDeviceInfo info;
10083 controller.populateDeviceInfo(&info);
10084 std::vector<InputDeviceLightInfo> lights = info.getLights();
10085 ASSERT_EQ(1U, lights.size());
10086 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10087 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10088 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010089
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010090 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10091 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010092}
10093
10094TEST_F(LightControllerTest, MultiColorRGBLight) {
10095 RawLightInfo infoColor = {.id = 1,
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010096 .name = "multi_color",
Chris Yee2b1e5c2021-03-10 22:45:12 -080010097 .maxBrightness = 255,
10098 .flags = InputLightClass::BRIGHTNESS |
10099 InputLightClass::MULTI_INTENSITY |
10100 InputLightClass::MULTI_INDEX,
10101 .path = ""};
10102
10103 mFakeEventHub->addRawLightInfo(infoColor.id, std::move(infoColor));
10104
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010105 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010106 InputDeviceInfo info;
10107 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010108 std::vector<InputDeviceLightInfo> lights = info.getLights();
10109 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010110 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10111 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10112 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
10113
10114 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10115 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
10116}
10117
10118TEST_F(LightControllerTest, MultiColorRGBKeyboardBacklight) {
10119 RawLightInfo infoColor = {.id = 1,
10120 .name = "multi_color_keyboard_backlight",
10121 .maxBrightness = 255,
10122 .flags = InputLightClass::BRIGHTNESS |
10123 InputLightClass::MULTI_INTENSITY |
10124 InputLightClass::MULTI_INDEX |
10125 InputLightClass::KEYBOARD_BACKLIGHT,
10126 .path = ""};
10127
10128 mFakeEventHub->addRawLightInfo(infoColor.id, std::move(infoColor));
10129
10130 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10131 InputDeviceInfo info;
10132 controller.populateDeviceInfo(&info);
10133 std::vector<InputDeviceLightInfo> lights = info.getLights();
10134 ASSERT_EQ(1U, lights.size());
10135 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
10136 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10137 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010138
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010139 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10140 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010141}
10142
10143TEST_F(LightControllerTest, PlayerIdLight) {
10144 RawLightInfo info1 = {.id = 1,
10145 .name = "player1",
10146 .maxBrightness = 255,
10147 .flags = InputLightClass::BRIGHTNESS,
10148 .path = ""};
10149 RawLightInfo info2 = {.id = 2,
10150 .name = "player2",
10151 .maxBrightness = 255,
10152 .flags = InputLightClass::BRIGHTNESS,
10153 .path = ""};
10154 RawLightInfo info3 = {.id = 3,
10155 .name = "player3",
10156 .maxBrightness = 255,
10157 .flags = InputLightClass::BRIGHTNESS,
10158 .path = ""};
10159 RawLightInfo info4 = {.id = 4,
10160 .name = "player4",
10161 .maxBrightness = 255,
10162 .flags = InputLightClass::BRIGHTNESS,
10163 .path = ""};
10164 mFakeEventHub->addRawLightInfo(info1.id, std::move(info1));
10165 mFakeEventHub->addRawLightInfo(info2.id, std::move(info2));
10166 mFakeEventHub->addRawLightInfo(info3.id, std::move(info3));
10167 mFakeEventHub->addRawLightInfo(info4.id, std::move(info4));
10168
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010169 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010170 InputDeviceInfo info;
10171 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010172 std::vector<InputDeviceLightInfo> lights = info.getLights();
10173 ASSERT_EQ(1U, lights.size());
10174 ASSERT_EQ(InputDeviceLightType::PLAYER_ID, lights[0].type);
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010175 ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10176 ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010177
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010178 ASSERT_FALSE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10179 ASSERT_TRUE(controller.setLightPlayerId(lights[0].id, LIGHT_PLAYER_ID));
10180 ASSERT_EQ(controller.getLightPlayerId(lights[0].id).value_or(-1), LIGHT_PLAYER_ID);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010181}
10182
Michael Wrightd02c5b62014-02-10 15:10:22 -080010183} // namespace android