blob: 6816818a7bc8e376fd96e183bdbc03be7543bec0 [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>
Harry Cuttsf13161a2023-03-08 14:15:49 +000019#include <optional>
Dominik Laskowski2f01d772022-03-23 16:01:29 -070020
Prabir Pradhan2770d242019-09-02 18:07:11 -070021#include <CursorInputMapper.h>
22#include <InputDevice.h>
23#include <InputMapper.h>
24#include <InputReader.h>
Prabir Pradhan1aed8582019-12-30 11:46:51 -080025#include <InputReaderBase.h>
26#include <InputReaderFactory.h>
Arthur Hung6d5b4b22022-01-21 07:21:10 +000027#include <JoystickInputMapper.h>
Prabir Pradhan2770d242019-09-02 18:07:11 -070028#include <KeyboardInputMapper.h>
29#include <MultiTouchInputMapper.h>
Chris Ye1dd2e5c2021-04-04 23:12:41 -070030#include <PeripheralController.h>
Chris Yef59a2f42020-10-16 12:55:26 -070031#include <SensorInputMapper.h>
Prabir Pradhan2770d242019-09-02 18:07:11 -070032#include <SingleTouchInputMapper.h>
33#include <SwitchInputMapper.h>
Prabir Pradhane3b28dd2023-10-06 04:19:29 +000034#include <TestEventMatchers.h>
Prabir Pradhan2770d242019-09-02 18:07:11 -070035#include <TestInputListener.h>
36#include <TouchInputMapper.h>
Prabir Pradhan1aed8582019-12-30 11:46:51 -080037#include <UinputDevice.h>
Chris Ye87143712020-11-10 05:05:58 +000038#include <VibratorInputMapper.h>
Prabir Pradhan2574dfa2019-10-16 16:35:07 -070039#include <android-base/thread_annotations.h>
Byoungho Jungda10dd32023-10-06 17:03:45 +090040#include <com_android_input_flags.h>
Michael Wrighta9cf4192022-12-01 23:46:39 +000041#include <ftl/enum.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080042#include <gtest/gtest.h>
chaviw3277faf2021-05-19 16:45:23 -050043#include <gui/constants.h>
Michael Wrighta9cf4192022-12-01 23:46:39 +000044#include <ui/Rotation.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080045
Siarhei Vishniakou21e96e62022-10-27 10:23:37 -070046#include <thread>
Harry Cuttsa5b71292022-11-28 12:56:17 +000047#include "FakeEventHub.h"
Harry Cutts6b5fbc52022-11-28 16:37:43 +000048#include "FakeInputReaderPolicy.h"
Harry Cuttsb57f1702022-11-28 15:34:22 +000049#include "FakePointerController.h"
Harry Cuttse6512e12022-11-28 18:44:01 +000050#include "InputMapperTest.h"
Harry Cutts144ff542022-11-28 17:41:06 +000051#include "InstrumentedInputReader.h"
Harry Cuttsa5b71292022-11-28 12:56:17 +000052#include "TestConstants.h"
Michael Wrightdde67b82020-10-27 16:09:22 +000053#include "input/DisplayViewport.h"
54#include "input/Input.h"
Michael Wright17db18e2020-06-26 20:51:44 +010055
Michael Wrightd02c5b62014-02-10 15:10:22 -080056namespace android {
57
Dominik Laskowski2f01d772022-03-23 16:01:29 -070058using namespace ftl::flag_operators;
Prabir Pradhan739dca42022-09-09 20:12:01 +000059using testing::AllOf;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -070060using std::chrono_literals::operator""ms;
61
Michael Wrightd02c5b62014-02-10 15:10:22 -080062// Arbitrary display properties.
arthurhungcc7f9802020-04-30 17:55:40 +080063static constexpr int32_t DISPLAY_ID = 0;
Prabir Pradhanc13ff082022-09-08 22:03:30 +000064static const std::string DISPLAY_UNIQUE_ID = "local:1";
arthurhungcc7f9802020-04-30 17:55:40 +080065static constexpr int32_t SECONDARY_DISPLAY_ID = DISPLAY_ID + 1;
Prabir Pradhanc13ff082022-09-08 22:03:30 +000066static const std::string SECONDARY_DISPLAY_UNIQUE_ID = "local:2";
arthurhungcc7f9802020-04-30 17:55:40 +080067static constexpr int32_t DISPLAY_WIDTH = 480;
68static constexpr int32_t DISPLAY_HEIGHT = 800;
69static constexpr int32_t VIRTUAL_DISPLAY_ID = 1;
70static constexpr int32_t VIRTUAL_DISPLAY_WIDTH = 400;
71static constexpr int32_t VIRTUAL_DISPLAY_HEIGHT = 500;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -070072static const char* VIRTUAL_DISPLAY_UNIQUE_ID = "virtual:1";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -070073static constexpr std::optional<uint8_t> NO_PORT = std::nullopt; // no physical port is specified
Michael Wrightd02c5b62014-02-10 15:10:22 -080074
arthurhungcc7f9802020-04-30 17:55:40 +080075static constexpr int32_t FIRST_SLOT = 0;
76static constexpr int32_t SECOND_SLOT = 1;
77static constexpr int32_t THIRD_SLOT = 2;
78static constexpr int32_t INVALID_TRACKING_ID = -1;
79static constexpr int32_t FIRST_TRACKING_ID = 0;
80static constexpr int32_t SECOND_TRACKING_ID = 1;
81static constexpr int32_t THIRD_TRACKING_ID = 2;
Chris Ye3fdbfef2021-01-06 18:45:18 -080082static constexpr int32_t LIGHT_BRIGHTNESS = 0x55000000;
83static constexpr int32_t LIGHT_COLOR = 0x7F448866;
84static constexpr int32_t LIGHT_PLAYER_ID = 2;
arthurhungcc7f9802020-04-30 17:55:40 +080085
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080086static constexpr int32_t ACTION_POINTER_0_DOWN =
87 AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
88static constexpr int32_t ACTION_POINTER_0_UP =
89 AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
90static constexpr int32_t ACTION_POINTER_1_DOWN =
91 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
92static constexpr int32_t ACTION_POINTER_1_UP =
93 AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
94
Prabir Pradhanb08a0e82023-09-14 22:28:32 +000095static constexpr uint32_t STYLUS_FUSION_SOURCE =
96 AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_BLUETOOTH_STYLUS;
97
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +000098// Minimum timestamp separation between subsequent input events from a Bluetooth device.
99static constexpr nsecs_t MIN_BLUETOOTH_TIMESTAMP_DELTA = ms2ns(4);
100// Maximum smoothing time delta so that we don't generate events too far into the future.
101constexpr static nsecs_t MAX_BLUETOOTH_SMOOTHING_DELTA = ms2ns(32);
102
Byoungho Jungda10dd32023-10-06 17:03:45 +0900103namespace input_flags = com::android::input::flags;
104
Michael Wrightd02c5b62014-02-10 15:10:22 -0800105template<typename T>
106static inline T min(T a, T b) {
107 return a < b ? a : b;
108}
109
110static inline float avg(float x, float y) {
111 return (x + y) / 2;
112}
113
Chris Ye3fdbfef2021-01-06 18:45:18 -0800114// Mapping for light color name and the light color
115const std::unordered_map<std::string, LightColor> LIGHT_COLORS = {{"red", LightColor::RED},
116 {"green", LightColor::GREEN},
117 {"blue", LightColor::BLUE}};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800118
Michael Wrighta9cf4192022-12-01 23:46:39 +0000119static ui::Rotation getInverseRotation(ui::Rotation orientation) {
Prabir Pradhanc14266f2021-05-12 15:56:24 -0700120 switch (orientation) {
Michael Wrighta9cf4192022-12-01 23:46:39 +0000121 case ui::ROTATION_90:
122 return ui::ROTATION_270;
123 case ui::ROTATION_270:
124 return ui::ROTATION_90;
Prabir Pradhanc14266f2021-05-12 15:56:24 -0700125 default:
126 return orientation;
127 }
128}
129
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800130static void assertAxisResolution(MultiTouchInputMapper& mapper, int axis, float resolution) {
131 InputDeviceInfo info;
Harry Cuttsd02ea102023-03-17 18:21:30 +0000132 mapper.populateDeviceInfo(info);
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800133
134 const InputDeviceInfo::MotionRange* motionRange =
135 info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
136 ASSERT_NEAR(motionRange->resolution, resolution, EPSILON);
137}
138
139static void assertAxisNotPresent(MultiTouchInputMapper& mapper, int axis) {
140 InputDeviceInfo info;
Harry Cuttsd02ea102023-03-17 18:21:30 +0000141 mapper.populateDeviceInfo(info);
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800142
143 const InputDeviceInfo::MotionRange* motionRange =
144 info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
145 ASSERT_EQ(nullptr, motionRange);
146}
147
Siarhei Vishniakou21e96e62022-10-27 10:23:37 -0700148[[maybe_unused]] static void dumpReader(InputReader& reader) {
149 std::string dump;
150 reader.dump(dump);
151 std::istringstream iss(dump);
152 for (std::string line; std::getline(iss, line);) {
153 ALOGE("%s", line.c_str());
154 std::this_thread::sleep_for(std::chrono::milliseconds(1));
155 }
156}
157
Michael Wrightd02c5b62014-02-10 15:10:22 -0800158// --- FakeInputMapper ---
159
160class FakeInputMapper : public InputMapper {
161 uint32_t mSources;
162 int32_t mKeyboardType;
163 int32_t mMetaState;
164 KeyedVector<int32_t, int32_t> mKeyCodeStates;
165 KeyedVector<int32_t, int32_t> mScanCodeStates;
166 KeyedVector<int32_t, int32_t> mSwitchStates;
Philip Junker4af3b3d2021-12-14 10:36:55 +0100167 // fake mapping which would normally come from keyCharacterMap
168 std::unordered_map<int32_t, int32_t> mKeyCodeMapping;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800169 std::vector<int32_t> mSupportedKeyCodes;
Yeabkal Wubshite03e8b12023-06-27 16:23:12 -0700170 std::list<NotifyArgs> mProcessResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800171
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700172 std::mutex mLock;
173 std::condition_variable mStateChangedCondition;
174 bool mConfigureWasCalled GUARDED_BY(mLock);
175 bool mResetWasCalled GUARDED_BY(mLock);
176 bool mProcessWasCalled GUARDED_BY(mLock);
177 RawEvent mLastEvent GUARDED_BY(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800178
Arthur Hungc23540e2018-11-29 20:42:11 +0800179 std::optional<DisplayViewport> mViewport;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800180public:
Arpit Singh8e6fb252023-04-06 11:49:17 +0000181 FakeInputMapper(InputDeviceContext& deviceContext, const InputReaderConfiguration& readerConfig,
182 uint32_t sources)
183 : InputMapper(deviceContext, readerConfig),
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800184 mSources(sources),
185 mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
Michael Wrightd02c5b62014-02-10 15:10:22 -0800186 mMetaState(0),
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800187 mConfigureWasCalled(false),
188 mResetWasCalled(false),
189 mProcessWasCalled(false) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800190
Chris Yea52ade12020-08-27 16:49:20 -0700191 virtual ~FakeInputMapper() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800192
193 void setKeyboardType(int32_t keyboardType) {
194 mKeyboardType = keyboardType;
195 }
196
197 void setMetaState(int32_t metaState) {
198 mMetaState = metaState;
199 }
200
Yeabkal Wubshite03e8b12023-06-27 16:23:12 -0700201 // Sets the return value for the `process` call.
202 void setProcessResult(std::list<NotifyArgs> notifyArgs) {
203 mProcessResult.clear();
204 for (auto notifyArg : notifyArgs) {
205 mProcessResult.push_back(notifyArg);
206 }
207 }
208
Michael Wrightd02c5b62014-02-10 15:10:22 -0800209 void assertConfigureWasCalled() {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700210 std::unique_lock<std::mutex> lock(mLock);
211 base::ScopedLockAssertion assumeLocked(mLock);
212 const bool configureCalled =
213 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
214 return mConfigureWasCalled;
215 });
216 if (!configureCalled) {
217 FAIL() << "Expected configure() to have been called.";
218 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800219 mConfigureWasCalled = false;
220 }
221
222 void assertResetWasCalled() {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700223 std::unique_lock<std::mutex> lock(mLock);
224 base::ScopedLockAssertion assumeLocked(mLock);
225 const bool resetCalled =
226 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
227 return mResetWasCalled;
228 });
229 if (!resetCalled) {
230 FAIL() << "Expected reset() to have been called.";
231 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800232 mResetWasCalled = false;
233 }
234
Prabir Pradhanf8d9e442023-12-06 22:06:13 +0000235 void assertResetWasNotCalled() {
236 std::scoped_lock lock(mLock);
237 ASSERT_FALSE(mResetWasCalled) << "Expected reset to not have been called.";
238 }
239
Yi Kong9b14ac62018-07-17 13:48:38 -0700240 void assertProcessWasCalled(RawEvent* outLastEvent = nullptr) {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700241 std::unique_lock<std::mutex> lock(mLock);
242 base::ScopedLockAssertion assumeLocked(mLock);
243 const bool processCalled =
244 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
245 return mProcessWasCalled;
246 });
247 if (!processCalled) {
248 FAIL() << "Expected process() to have been called.";
249 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800250 if (outLastEvent) {
251 *outLastEvent = mLastEvent;
252 }
253 mProcessWasCalled = false;
254 }
255
Prabir Pradhanf8d9e442023-12-06 22:06:13 +0000256 void assertProcessWasNotCalled() {
257 std::scoped_lock lock(mLock);
258 ASSERT_FALSE(mProcessWasCalled) << "Expected process to not have been called.";
259 }
260
Michael Wrightd02c5b62014-02-10 15:10:22 -0800261 void setKeyCodeState(int32_t keyCode, int32_t state) {
262 mKeyCodeStates.replaceValueFor(keyCode, state);
263 }
264
265 void setScanCodeState(int32_t scanCode, int32_t state) {
266 mScanCodeStates.replaceValueFor(scanCode, state);
267 }
268
269 void setSwitchState(int32_t switchCode, int32_t state) {
270 mSwitchStates.replaceValueFor(switchCode, state);
271 }
272
273 void addSupportedKeyCode(int32_t keyCode) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800274 mSupportedKeyCodes.push_back(keyCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800275 }
276
Philip Junker4af3b3d2021-12-14 10:36:55 +0100277 void addKeyCodeMapping(int32_t fromKeyCode, int32_t toKeyCode) {
278 mKeyCodeMapping.insert_or_assign(fromKeyCode, toKeyCode);
279 }
280
Michael Wrightd02c5b62014-02-10 15:10:22 -0800281private:
Philip Junker4af3b3d2021-12-14 10:36:55 +0100282 uint32_t getSources() const override { return mSources; }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800283
Harry Cuttsd02ea102023-03-17 18:21:30 +0000284 void populateDeviceInfo(InputDeviceInfo& deviceInfo) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800285 InputMapper::populateDeviceInfo(deviceInfo);
286
287 if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) {
Harry Cuttsd02ea102023-03-17 18:21:30 +0000288 deviceInfo.setKeyboardType(mKeyboardType);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800289 }
290 }
291
Arpit Singhed6c3de2023-04-05 19:24:37 +0000292 std::list<NotifyArgs> reconfigure(nsecs_t, const InputReaderConfiguration& config,
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000293 ConfigurationChanges changes) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700294 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800295 mConfigureWasCalled = true;
Arthur Hungc23540e2018-11-29 20:42:11 +0800296
297 // Find the associated viewport if exist.
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800298 const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000299 if (displayPort && changes.test(InputReaderConfiguration::Change::DISPLAY_INFO)) {
Arpit Singhed6c3de2023-04-05 19:24:37 +0000300 mViewport = config.getDisplayViewportByPort(*displayPort);
Arthur Hungc23540e2018-11-29 20:42:11 +0800301 }
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700302
303 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700304 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800305 }
306
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700307 std::list<NotifyArgs> reset(nsecs_t) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700308 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800309 mResetWasCalled = true;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700310 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700311 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800312 }
313
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700314 std::list<NotifyArgs> process(const RawEvent* rawEvent) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700315 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800316 mLastEvent = *rawEvent;
317 mProcessWasCalled = true;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700318 mStateChangedCondition.notify_all();
Yeabkal Wubshite03e8b12023-06-27 16:23:12 -0700319 return mProcessResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800320 }
321
Chris Yea52ade12020-08-27 16:49:20 -0700322 int32_t getKeyCodeState(uint32_t, int32_t keyCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800323 ssize_t index = mKeyCodeStates.indexOfKey(keyCode);
324 return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
325 }
326
Philip Junker4af3b3d2021-12-14 10:36:55 +0100327 int32_t getKeyCodeForKeyLocation(int32_t locationKeyCode) const override {
328 auto it = mKeyCodeMapping.find(locationKeyCode);
329 return it != mKeyCodeMapping.end() ? it->second : locationKeyCode;
330 }
331
Chris Yea52ade12020-08-27 16:49:20 -0700332 int32_t getScanCodeState(uint32_t, int32_t scanCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800333 ssize_t index = mScanCodeStates.indexOfKey(scanCode);
334 return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
335 }
336
Chris Yea52ade12020-08-27 16:49:20 -0700337 int32_t getSwitchState(uint32_t, int32_t switchCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800338 ssize_t index = mSwitchStates.indexOfKey(switchCode);
339 return index >= 0 ? mSwitchStates.valueAt(index) : AKEY_STATE_UNKNOWN;
340 }
341
Chris Yea52ade12020-08-27 16:49:20 -0700342 // Return true if the device has non-empty key layout.
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700343 bool markSupportedKeyCodes(uint32_t, const std::vector<int32_t>& keyCodes,
Chris Yea52ade12020-08-27 16:49:20 -0700344 uint8_t* outFlags) override {
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700345 for (size_t i = 0; i < keyCodes.size(); i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800346 for (size_t j = 0; j < mSupportedKeyCodes.size(); j++) {
347 if (keyCodes[i] == mSupportedKeyCodes[j]) {
348 outFlags[i] = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800349 }
350 }
351 }
Chris Yea52ade12020-08-27 16:49:20 -0700352 bool result = mSupportedKeyCodes.size() > 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800353 return result;
354 }
355
356 virtual int32_t getMetaState() {
357 return mMetaState;
358 }
359
360 virtual void fadePointer() {
361 }
Arthur Hungc23540e2018-11-29 20:42:11 +0800362
363 virtual std::optional<int32_t> getAssociatedDisplay() {
364 if (mViewport) {
365 return std::make_optional(mViewport->displayId);
366 }
367 return std::nullopt;
368 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800369};
370
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700371// --- InputReaderPolicyTest ---
372class InputReaderPolicyTest : public testing::Test {
Siarhei Vishniakoucd7ac1e2018-10-15 13:39:50 -0700373protected:
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700374 sp<FakeInputReaderPolicy> mFakePolicy;
375
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700376 void SetUp() override { mFakePolicy = sp<FakeInputReaderPolicy>::make(); }
Chris Yea52ade12020-08-27 16:49:20 -0700377 void TearDown() override { mFakePolicy.clear(); }
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700378};
379
380/**
381 * Check that empty set of viewports is an acceptable configuration.
382 * Also try to get internal viewport two different ways - by type and by uniqueId.
383 *
384 * There will be confusion if two viewports with empty uniqueId and identical type are present.
385 * Such configuration is not currently allowed.
386 */
387TEST_F(InputReaderPolicyTest, Viewports_GetCleared) {
Siarhei Vishniakoucd7ac1e2018-10-15 13:39:50 -0700388 static const std::string uniqueId = "local:0";
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700389
390 // We didn't add any viewports yet, so there shouldn't be any.
391 std::optional<DisplayViewport> internalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100392 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700393 ASSERT_FALSE(internalViewport);
394
395 // Add an internal viewport, then clear it
Michael Wrighta9cf4192022-12-01 23:46:39 +0000396 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +0000397 /*isActive=*/true, uniqueId, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700398
399 // Check matching by uniqueId
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700400 internalViewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700401 ASSERT_TRUE(internalViewport);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100402 ASSERT_EQ(ViewportType::INTERNAL, internalViewport->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700403
404 // Check matching by viewport type
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100405 internalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700406 ASSERT_TRUE(internalViewport);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700407 ASSERT_EQ(uniqueId, internalViewport->uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700408
409 mFakePolicy->clearViewports();
410 // Make sure nothing is found after clear
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700411 internalViewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700412 ASSERT_FALSE(internalViewport);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100413 internalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700414 ASSERT_FALSE(internalViewport);
415}
416
417TEST_F(InputReaderPolicyTest, Viewports_GetByType) {
418 const std::string internalUniqueId = "local:0";
419 const std::string externalUniqueId = "local:1";
420 const std::string virtualUniqueId1 = "virtual:2";
421 const std::string virtualUniqueId2 = "virtual:3";
422 constexpr int32_t virtualDisplayId1 = 2;
423 constexpr int32_t virtualDisplayId2 = 3;
424
425 // Add an internal viewport
Michael Wrighta9cf4192022-12-01 23:46:39 +0000426 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +0000427 /*isActive=*/true, internalUniqueId, NO_PORT,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000428 ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700429 // Add an external viewport
Michael Wrighta9cf4192022-12-01 23:46:39 +0000430 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +0000431 /*isActive=*/true, externalUniqueId, NO_PORT,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000432 ViewportType::EXTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700433 // Add an virtual viewport
434 mFakePolicy->addDisplayViewport(virtualDisplayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +0000435 ui::ROTATION_0, /*isActive=*/true, virtualUniqueId1, NO_PORT,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000436 ViewportType::VIRTUAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700437 // Add another virtual viewport
438 mFakePolicy->addDisplayViewport(virtualDisplayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +0000439 ui::ROTATION_0, /*isActive=*/true, virtualUniqueId2, NO_PORT,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000440 ViewportType::VIRTUAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700441
442 // Check matching by type for internal
443 std::optional<DisplayViewport> internalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100444 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700445 ASSERT_TRUE(internalViewport);
446 ASSERT_EQ(internalUniqueId, internalViewport->uniqueId);
447
448 // Check matching by type for external
449 std::optional<DisplayViewport> externalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100450 mFakePolicy->getDisplayViewportByType(ViewportType::EXTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700451 ASSERT_TRUE(externalViewport);
452 ASSERT_EQ(externalUniqueId, externalViewport->uniqueId);
453
454 // Check matching by uniqueId for virtual viewport #1
455 std::optional<DisplayViewport> virtualViewport1 =
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700456 mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId1);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700457 ASSERT_TRUE(virtualViewport1);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100458 ASSERT_EQ(ViewportType::VIRTUAL, virtualViewport1->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700459 ASSERT_EQ(virtualUniqueId1, virtualViewport1->uniqueId);
460 ASSERT_EQ(virtualDisplayId1, virtualViewport1->displayId);
461
462 // Check matching by uniqueId for virtual viewport #2
463 std::optional<DisplayViewport> virtualViewport2 =
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700464 mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId2);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700465 ASSERT_TRUE(virtualViewport2);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100466 ASSERT_EQ(ViewportType::VIRTUAL, virtualViewport2->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700467 ASSERT_EQ(virtualUniqueId2, virtualViewport2->uniqueId);
468 ASSERT_EQ(virtualDisplayId2, virtualViewport2->displayId);
469}
470
471
472/**
473 * We can have 2 viewports of the same kind. We can distinguish them by uniqueId, and confirm
474 * that lookup works by checking display id.
475 * Check that 2 viewports of each kind is possible, for all existing viewport types.
476 */
477TEST_F(InputReaderPolicyTest, Viewports_TwoOfSameType) {
478 const std::string uniqueId1 = "uniqueId1";
479 const std::string uniqueId2 = "uniqueId2";
480 constexpr int32_t displayId1 = 2;
481 constexpr int32_t displayId2 = 3;
482
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100483 std::vector<ViewportType> types = {ViewportType::INTERNAL, ViewportType::EXTERNAL,
484 ViewportType::VIRTUAL};
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700485 for (const ViewportType& type : types) {
486 mFakePolicy->clearViewports();
487 // Add a viewport
Michael Wrighta9cf4192022-12-01 23:46:39 +0000488 mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +0000489 /*isActive=*/true, uniqueId1, NO_PORT, type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700490 // Add another viewport
Michael Wrighta9cf4192022-12-01 23:46:39 +0000491 mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +0000492 /*isActive=*/true, uniqueId2, NO_PORT, type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700493
494 // Check that correct display viewport was returned by comparing the display IDs.
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700495 std::optional<DisplayViewport> viewport1 =
496 mFakePolicy->getDisplayViewportByUniqueId(uniqueId1);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700497 ASSERT_TRUE(viewport1);
498 ASSERT_EQ(displayId1, viewport1->displayId);
499 ASSERT_EQ(type, viewport1->type);
500
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700501 std::optional<DisplayViewport> viewport2 =
502 mFakePolicy->getDisplayViewportByUniqueId(uniqueId2);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700503 ASSERT_TRUE(viewport2);
504 ASSERT_EQ(displayId2, viewport2->displayId);
505 ASSERT_EQ(type, viewport2->type);
506
507 // When there are multiple viewports of the same kind, and uniqueId is not specified
508 // in the call to getDisplayViewport, then that situation is not supported.
509 // The viewports can be stored in any order, so we cannot rely on the order, since that
510 // is just implementation detail.
511 // However, we can check that it still returns *a* viewport, we just cannot assert
512 // which one specifically is returned.
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700513 std::optional<DisplayViewport> someViewport = mFakePolicy->getDisplayViewportByType(type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700514 ASSERT_TRUE(someViewport);
515 }
516}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800517
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700518/**
Michael Wrightdde67b82020-10-27 16:09:22 +0000519 * When we have multiple internal displays make sure we always return the default display when
520 * querying by type.
521 */
522TEST_F(InputReaderPolicyTest, Viewports_ByTypeReturnsDefaultForInternal) {
523 const std::string uniqueId1 = "uniqueId1";
524 const std::string uniqueId2 = "uniqueId2";
525 constexpr int32_t nonDefaultDisplayId = 2;
526 static_assert(nonDefaultDisplayId != ADISPLAY_ID_DEFAULT,
527 "Test display ID should not be ADISPLAY_ID_DEFAULT");
528
529 // Add the default display first and ensure it gets returned.
530 mFakePolicy->clearViewports();
531 mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +0000532 ui::ROTATION_0, /*isActive=*/true, uniqueId1, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000533 ViewportType::INTERNAL);
534 mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +0000535 ui::ROTATION_0, /*isActive=*/true, uniqueId2, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000536 ViewportType::INTERNAL);
537
538 std::optional<DisplayViewport> viewport =
539 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
540 ASSERT_TRUE(viewport);
541 ASSERT_EQ(ADISPLAY_ID_DEFAULT, viewport->displayId);
542 ASSERT_EQ(ViewportType::INTERNAL, viewport->type);
543
544 // Add the default display second to make sure order doesn't matter.
545 mFakePolicy->clearViewports();
546 mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +0000547 ui::ROTATION_0, /*isActive=*/true, uniqueId2, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000548 ViewportType::INTERNAL);
549 mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +0000550 ui::ROTATION_0, /*isActive=*/true, uniqueId1, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000551 ViewportType::INTERNAL);
552
553 viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
554 ASSERT_TRUE(viewport);
555 ASSERT_EQ(ADISPLAY_ID_DEFAULT, viewport->displayId);
556 ASSERT_EQ(ViewportType::INTERNAL, viewport->type);
557}
558
559/**
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700560 * Check getDisplayViewportByPort
561 */
562TEST_F(InputReaderPolicyTest, Viewports_GetByPort) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100563 constexpr ViewportType type = ViewportType::EXTERNAL;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700564 const std::string uniqueId1 = "uniqueId1";
565 const std::string uniqueId2 = "uniqueId2";
566 constexpr int32_t displayId1 = 1;
567 constexpr int32_t displayId2 = 2;
568 const uint8_t hdmi1 = 0;
569 const uint8_t hdmi2 = 1;
570 const uint8_t hdmi3 = 2;
571
572 mFakePolicy->clearViewports();
573 // Add a viewport that's associated with some display port that's not of interest.
Michael Wrighta9cf4192022-12-01 23:46:39 +0000574 mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +0000575 /*isActive=*/true, uniqueId1, hdmi3, type);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700576 // Add another viewport, connected to HDMI1 port
Michael Wrighta9cf4192022-12-01 23:46:39 +0000577 mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +0000578 /*isActive=*/true, uniqueId2, hdmi1, type);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700579
580 // Check that correct display viewport was returned by comparing the display ports.
581 std::optional<DisplayViewport> hdmi1Viewport = mFakePolicy->getDisplayViewportByPort(hdmi1);
582 ASSERT_TRUE(hdmi1Viewport);
583 ASSERT_EQ(displayId2, hdmi1Viewport->displayId);
584 ASSERT_EQ(uniqueId2, hdmi1Viewport->uniqueId);
585
586 // Check that we can still get the same viewport using the uniqueId
587 hdmi1Viewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId2);
588 ASSERT_TRUE(hdmi1Viewport);
589 ASSERT_EQ(displayId2, hdmi1Viewport->displayId);
590 ASSERT_EQ(uniqueId2, hdmi1Viewport->uniqueId);
591 ASSERT_EQ(type, hdmi1Viewport->type);
592
593 // Check that we cannot find a port with "HDMI2", because we never added one
594 std::optional<DisplayViewport> hdmi2Viewport = mFakePolicy->getDisplayViewportByPort(hdmi2);
595 ASSERT_FALSE(hdmi2Viewport);
596}
597
Michael Wrightd02c5b62014-02-10 15:10:22 -0800598// --- InputReaderTest ---
599
600class InputReaderTest : public testing::Test {
601protected:
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700602 std::unique_ptr<TestInputListener> mFakeListener;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800603 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -0700604 std::shared_ptr<FakeEventHub> mFakeEventHub;
Prabir Pradhan28efc192019-11-05 01:10:04 +0000605 std::unique_ptr<InstrumentedInputReader> mReader;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800606
Chris Yea52ade12020-08-27 16:49:20 -0700607 void SetUp() override {
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -0700608 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700609 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700610 mFakeListener = std::make_unique<TestInputListener>();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800611
Prabir Pradhan28efc192019-11-05 01:10:04 +0000612 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700613 *mFakeListener);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800614 }
615
Chris Yea52ade12020-08-27 16:49:20 -0700616 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700617 mFakeListener.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800618 mFakePolicy.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800619 }
620
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700621 void addDevice(int32_t eventHubId, const std::string& name,
622 ftl::Flags<InputDeviceClass> classes, const PropertyMap* configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800623 mFakeEventHub->addDevice(eventHubId, name, classes);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800624
625 if (configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800626 mFakeEventHub->addConfigurationMap(eventHubId, configuration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800627 }
628 mFakeEventHub->finishDeviceScan();
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000629 mReader->loopOnce();
630 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700631 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
Prabir Pradhane3da4bb2023-04-05 23:51:23 +0000632 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyInputDevicesChangedWasCalled());
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700633 ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800634 }
635
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800636 void disableDevice(int32_t deviceId) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700637 mFakePolicy->addDisabledDevice(deviceId);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000638 mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::ENABLED_STATE);
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700639 }
640
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800641 void enableDevice(int32_t deviceId) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700642 mFakePolicy->removeDisabledDevice(deviceId);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000643 mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::ENABLED_STATE);
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700644 }
645
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800646 FakeInputMapper& addDeviceWithFakeInputMapper(int32_t deviceId, int32_t eventHubId,
Chris Ye1b0c7342020-07-28 21:57:03 -0700647 const std::string& name,
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700648 ftl::Flags<InputDeviceClass> classes,
649 uint32_t sources,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800650 const PropertyMap* configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800651 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, name);
Arpit Singh8e6fb252023-04-06 11:49:17 +0000652 FakeInputMapper& mapper =
653 device->addMapper<FakeInputMapper>(eventHubId,
654 mFakePolicy->getReaderConfiguration(), sources);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800655 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800656 addDevice(eventHubId, name, classes, configuration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800657 return mapper;
658 }
659};
660
Chris Ye98d3f532020-10-01 21:48:59 -0700661TEST_F(InputReaderTest, PolicyGetInputDevices) {
662 ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr));
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700663 ASSERT_NO_FATAL_FAILURE(addDevice(2, "ignored", ftl::Flags<InputDeviceClass>(0),
Chris Ye98d3f532020-10-01 21:48:59 -0700664 nullptr)); // no classes so device will be ignored
Michael Wrightd02c5b62014-02-10 15:10:22 -0800665
666 // Should also have received a notification describing the new input devices.
Chris Ye98d3f532020-10-01 21:48:59 -0700667 const std::vector<InputDeviceInfo>& inputDevices = mFakePolicy->getInputDevices();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800668 ASSERT_EQ(1U, inputDevices.size());
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800669 ASSERT_EQ(END_RESERVED_ID + 1, inputDevices[0].getId());
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100670 ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800671 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
672 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
Siarhei Vishniakou1983a712021-06-04 19:27:09 +0000673 ASSERT_EQ(0U, inputDevices[0].getMotionRanges().size());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800674}
675
Vaibhav Devmurari5fc7d852023-03-17 18:43:33 +0000676TEST_F(InputReaderTest, InputDeviceRecreatedOnSysfsNodeChanged) {
677 ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr));
678 mFakeEventHub->setSysfsRootPath(1, "xyz");
679
680 // Should also have received a notification describing the new input device.
681 ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
682 InputDeviceInfo inputDevice = mFakePolicy->getInputDevices()[0];
683 ASSERT_EQ(0U, inputDevice.getLights().size());
684
685 RawLightInfo infoMonolight = {.id = 123,
686 .name = "mono_keyboard_backlight",
687 .maxBrightness = 255,
688 .flags = InputLightClass::BRIGHTNESS,
689 .path = ""};
690 mFakeEventHub->addRawLightInfo(/*rawId=*/123, std::move(infoMonolight));
691 mReader->sysfsNodeChanged("xyz");
692 mReader->loopOnce();
693
694 // Should also have received a notification describing the new recreated input device.
695 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
696 inputDevice = mFakePolicy->getInputDevices()[0];
697 ASSERT_EQ(1U, inputDevice.getLights().size());
698}
699
Chris Yee7310032020-09-22 15:36:28 -0700700TEST_F(InputReaderTest, GetMergedInputDevices) {
701 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
702 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
703 // Add two subdevices to device
704 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
705 // Must add at least one mapper or the device will be ignored!
Arpit Singh8e6fb252023-04-06 11:49:17 +0000706 device->addMapper<FakeInputMapper>(eventHubIds[0], mFakePolicy->getReaderConfiguration(),
707 AINPUT_SOURCE_KEYBOARD);
708 device->addMapper<FakeInputMapper>(eventHubIds[1], mFakePolicy->getReaderConfiguration(),
709 AINPUT_SOURCE_KEYBOARD);
Chris Yee7310032020-09-22 15:36:28 -0700710
711 // Push same device instance for next device to be added, so they'll have same identifier.
712 mReader->pushNextDevice(device);
713 mReader->pushNextDevice(device);
714 ASSERT_NO_FATAL_FAILURE(
715 addDevice(eventHubIds[0], "fake1", InputDeviceClass::KEYBOARD, nullptr));
716 ASSERT_NO_FATAL_FAILURE(
717 addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
718
719 // Two devices will be merged to one input device as they have same identifier
Siarhei Vishniakou1983a712021-06-04 19:27:09 +0000720 ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
Chris Yee7310032020-09-22 15:36:28 -0700721}
722
Chris Yee14523a2020-12-19 13:46:00 -0800723TEST_F(InputReaderTest, GetMergedInputDevicesEnabled) {
724 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
725 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
726 // Add two subdevices to device
727 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
728 // Must add at least one mapper or the device will be ignored!
Arpit Singh8e6fb252023-04-06 11:49:17 +0000729 device->addMapper<FakeInputMapper>(eventHubIds[0], mFakePolicy->getReaderConfiguration(),
730 AINPUT_SOURCE_KEYBOARD);
731 device->addMapper<FakeInputMapper>(eventHubIds[1], mFakePolicy->getReaderConfiguration(),
732 AINPUT_SOURCE_KEYBOARD);
Chris Yee14523a2020-12-19 13:46:00 -0800733
734 // Push same device instance for next device to be added, so they'll have same identifier.
735 mReader->pushNextDevice(device);
736 mReader->pushNextDevice(device);
737 // Sensor device is initially disabled
738 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1",
739 InputDeviceClass::KEYBOARD | InputDeviceClass::SENSOR,
740 nullptr));
741 // Device is disabled because the only sub device is a sensor device and disabled initially.
742 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
743 ASSERT_FALSE(device->isEnabled());
744 ASSERT_NO_FATAL_FAILURE(
745 addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
746 // The merged device is enabled if any sub device is enabled
747 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
748 ASSERT_TRUE(device->isEnabled());
749}
750
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700751TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800752 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700753 constexpr ftl::Flags<InputDeviceClass> deviceClass(InputDeviceClass::KEYBOARD);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800754 constexpr int32_t eventHubId = 1;
755 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700756 // Must add at least one mapper or the device will be ignored!
Arpit Singh8e6fb252023-04-06 11:49:17 +0000757 device->addMapper<FakeInputMapper>(eventHubId, mFakePolicy->getReaderConfiguration(),
758 AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800759 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800760 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700761
Yi Kong9b14ac62018-07-17 13:48:38 -0700762 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700763
764 NotifyDeviceResetArgs resetArgs;
765 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700766 ASSERT_EQ(deviceId, resetArgs.deviceId);
767
768 ASSERT_EQ(device->isEnabled(), true);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800769 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000770 mReader->loopOnce();
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700771
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700772 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700773 ASSERT_EQ(deviceId, resetArgs.deviceId);
774 ASSERT_EQ(device->isEnabled(), false);
775
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800776 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000777 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700778 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
779 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasNotCalled());
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700780 ASSERT_EQ(device->isEnabled(), false);
781
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800782 enableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000783 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700784 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700785 ASSERT_EQ(deviceId, resetArgs.deviceId);
786 ASSERT_EQ(device->isEnabled(), true);
787}
788
Michael Wrightd02c5b62014-02-10 15:10:22 -0800789TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800790 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700791 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800792 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800793 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800794 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800795 AINPUT_SOURCE_KEYBOARD, nullptr);
796 mapper.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800797
798 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(0,
799 AINPUT_SOURCE_ANY, AKEYCODE_A))
800 << "Should return unknown when the device id is >= 0 but unknown.";
801
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800802 ASSERT_EQ(AKEY_STATE_UNKNOWN,
803 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
804 << "Should return unknown when the device id is valid but the sources are not "
805 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800806
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800807 ASSERT_EQ(AKEY_STATE_DOWN,
808 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
809 AKEYCODE_A))
810 << "Should return value provided by mapper when device id is valid and the device "
811 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800812
813 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(-1,
814 AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
815 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
816
817 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(-1,
818 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
819 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
820}
821
Philip Junker4af3b3d2021-12-14 10:36:55 +0100822TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_ForwardsRequestsToMappers) {
823 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
824 constexpr int32_t eventHubId = 1;
825 FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "keyboard",
826 InputDeviceClass::KEYBOARD,
827 AINPUT_SOURCE_KEYBOARD, nullptr);
828 mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
829
830 ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(0, AKEYCODE_Y))
831 << "Should return unknown when the device with the specified id is not found.";
832
833 ASSERT_EQ(AKEYCODE_Z, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
834 << "Should return correct mapping when device id is valid and mapping exists.";
835
836 ASSERT_EQ(AKEYCODE_A, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_A))
837 << "Should return the location key code when device id is valid and there's no "
838 "mapping.";
839}
840
841TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_NoKeyboardMapper) {
842 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
843 constexpr int32_t eventHubId = 1;
844 FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "joystick",
845 InputDeviceClass::JOYSTICK,
846 AINPUT_SOURCE_GAMEPAD, nullptr);
847 mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
848
849 ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
850 << "Should return unknown when the device id is valid but there is no keyboard mapper";
851}
852
Michael Wrightd02c5b62014-02-10 15:10:22 -0800853TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800854 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700855 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800856 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800857 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800858 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800859 AINPUT_SOURCE_KEYBOARD, nullptr);
860 mapper.setScanCodeState(KEY_A, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800861
862 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(0,
863 AINPUT_SOURCE_ANY, KEY_A))
864 << "Should return unknown when the device id is >= 0 but unknown.";
865
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800866 ASSERT_EQ(AKEY_STATE_UNKNOWN,
867 mReader->getScanCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, KEY_A))
868 << "Should return unknown when the device id is valid but the sources are not "
869 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800870
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800871 ASSERT_EQ(AKEY_STATE_DOWN,
872 mReader->getScanCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
873 KEY_A))
874 << "Should return value provided by mapper when device id is valid and the device "
875 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800876
877 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(-1,
878 AINPUT_SOURCE_TRACKBALL, KEY_A))
879 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
880
881 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(-1,
882 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
883 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
884}
885
886TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800887 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700888 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800889 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800890 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800891 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800892 AINPUT_SOURCE_KEYBOARD, nullptr);
893 mapper.setSwitchState(SW_LID, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800894
895 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(0,
896 AINPUT_SOURCE_ANY, SW_LID))
897 << "Should return unknown when the device id is >= 0 but unknown.";
898
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800899 ASSERT_EQ(AKEY_STATE_UNKNOWN,
900 mReader->getSwitchState(deviceId, AINPUT_SOURCE_TRACKBALL, SW_LID))
901 << "Should return unknown when the device id is valid but the sources are not "
902 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800903
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800904 ASSERT_EQ(AKEY_STATE_DOWN,
905 mReader->getSwitchState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
906 SW_LID))
907 << "Should return value provided by mapper when device id is valid and the device "
908 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800909
910 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(-1,
911 AINPUT_SOURCE_TRACKBALL, SW_LID))
912 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
913
914 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(-1,
915 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
916 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
917}
918
919TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800920 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700921 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800922 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800923 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800924 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800925 AINPUT_SOURCE_KEYBOARD, nullptr);
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100926
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800927 mapper.addSupportedKeyCode(AKEYCODE_A);
928 mapper.addSupportedKeyCode(AKEYCODE_B);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800929
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700930 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800931 uint8_t flags[4] = { 0, 0, 0, 1 };
932
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700933 ASSERT_FALSE(mReader->hasKeys(0, AINPUT_SOURCE_ANY, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800934 << "Should return false when device id is >= 0 but unknown.";
935 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
936
937 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700938 ASSERT_FALSE(mReader->hasKeys(deviceId, AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800939 << "Should return false when device id is valid but the sources are not supported by "
940 "the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800941 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
942
943 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700944 ASSERT_TRUE(mReader->hasKeys(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800945 keyCodes, flags))
946 << "Should return value provided by mapper when device id is valid and the device "
947 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800948 ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
949
950 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700951 ASSERT_FALSE(mReader->hasKeys(-1, AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
952 << "Should return false when the device id is < 0 but the sources are not supported by "
953 "any device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800954 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
955
956 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700957 ASSERT_TRUE(
958 mReader->hasKeys(-1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
959 << "Should return value provided by mapper when device id is < 0 and one of the "
960 "devices supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800961 ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
962}
963
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000964TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800965 constexpr int32_t eventHubId = 1;
Chris Ye1b0c7342020-07-28 21:57:03 -0700966 addDevice(eventHubId, "ignored", InputDeviceClass::KEYBOARD, nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800967
968 NotifyConfigurationChangedArgs args;
969
970 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(&args));
971 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
972}
973
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000974TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800975 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700976 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000977 constexpr nsecs_t when = 0;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800978 constexpr int32_t eventHubId = 1;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000979 constexpr nsecs_t readTime = 2;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800980 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800981 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800982 AINPUT_SOURCE_KEYBOARD, nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800983
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000984 mFakeEventHub->enqueueEvent(when, readTime, eventHubId, EV_KEY, KEY_A, 1);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000985 mReader->loopOnce();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800986 ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
987
988 RawEvent event;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800989 ASSERT_NO_FATAL_FAILURE(mapper.assertProcessWasCalled(&event));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000990 ASSERT_EQ(when, event.when);
991 ASSERT_EQ(readTime, event.readTime);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800992 ASSERT_EQ(eventHubId, event.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800993 ASSERT_EQ(EV_KEY, event.type);
994 ASSERT_EQ(KEY_A, event.code);
995 ASSERT_EQ(1, event.value);
996}
997
Garfield Tan1c7bc862020-01-28 13:24:04 -0800998TEST_F(InputReaderTest, DeviceReset_RandomId) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800999 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001000 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001001 constexpr int32_t eventHubId = 1;
1002 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
Prabir Pradhan42611e02018-11-27 14:04:02 -08001003 // Must add at least one mapper or the device will be ignored!
Arpit Singh8e6fb252023-04-06 11:49:17 +00001004 device->addMapper<FakeInputMapper>(eventHubId, mFakePolicy->getReaderConfiguration(),
1005 AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001006 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001007 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Prabir Pradhan42611e02018-11-27 14:04:02 -08001008
1009 NotifyDeviceResetArgs resetArgs;
1010 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001011 int32_t prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08001012
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001013 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001014 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001015 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -08001016 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001017 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08001018
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001019 enableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001020 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001021 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -08001022 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001023 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08001024
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001025 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001026 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001027 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -08001028 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001029 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08001030}
1031
Garfield Tan1c7bc862020-01-28 13:24:04 -08001032TEST_F(InputReaderTest, DeviceReset_GenerateIdWithInputReaderSource) {
1033 constexpr int32_t deviceId = 1;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001034 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Garfield Tan1c7bc862020-01-28 13:24:04 -08001035 constexpr int32_t eventHubId = 1;
1036 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1037 // Must add at least one mapper or the device will be ignored!
Arpit Singh8e6fb252023-04-06 11:49:17 +00001038 device->addMapper<FakeInputMapper>(eventHubId, mFakePolicy->getReaderConfiguration(),
1039 AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001040 mReader->pushNextDevice(device);
Garfield Tan1c7bc862020-01-28 13:24:04 -08001041 ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr));
1042
1043 NotifyDeviceResetArgs resetArgs;
1044 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1045 ASSERT_EQ(IdGenerator::Source::INPUT_READER, IdGenerator::getSource(resetArgs.id));
1046}
1047
Arthur Hungc23540e2018-11-29 20:42:11 +08001048TEST_F(InputReaderTest, Device_CanDispatchToDisplay) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001049 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001050 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001051 constexpr int32_t eventHubId = 1;
Arthur Hungc23540e2018-11-29 20:42:11 +08001052 const char* DEVICE_LOCATION = "USB1";
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001053 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1054 FakeInputMapper& mapper =
Arpit Singh8e6fb252023-04-06 11:49:17 +00001055 device->addMapper<FakeInputMapper>(eventHubId, mFakePolicy->getReaderConfiguration(),
1056 AINPUT_SOURCE_TOUCHSCREEN);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001057 mReader->pushNextDevice(device);
Arthur Hungc23540e2018-11-29 20:42:11 +08001058
1059 const uint8_t hdmi1 = 1;
1060
1061 // Associated touch screen with second display.
1062 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
1063
1064 // Add default and second display.
Prabir Pradhan28efc192019-11-05 01:10:04 +00001065 mFakePolicy->clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00001066 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +00001067 /*isActive=*/true, "local:0", NO_PORT, ViewportType::INTERNAL);
Arthur Hungc23540e2018-11-29 20:42:11 +08001068 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +00001069 ui::ROTATION_0, /*isActive=*/true, "local:1", hdmi1,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001070 ViewportType::EXTERNAL);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00001071 mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::DISPLAY_INFO);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001072 mReader->loopOnce();
Prabir Pradhan28efc192019-11-05 01:10:04 +00001073
1074 // Add the device, and make sure all of the callbacks are triggered.
1075 // The device is added after the input port associations are processed since
1076 // we do not yet support dynamic device-to-display associations.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001077 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001078 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled());
Prabir Pradhan28efc192019-11-05 01:10:04 +00001079 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001080 ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
Arthur Hungc23540e2018-11-29 20:42:11 +08001081
Arthur Hung2c9a3342019-07-23 14:18:59 +08001082 // Device should only dispatch to the specified display.
Arthur Hungc23540e2018-11-29 20:42:11 +08001083 ASSERT_EQ(deviceId, device->getId());
1084 ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, DISPLAY_ID));
1085 ASSERT_TRUE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
Arthur Hung2c9a3342019-07-23 14:18:59 +08001086
1087 // Can't dispatch event from a disabled device.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001088 disableDevice(deviceId);
Prabir Pradhan28efc192019-11-05 01:10:04 +00001089 mReader->loopOnce();
Arthur Hung2c9a3342019-07-23 14:18:59 +08001090 ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
Arthur Hungc23540e2018-11-29 20:42:11 +08001091}
1092
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001093TEST_F(InputReaderTest, WhenEnabledChanges_AllSubdevicesAreUpdated) {
1094 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001095 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001096 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
1097 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1098 // Must add at least one mapper or the device will be ignored!
Arpit Singh8e6fb252023-04-06 11:49:17 +00001099 device->addMapper<FakeInputMapper>(eventHubIds[0], mFakePolicy->getReaderConfiguration(),
1100 AINPUT_SOURCE_KEYBOARD);
1101 device->addMapper<FakeInputMapper>(eventHubIds[1], mFakePolicy->getReaderConfiguration(),
1102 AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001103 mReader->pushNextDevice(device);
1104 mReader->pushNextDevice(device);
1105 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
1106 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
1107
1108 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
1109
1110 NotifyDeviceResetArgs resetArgs;
1111 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1112 ASSERT_EQ(deviceId, resetArgs.deviceId);
1113 ASSERT_TRUE(device->isEnabled());
1114 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1115 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1116
1117 disableDevice(deviceId);
1118 mReader->loopOnce();
1119
1120 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1121 ASSERT_EQ(deviceId, resetArgs.deviceId);
1122 ASSERT_FALSE(device->isEnabled());
1123 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1124 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1125
1126 enableDevice(deviceId);
1127 mReader->loopOnce();
1128
1129 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1130 ASSERT_EQ(deviceId, resetArgs.deviceId);
1131 ASSERT_TRUE(device->isEnabled());
1132 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1133 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1134}
1135
1136TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToSubdeviceMappers) {
1137 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001138 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001139 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
1140 // Add two subdevices to device
1141 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1142 FakeInputMapper& mapperDevice1 =
Arpit Singh8e6fb252023-04-06 11:49:17 +00001143 device->addMapper<FakeInputMapper>(eventHubIds[0],
1144 mFakePolicy->getReaderConfiguration(),
1145 AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001146 FakeInputMapper& mapperDevice2 =
Arpit Singh8e6fb252023-04-06 11:49:17 +00001147 device->addMapper<FakeInputMapper>(eventHubIds[1],
1148 mFakePolicy->getReaderConfiguration(),
1149 AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001150 mReader->pushNextDevice(device);
1151 mReader->pushNextDevice(device);
1152 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
1153 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
1154
1155 mapperDevice1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
1156 mapperDevice2.setKeyCodeState(AKEYCODE_B, AKEY_STATE_DOWN);
1157
1158 ASSERT_EQ(AKEY_STATE_DOWN,
1159 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_A));
1160 ASSERT_EQ(AKEY_STATE_DOWN,
1161 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_B));
1162 ASSERT_EQ(AKEY_STATE_UNKNOWN,
1163 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_C));
1164}
1165
Prabir Pradhan7e186182020-11-10 13:56:45 -08001166TEST_F(InputReaderTest, ChangingPointerCaptureNotifiesInputListener) {
1167 NotifyPointerCaptureChangedArgs args;
1168
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001169 auto request = mFakePolicy->setPointerCapture(true);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00001170 mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::POINTER_CAPTURE);
Prabir Pradhan7e186182020-11-10 13:56:45 -08001171 mReader->loopOnce();
1172 mFakeListener->assertNotifyCaptureWasCalled(&args);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001173 ASSERT_TRUE(args.request.enable) << "Pointer Capture should be enabled.";
1174 ASSERT_EQ(args.request, request) << "Pointer Capture sequence number should match.";
Prabir Pradhan7e186182020-11-10 13:56:45 -08001175
1176 mFakePolicy->setPointerCapture(false);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00001177 mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::POINTER_CAPTURE);
Prabir Pradhan7e186182020-11-10 13:56:45 -08001178 mReader->loopOnce();
1179 mFakeListener->assertNotifyCaptureWasCalled(&args);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001180 ASSERT_FALSE(args.request.enable) << "Pointer Capture should be disabled.";
Prabir Pradhan7e186182020-11-10 13:56:45 -08001181
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001182 // Verify that the Pointer Capture state is not updated when the configuration value
Prabir Pradhan7e186182020-11-10 13:56:45 -08001183 // does not change.
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00001184 mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::POINTER_CAPTURE);
Prabir Pradhan7e186182020-11-10 13:56:45 -08001185 mReader->loopOnce();
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001186 mFakeListener->assertNotifyCaptureWasNotCalled();
Prabir Pradhan7e186182020-11-10 13:56:45 -08001187}
1188
Chris Ye87143712020-11-10 05:05:58 +00001189class FakeVibratorInputMapper : public FakeInputMapper {
1190public:
Arpit Singh8e6fb252023-04-06 11:49:17 +00001191 FakeVibratorInputMapper(InputDeviceContext& deviceContext,
1192 const InputReaderConfiguration& readerConfig, uint32_t sources)
1193 : FakeInputMapper(deviceContext, readerConfig, sources) {}
Chris Ye87143712020-11-10 05:05:58 +00001194
1195 std::vector<int32_t> getVibratorIds() override { return getDeviceContext().getVibratorIds(); }
1196};
1197
1198TEST_F(InputReaderTest, VibratorGetVibratorIds) {
1199 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001200 ftl::Flags<InputDeviceClass> deviceClass =
1201 InputDeviceClass::KEYBOARD | InputDeviceClass::VIBRATOR;
Chris Ye87143712020-11-10 05:05:58 +00001202 constexpr int32_t eventHubId = 1;
1203 const char* DEVICE_LOCATION = "BLUETOOTH";
1204 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1205 FakeVibratorInputMapper& mapper =
Arpit Singh8e6fb252023-04-06 11:49:17 +00001206 device->addMapper<FakeVibratorInputMapper>(eventHubId,
1207 mFakePolicy->getReaderConfiguration(),
1208 AINPUT_SOURCE_KEYBOARD);
Chris Ye87143712020-11-10 05:05:58 +00001209 mReader->pushNextDevice(device);
1210
1211 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1212 ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
1213
1214 ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
1215 ASSERT_EQ(mReader->getVibratorIds(deviceId).size(), 2U);
1216}
1217
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001218// --- FakePeripheralController ---
Kim Low03ea0352020-11-06 12:45:07 -08001219
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001220class FakePeripheralController : public PeripheralControllerInterface {
Chris Yee2b1e5c2021-03-10 22:45:12 -08001221public:
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001222 FakePeripheralController(InputDeviceContext& deviceContext) : mDeviceContext(deviceContext) {}
Chris Yee2b1e5c2021-03-10 22:45:12 -08001223
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001224 ~FakePeripheralController() override {}
Chris Yee2b1e5c2021-03-10 22:45:12 -08001225
Andy Chenf9f1a022022-08-29 20:07:10 -04001226 int32_t getEventHubId() const { return getDeviceContext().getEventHubId(); }
1227
Chris Yee2b1e5c2021-03-10 22:45:12 -08001228 void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {}
1229
1230 void dump(std::string& dump) override {}
1231
1232 std::optional<int32_t> getBatteryCapacity(int32_t batteryId) override {
1233 return getDeviceContext().getBatteryCapacity(batteryId);
Kim Low03ea0352020-11-06 12:45:07 -08001234 }
1235
Chris Yee2b1e5c2021-03-10 22:45:12 -08001236 std::optional<int32_t> getBatteryStatus(int32_t batteryId) override {
1237 return getDeviceContext().getBatteryStatus(batteryId);
Kim Low03ea0352020-11-06 12:45:07 -08001238 }
Chris Ye3fdbfef2021-01-06 18:45:18 -08001239
1240 bool setLightColor(int32_t lightId, int32_t color) override {
1241 getDeviceContext().setLightBrightness(lightId, color >> 24);
1242 return true;
1243 }
1244
1245 std::optional<int32_t> getLightColor(int32_t lightId) override {
1246 std::optional<int32_t> result = getDeviceContext().getLightBrightness(lightId);
1247 if (!result.has_value()) {
1248 return std::nullopt;
1249 }
1250 return result.value() << 24;
1251 }
Chris Yee2b1e5c2021-03-10 22:45:12 -08001252
1253 bool setLightPlayerId(int32_t lightId, int32_t playerId) override { return true; }
1254
1255 std::optional<int32_t> getLightPlayerId(int32_t lightId) override { return std::nullopt; }
1256
1257private:
1258 InputDeviceContext& mDeviceContext;
1259 inline int32_t getDeviceId() { return mDeviceContext.getId(); }
1260 inline InputDeviceContext& getDeviceContext() { return mDeviceContext; }
Andy Chenf9f1a022022-08-29 20:07:10 -04001261 inline InputDeviceContext& getDeviceContext() const { return mDeviceContext; }
Chris Ye3fdbfef2021-01-06 18:45:18 -08001262};
1263
Chris Yee2b1e5c2021-03-10 22:45:12 -08001264TEST_F(InputReaderTest, BatteryGetCapacity) {
1265 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001266 ftl::Flags<InputDeviceClass> deviceClass =
1267 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
Chris Yee2b1e5c2021-03-10 22:45:12 -08001268 constexpr int32_t eventHubId = 1;
1269 const char* DEVICE_LOCATION = "BLUETOOTH";
1270 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001271 FakePeripheralController& controller =
1272 device->addController<FakePeripheralController>(eventHubId);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001273 mReader->pushNextDevice(device);
1274
1275 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1276
Harry Cuttsa5b71292022-11-28 12:56:17 +00001277 ASSERT_EQ(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY),
1278 FakeEventHub::BATTERY_CAPACITY);
1279 ASSERT_EQ(mReader->getBatteryCapacity(deviceId), FakeEventHub::BATTERY_CAPACITY);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001280}
1281
1282TEST_F(InputReaderTest, BatteryGetStatus) {
1283 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001284 ftl::Flags<InputDeviceClass> deviceClass =
1285 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
Chris Yee2b1e5c2021-03-10 22:45:12 -08001286 constexpr int32_t eventHubId = 1;
1287 const char* DEVICE_LOCATION = "BLUETOOTH";
1288 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001289 FakePeripheralController& controller =
1290 device->addController<FakePeripheralController>(eventHubId);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001291 mReader->pushNextDevice(device);
1292
1293 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1294
Harry Cuttsa5b71292022-11-28 12:56:17 +00001295 ASSERT_EQ(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY),
1296 FakeEventHub::BATTERY_STATUS);
1297 ASSERT_EQ(mReader->getBatteryStatus(deviceId), FakeEventHub::BATTERY_STATUS);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001298}
1299
Prabir Pradhane287ecd2022-09-07 21:18:05 +00001300TEST_F(InputReaderTest, BatteryGetDevicePath) {
1301 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1302 ftl::Flags<InputDeviceClass> deviceClass =
1303 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
1304 constexpr int32_t eventHubId = 1;
1305 const char* DEVICE_LOCATION = "BLUETOOTH";
1306 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1307 device->addController<FakePeripheralController>(eventHubId);
1308 mReader->pushNextDevice(device);
1309
1310 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1311
Harry Cuttsa5b71292022-11-28 12:56:17 +00001312 ASSERT_EQ(mReader->getBatteryDevicePath(deviceId), FakeEventHub::BATTERY_DEVPATH);
Prabir Pradhane287ecd2022-09-07 21:18:05 +00001313}
1314
Chris Ye3fdbfef2021-01-06 18:45:18 -08001315TEST_F(InputReaderTest, LightGetColor) {
1316 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001317 ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD | InputDeviceClass::LIGHT;
Chris Ye3fdbfef2021-01-06 18:45:18 -08001318 constexpr int32_t eventHubId = 1;
1319 const char* DEVICE_LOCATION = "BLUETOOTH";
1320 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001321 FakePeripheralController& controller =
1322 device->addController<FakePeripheralController>(eventHubId);
Chris Ye3fdbfef2021-01-06 18:45:18 -08001323 mReader->pushNextDevice(device);
1324 RawLightInfo info = {.id = 1,
1325 .name = "Mono",
1326 .maxBrightness = 255,
1327 .flags = InputLightClass::BRIGHTNESS,
1328 .path = ""};
Harry Cutts33476232023-01-30 19:57:29 +00001329 mFakeEventHub->addRawLightInfo(/*rawId=*/1, std::move(info));
1330 mFakeEventHub->fakeLightBrightness(/*rawId=*/1, 0x55);
Chris Ye3fdbfef2021-01-06 18:45:18 -08001331
1332 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Chris Ye3fdbfef2021-01-06 18:45:18 -08001333
Harry Cutts33476232023-01-30 19:57:29 +00001334 ASSERT_TRUE(controller.setLightColor(/*lightId=*/1, LIGHT_BRIGHTNESS));
1335 ASSERT_EQ(controller.getLightColor(/*lightId=*/1), LIGHT_BRIGHTNESS);
1336 ASSERT_TRUE(mReader->setLightColor(deviceId, /*lightId=*/1, LIGHT_BRIGHTNESS));
1337 ASSERT_EQ(mReader->getLightColor(deviceId, /*lightId=*/1), LIGHT_BRIGHTNESS);
Chris Ye3fdbfef2021-01-06 18:45:18 -08001338}
1339
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001340// --- InputReaderIntegrationTest ---
1341
1342// These tests create and interact with the InputReader only through its interface.
1343// The InputReader is started during SetUp(), which starts its processing in its own
1344// thread. The tests use linux uinput to emulate input devices.
1345// NOTE: Interacting with the physical device while these tests are running may cause
1346// the tests to fail.
1347class InputReaderIntegrationTest : public testing::Test {
1348protected:
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001349 std::unique_ptr<TestInputListener> mTestListener;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001350 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001351 std::unique_ptr<InputReaderInterface> mReader;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001352
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00001353 std::shared_ptr<FakePointerController> mFakePointerController;
1354
Chris Yea52ade12020-08-27 16:49:20 -07001355 void SetUp() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001356#if !defined(__ANDROID__)
1357 GTEST_SKIP();
1358#endif
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07001359 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00001360 mFakePointerController = std::make_shared<FakePointerController>();
1361 mFakePolicy->setPointerController(mFakePointerController);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001362
Arpit Singh440bf652023-08-09 09:23:43 +00001363 setupInputReader();
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001364 }
1365
Chris Yea52ade12020-08-27 16:49:20 -07001366 void TearDown() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001367#if !defined(__ANDROID__)
1368 return;
1369#endif
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001370 ASSERT_EQ(mReader->stop(), OK);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001371 mReader.reset();
1372 mTestListener.reset();
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001373 mFakePolicy.clear();
1374 }
Prabir Pradhanda20b172022-09-26 17:01:18 +00001375
1376 std::optional<InputDeviceInfo> findDeviceByName(const std::string& name) {
1377 const std::vector<InputDeviceInfo> inputDevices = mFakePolicy->getInputDevices();
1378 const auto& it = std::find_if(inputDevices.begin(), inputDevices.end(),
1379 [&name](const InputDeviceInfo& info) {
1380 return info.getIdentifier().name == name;
1381 });
1382 return it != inputDevices.end() ? std::make_optional(*it) : std::nullopt;
1383 }
Arpit Singh440bf652023-08-09 09:23:43 +00001384
1385 void setupInputReader() {
1386 mTestListener = std::make_unique<TestInputListener>(/*eventHappenedTimeout=*/2000ms,
1387 /*eventDidNotHappenTimeout=*/30ms);
1388
1389 mReader = std::make_unique<InputReader>(std::make_shared<EventHub>(), mFakePolicy,
1390 *mTestListener);
1391 ASSERT_EQ(mReader->start(), OK);
1392
1393 // Since this test is run on a real device, all the input devices connected
1394 // to the test device will show up in mReader. We wait for those input devices to
1395 // show up before beginning the tests.
1396 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1397 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyInputDevicesChangedWasCalled());
1398 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1399 }
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001400};
1401
1402TEST_F(InputReaderIntegrationTest, TestInvalidDevice) {
1403 // An invalid input device that is only used for this test.
1404 class InvalidUinputDevice : public UinputDevice {
1405 public:
Harry Cutts33476232023-01-30 19:57:29 +00001406 InvalidUinputDevice() : UinputDevice("Invalid Device", /*productId=*/99) {}
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001407
1408 private:
1409 void configureDevice(int fd, uinput_user_dev* device) override {}
1410 };
1411
1412 const size_t numDevices = mFakePolicy->getInputDevices().size();
1413
1414 // UinputDevice does not set any event or key bits, so InputReader should not
1415 // consider it as a valid device.
1416 std::unique_ptr<UinputDevice> invalidDevice = createUinputDevice<InvalidUinputDevice>();
1417 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
1418 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
1419 ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
1420
1421 invalidDevice.reset();
1422 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
1423 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
1424 ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
1425}
1426
1427TEST_F(InputReaderIntegrationTest, AddNewDevice) {
1428 const size_t initialNumDevices = mFakePolicy->getInputDevices().size();
1429
1430 std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
1431 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1432 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1433 ASSERT_EQ(initialNumDevices + 1, mFakePolicy->getInputDevices().size());
1434
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001435 const auto device = findDeviceByName(keyboard->getName());
1436 ASSERT_TRUE(device.has_value());
1437 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, device->getKeyboardType());
1438 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources());
1439 ASSERT_EQ(0U, device->getMotionRanges().size());
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001440
1441 keyboard.reset();
1442 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1443 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1444 ASSERT_EQ(initialNumDevices, mFakePolicy->getInputDevices().size());
1445}
1446
1447TEST_F(InputReaderIntegrationTest, SendsEventsToInputListener) {
1448 std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
1449 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1450
1451 NotifyConfigurationChangedArgs configChangedArgs;
1452 ASSERT_NO_FATAL_FAILURE(
1453 mTestListener->assertNotifyConfigurationChangedWasCalled(&configChangedArgs));
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001454 int32_t prevId = configChangedArgs.id;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001455 nsecs_t prevTimestamp = configChangedArgs.eventTime;
1456
1457 NotifyKeyArgs keyArgs;
1458 keyboard->pressAndReleaseHomeKey();
1459 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
1460 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
Garfield Tan1c7bc862020-01-28 13:24:04 -08001461 ASSERT_NE(prevId, keyArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001462 prevId = keyArgs.id;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001463 ASSERT_LE(prevTimestamp, keyArgs.eventTime);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001464 ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001465 prevTimestamp = keyArgs.eventTime;
1466
1467 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
1468 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
Garfield Tan1c7bc862020-01-28 13:24:04 -08001469 ASSERT_NE(prevId, keyArgs.id);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001470 ASSERT_LE(prevTimestamp, keyArgs.eventTime);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001471 ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001472}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001473
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001474TEST_F(InputReaderIntegrationTest, ExternalStylusesButtons) {
1475 std::unique_ptr<UinputExternalStylus> stylus = createUinputDevice<UinputExternalStylus>();
1476 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1477
1478 const auto device = findDeviceByName(stylus->getName());
1479 ASSERT_TRUE(device.has_value());
1480
Prabir Pradhana3621852022-10-14 18:57:23 +00001481 // An external stylus with buttons should also be recognized as a keyboard.
1482 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_STYLUS, device->getSources())
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001483 << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
1484 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, device->getKeyboardType());
1485
1486 const auto DOWN =
1487 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD));
1488 const auto UP = AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD));
1489
1490 stylus->pressAndReleaseKey(BTN_STYLUS);
1491 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1492 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1493 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1494 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1495
1496 stylus->pressAndReleaseKey(BTN_STYLUS2);
1497 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1498 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_SECONDARY))));
1499 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1500 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_SECONDARY))));
1501
1502 stylus->pressAndReleaseKey(BTN_STYLUS3);
1503 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1504 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
1505 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1506 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
1507}
1508
Prabir Pradhan3c28b942023-08-18 20:02:01 +00001509TEST_F(InputReaderIntegrationTest, KeyboardWithStylusButtons) {
1510 std::unique_ptr<UinputKeyboard> keyboard =
1511 createUinputDevice<UinputKeyboard>("KeyboardWithStylusButtons", /*productId=*/99,
1512 std::initializer_list<int>{KEY_Q, KEY_W, KEY_E,
1513 KEY_R, KEY_T, KEY_Y,
1514 BTN_STYLUS, BTN_STYLUS2,
1515 BTN_STYLUS3});
1516 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1517
1518 const auto device = findDeviceByName(keyboard->getName());
1519 ASSERT_TRUE(device.has_value());
1520
1521 // An alphabetical keyboard that reports stylus buttons should not be recognized as a stylus.
1522 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources())
1523 << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
1524 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, device->getKeyboardType());
1525}
1526
Prabir Pradhan37a819b2023-08-22 23:20:16 +00001527TEST_F(InputReaderIntegrationTest, HidUsageKeyboardIsNotAStylus) {
1528 // Create a Uinput keyboard that simulates a keyboard that can report HID usage codes. The
1529 // hid-input driver reports HID usage codes using the value for EV_MSC MSC_SCAN event.
1530 std::unique_ptr<UinputKeyboardWithHidUsage> keyboard =
1531 createUinputDevice<UinputKeyboardWithHidUsage>(
1532 std::initializer_list<int>{KEY_VOLUMEUP, KEY_VOLUMEDOWN});
1533 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1534
1535 const auto device = findDeviceByName(keyboard->getName());
1536 ASSERT_TRUE(device.has_value());
1537
1538 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources())
1539 << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
1540
1541 // If a device supports reporting HID usage codes, it shouldn't automatically support
1542 // stylus keys.
1543 const std::vector<int> keycodes{AKEYCODE_STYLUS_BUTTON_PRIMARY};
1544 uint8_t outFlags[] = {0};
1545 ASSERT_TRUE(mReader->hasKeys(device->getId(), AINPUT_SOURCE_KEYBOARD, keycodes, outFlags));
1546 ASSERT_EQ(0, outFlags[0]) << "Keyboard should not have stylus button";
1547}
1548
Siarhei Vishniakoua0d2b802020-05-13 14:00:31 -07001549/**
1550 * The Steam controller sends BTN_GEAR_DOWN and BTN_GEAR_UP for the two "paddle" buttons
1551 * on the back. In this test, we make sure that BTN_GEAR_DOWN / BTN_WHEEL and BTN_GEAR_UP
1552 * are passed to the listener.
1553 */
1554static_assert(BTN_GEAR_DOWN == BTN_WHEEL);
1555TEST_F(InputReaderIntegrationTest, SendsGearDownAndUpToInputListener) {
1556 std::unique_ptr<UinputSteamController> controller = createUinputDevice<UinputSteamController>();
1557 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1558 NotifyKeyArgs keyArgs;
1559
1560 controller->pressAndReleaseKey(BTN_GEAR_DOWN);
1561 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
1562 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
1563 ASSERT_EQ(BTN_GEAR_DOWN, keyArgs.scanCode);
1564
1565 controller->pressAndReleaseKey(BTN_GEAR_UP);
1566 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
1567 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
1568 ASSERT_EQ(BTN_GEAR_UP, keyArgs.scanCode);
1569}
1570
Prabir Pradhan484d55a2022-10-14 23:17:16 +00001571// --- TouchIntegrationTest ---
1572
Arpit Singh440bf652023-08-09 09:23:43 +00001573class BaseTouchIntegrationTest : public InputReaderIntegrationTest {
Arthur Hungaab25622020-01-16 11:22:11 +08001574protected:
Arthur Hungaab25622020-01-16 11:22:11 +08001575 const std::string UNIQUE_ID = "local:0";
1576
Chris Yea52ade12020-08-27 16:49:20 -07001577 void SetUp() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001578#if !defined(__ANDROID__)
1579 GTEST_SKIP();
1580#endif
Arthur Hungaab25622020-01-16 11:22:11 +08001581 InputReaderIntegrationTest::SetUp();
1582 // At least add an internal display.
Michael Wrighta9cf4192022-12-01 23:46:39 +00001583 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
1584 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Arthur Hungaab25622020-01-16 11:22:11 +08001585
1586 mDevice = createUinputDevice<UinputTouchScreen>(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT));
1587 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1588 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
Prabir Pradhanda20b172022-09-26 17:01:18 +00001589 const auto info = findDeviceByName(mDevice->getName());
1590 ASSERT_TRUE(info);
1591 mDeviceInfo = *info;
Arthur Hungaab25622020-01-16 11:22:11 +08001592 }
1593
1594 void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
Michael Wrighta9cf4192022-12-01 23:46:39 +00001595 ui::Rotation orientation, const std::string& uniqueId,
Arthur Hungaab25622020-01-16 11:22:11 +08001596 std::optional<uint8_t> physicalPort,
1597 ViewportType viewportType) {
Harry Cutts33476232023-01-30 19:57:29 +00001598 mFakePolicy->addDisplayViewport(displayId, width, height, orientation, /*isActive=*/true,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001599 uniqueId, physicalPort, viewportType);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00001600 mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::DISPLAY_INFO);
Arthur Hungaab25622020-01-16 11:22:11 +08001601 }
1602
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001603 void assertReceivedMotion(int32_t action, const std::vector<Point>& points) {
1604 NotifyMotionArgs args;
1605 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1606 EXPECT_EQ(action, args.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07001607 ASSERT_EQ(points.size(), args.getPointerCount());
1608 for (size_t i = 0; i < args.getPointerCount(); i++) {
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001609 EXPECT_EQ(points[i].x, args.pointerCoords[i].getX());
1610 EXPECT_EQ(points[i].y, args.pointerCoords[i].getY());
1611 }
1612 }
1613
Arthur Hungaab25622020-01-16 11:22:11 +08001614 std::unique_ptr<UinputTouchScreen> mDevice;
Prabir Pradhanda20b172022-09-26 17:01:18 +00001615 InputDeviceInfo mDeviceInfo;
Arthur Hungaab25622020-01-16 11:22:11 +08001616};
1617
Arpit Singh440bf652023-08-09 09:23:43 +00001618enum class TouchIntegrationTestDisplays { DISPLAY_INTERNAL, DISPLAY_INPUT_PORT, DISPLAY_UNIQUE_ID };
1619
1620class TouchIntegrationTest : public BaseTouchIntegrationTest,
1621 public testing::WithParamInterface<TouchIntegrationTestDisplays> {
1622protected:
1623 static constexpr std::optional<uint8_t> DISPLAY_PORT = 0;
1624 const std::string INPUT_PORT = "uinput_touch/input0";
1625
1626 void SetUp() override {
1627#if !defined(__ANDROID__)
1628 GTEST_SKIP();
1629#endif
1630 if (GetParam() == TouchIntegrationTestDisplays::DISPLAY_INTERNAL) {
1631 BaseTouchIntegrationTest::SetUp();
1632 return;
1633 }
1634
1635 // setup policy with a input-port or UniqueId association to the display
1636 bool isInputPortAssociation =
1637 GetParam() == TouchIntegrationTestDisplays::DISPLAY_INPUT_PORT;
1638
1639 mFakePolicy = sp<FakeInputReaderPolicy>::make();
1640 if (isInputPortAssociation) {
1641 mFakePolicy->addInputPortAssociation(INPUT_PORT, DISPLAY_PORT.value());
1642 } else {
1643 mFakePolicy->addInputUniqueIdAssociation(INPUT_PORT, UNIQUE_ID);
1644 }
1645 mFakePointerController = std::make_shared<FakePointerController>();
1646 mFakePolicy->setPointerController(mFakePointerController);
1647
1648 InputReaderIntegrationTest::setupInputReader();
1649
1650 mDevice = createUinputDevice<UinputTouchScreen>(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT),
1651 INPUT_PORT);
1652 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1653
1654 // Add a display linked to a physical port or UniqueId.
1655 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
1656 UNIQUE_ID, isInputPortAssociation ? DISPLAY_PORT : NO_PORT,
1657 ViewportType::INTERNAL);
1658 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1659 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1660 const auto info = findDeviceByName(mDevice->getName());
1661 ASSERT_TRUE(info);
1662 mDeviceInfo = *info;
1663 }
1664};
1665
1666TEST_P(TouchIntegrationTest, MultiTouchDeviceSource) {
Prabir Pradhanf9a41282022-10-25 17:15:50 +00001667 // The UinputTouchScreen is an MT device that supports MT_TOOL_TYPE and also supports stylus
1668 // buttons. It should show up as a touchscreen, stylus, and keyboard (for reporting button
1669 // presses).
1670 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD,
1671 mDeviceInfo.getSources());
1672}
1673
Arpit Singh440bf652023-08-09 09:23:43 +00001674TEST_P(TouchIntegrationTest, InputEvent_ProcessSingleTouch) {
Arthur Hungaab25622020-01-16 11:22:11 +08001675 NotifyMotionArgs args;
1676 const Point centerPoint = mDevice->getCenterPoint();
1677
1678 // ACTION_DOWN
Arthur Hung9ad18942021-06-19 02:04:46 +00001679 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001680 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001681 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001682 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1683 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1684
1685 // ACTION_MOVE
1686 mDevice->sendMove(centerPoint + Point(1, 1));
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001687 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001688 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1689 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1690
1691 // ACTION_UP
1692 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001693 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001694 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1695 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
1696}
1697
Arpit Singh440bf652023-08-09 09:23:43 +00001698TEST_P(TouchIntegrationTest, InputEvent_ProcessMultiTouch) {
Arthur Hungaab25622020-01-16 11:22:11 +08001699 NotifyMotionArgs args;
1700 const Point centerPoint = mDevice->getCenterPoint();
1701
1702 // ACTION_DOWN
Arthur Hung9ad18942021-06-19 02:04:46 +00001703 mDevice->sendSlot(FIRST_SLOT);
1704 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001705 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001706 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001707 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1708 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1709
1710 // ACTION_POINTER_DOWN (Second slot)
1711 const Point secondPoint = centerPoint + Point(100, 100);
1712 mDevice->sendSlot(SECOND_SLOT);
1713 mDevice->sendTrackingId(SECOND_TRACKING_ID);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001714 mDevice->sendDown(secondPoint);
1715 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001716 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001717 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001718
1719 // ACTION_MOVE (Second slot)
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001720 mDevice->sendMove(secondPoint + Point(1, 1));
1721 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001722 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1723 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1724
1725 // ACTION_POINTER_UP (Second slot)
arthurhungcc7f9802020-04-30 17:55:40 +08001726 mDevice->sendPointerUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001727 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001728 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001729 ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001730
1731 // ACTION_UP
1732 mDevice->sendSlot(FIRST_SLOT);
1733 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001734 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001735 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1736 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
1737}
1738
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001739/**
1740 * What happens when a pointer goes up while another pointer moves in the same frame? Are POINTER_UP
1741 * events guaranteed to contain the same data as a preceding MOVE, or can they contain different
1742 * data?
1743 * In this test, we try to send a change in coordinates in Pointer 0 in the same frame as the
1744 * liftoff of Pointer 1. We check that POINTER_UP event is generated first, and the MOVE event
1745 * for Pointer 0 only is generated after.
1746 * Suppose we are only interested in learning the movement of Pointer 0. If we only observe MOVE
1747 * events, we will not miss any information.
1748 * Even though the Pointer 1 up event contains updated Pointer 0 coordinates, there is another MOVE
1749 * event generated afterwards that contains the newest movement of pointer 0.
1750 * This is important for palm rejection. If there is a subsequent InputListener stage that detects
1751 * palms, and wants to cancel Pointer 1, then it is safe to simply drop POINTER_1_UP event without
1752 * losing information about non-palm pointers.
1753 */
Arpit Singh440bf652023-08-09 09:23:43 +00001754TEST_P(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerUp) {
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001755 NotifyMotionArgs args;
1756 const Point centerPoint = mDevice->getCenterPoint();
1757
1758 // ACTION_DOWN
1759 mDevice->sendSlot(FIRST_SLOT);
1760 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1761 mDevice->sendDown(centerPoint);
1762 mDevice->sendSync();
1763 assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
1764
1765 // ACTION_POINTER_DOWN (Second slot)
1766 const Point secondPoint = centerPoint + Point(100, 100);
1767 mDevice->sendSlot(SECOND_SLOT);
1768 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1769 mDevice->sendDown(secondPoint);
1770 mDevice->sendSync();
1771 assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
1772
1773 // ACTION_MOVE (First slot)
1774 mDevice->sendSlot(FIRST_SLOT);
1775 mDevice->sendMove(centerPoint + Point(5, 5));
1776 // ACTION_POINTER_UP (Second slot)
1777 mDevice->sendSlot(SECOND_SLOT);
1778 mDevice->sendPointerUp();
1779 // Send a single sync for the above 2 pointer updates
1780 mDevice->sendSync();
1781
1782 // First, we should get POINTER_UP for the second pointer
1783 assertReceivedMotion(ACTION_POINTER_1_UP,
1784 {/*first pointer */ centerPoint + Point(5, 5),
1785 /*second pointer*/ secondPoint});
1786
1787 // Next, the MOVE event for the first pointer
1788 assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
1789}
1790
1791/**
1792 * Similar scenario as above. The difference is that when the second pointer goes up, it will first
1793 * move, and then it will go up, all in the same frame.
1794 * In this scenario, the movement of the second pointer just prior to liftoff is ignored, and never
1795 * gets sent to the listener.
1796 */
Arpit Singh440bf652023-08-09 09:23:43 +00001797TEST_P(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerMoveAndUp) {
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001798 NotifyMotionArgs args;
1799 const Point centerPoint = mDevice->getCenterPoint();
1800
1801 // ACTION_DOWN
1802 mDevice->sendSlot(FIRST_SLOT);
1803 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1804 mDevice->sendDown(centerPoint);
1805 mDevice->sendSync();
1806 assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
1807
1808 // ACTION_POINTER_DOWN (Second slot)
1809 const Point secondPoint = centerPoint + Point(100, 100);
1810 mDevice->sendSlot(SECOND_SLOT);
1811 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1812 mDevice->sendDown(secondPoint);
1813 mDevice->sendSync();
1814 assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
1815
1816 // ACTION_MOVE (First slot)
1817 mDevice->sendSlot(FIRST_SLOT);
1818 mDevice->sendMove(centerPoint + Point(5, 5));
1819 // ACTION_POINTER_UP (Second slot)
1820 mDevice->sendSlot(SECOND_SLOT);
1821 mDevice->sendMove(secondPoint + Point(6, 6));
1822 mDevice->sendPointerUp();
1823 // Send a single sync for the above 2 pointer updates
1824 mDevice->sendSync();
1825
1826 // First, we should get POINTER_UP for the second pointer
1827 // The movement of the second pointer during the liftoff frame is ignored.
1828 // The coordinates 'secondPoint + Point(6, 6)' are never sent to the listener.
1829 assertReceivedMotion(ACTION_POINTER_1_UP,
1830 {/*first pointer */ centerPoint + Point(5, 5),
1831 /*second pointer*/ secondPoint});
1832
1833 // Next, the MOVE event for the first pointer
1834 assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
1835}
1836
Arpit Singh440bf652023-08-09 09:23:43 +00001837TEST_P(TouchIntegrationTest, InputEvent_ProcessPalm) {
Arthur Hungaab25622020-01-16 11:22:11 +08001838 NotifyMotionArgs args;
1839 const Point centerPoint = mDevice->getCenterPoint();
1840
1841 // ACTION_DOWN
arthurhungcc7f9802020-04-30 17:55:40 +08001842 mDevice->sendSlot(FIRST_SLOT);
1843 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001844 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001845 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001846 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1847 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1848
arthurhungcc7f9802020-04-30 17:55:40 +08001849 // ACTION_POINTER_DOWN (second slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001850 const Point secondPoint = centerPoint + Point(100, 100);
1851 mDevice->sendSlot(SECOND_SLOT);
1852 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1853 mDevice->sendDown(secondPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001854 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001855 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001856 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001857
arthurhungcc7f9802020-04-30 17:55:40 +08001858 // ACTION_MOVE (second slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001859 mDevice->sendMove(secondPoint + Point(1, 1));
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001860 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001861 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1862 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1863
arthurhungcc7f9802020-04-30 17:55:40 +08001864 // Send MT_TOOL_PALM (second slot), which indicates that the touch IC has determined this to be
1865 // a palm event.
1866 // Expect to receive the ACTION_POINTER_UP with cancel flag.
Arthur Hungaab25622020-01-16 11:22:11 +08001867 mDevice->sendToolType(MT_TOOL_PALM);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001868 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001869 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001870 ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
arthurhungcc7f9802020-04-30 17:55:40 +08001871 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, args.flags);
Arthur Hungaab25622020-01-16 11:22:11 +08001872
arthurhungcc7f9802020-04-30 17:55:40 +08001873 // Send up to second slot, expect first slot send moving.
1874 mDevice->sendPointerUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001875 mDevice->sendSync();
arthurhungcc7f9802020-04-30 17:55:40 +08001876 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1877 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001878
arthurhungcc7f9802020-04-30 17:55:40 +08001879 // Send ACTION_UP (first slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001880 mDevice->sendSlot(FIRST_SLOT);
1881 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001882 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001883
arthurhungcc7f9802020-04-30 17:55:40 +08001884 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1885 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001886}
1887
Prabir Pradhanc09ec6d2023-08-14 22:31:43 +00001888/**
1889 * Some drivers historically have reported axis values outside of the range specified in the
1890 * evdev axis info. Ensure we don't crash when this happens. For example, a driver may report a
1891 * pressure value greater than the reported maximum, since it unclear what specific meaning the
1892 * maximum value for pressure has (beyond the maximum value that can be produced by a sensor),
1893 * and no units for pressure (resolution) is specified by the evdev documentation.
1894 */
1895TEST_P(TouchIntegrationTest, AcceptsAxisValuesOutsideReportedRange) {
1896 const Point centerPoint = mDevice->getCenterPoint();
1897
1898 // Down with pressure outside the reported range
1899 mDevice->sendSlot(FIRST_SLOT);
1900 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1901 mDevice->sendDown(centerPoint);
1902 mDevice->sendPressure(UinputTouchScreen::RAW_PRESSURE_MAX + 2);
1903 mDevice->sendSync();
1904 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1905 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
1906
1907 // Move to a point outside the reported range
1908 mDevice->sendMove(Point(DISPLAY_WIDTH, DISPLAY_HEIGHT) + Point(1, 1));
1909 mDevice->sendSync();
1910 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1911 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
1912
1913 // Up
1914 mDevice->sendUp();
1915 mDevice->sendSync();
1916 ASSERT_NO_FATAL_FAILURE(
1917 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
1918}
1919
Arpit Singh440bf652023-08-09 09:23:43 +00001920TEST_P(TouchIntegrationTest, NotifiesPolicyWhenStylusGestureStarted) {
Prabir Pradhanda20b172022-09-26 17:01:18 +00001921 const Point centerPoint = mDevice->getCenterPoint();
1922
1923 // Send down with the pen tool selected. The policy should be notified of the stylus presence.
1924 mDevice->sendSlot(FIRST_SLOT);
1925 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1926 mDevice->sendToolType(MT_TOOL_PEN);
1927 mDevice->sendDown(centerPoint);
1928 mDevice->sendSync();
1929 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1930 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07001931 WithToolType(ToolType::STYLUS))));
Prabir Pradhanda20b172022-09-26 17:01:18 +00001932
1933 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
1934
1935 // Release the stylus touch.
1936 mDevice->sendUp();
1937 mDevice->sendSync();
1938 ASSERT_NO_FATAL_FAILURE(
1939 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
1940
1941 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
1942
1943 // Touch down with the finger, without the pen tool selected. The policy is not notified.
1944 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1945 mDevice->sendToolType(MT_TOOL_FINGER);
1946 mDevice->sendDown(centerPoint);
1947 mDevice->sendSync();
1948 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1949 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07001950 WithToolType(ToolType::FINGER))));
Prabir Pradhanda20b172022-09-26 17:01:18 +00001951
1952 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
1953
1954 mDevice->sendUp();
1955 mDevice->sendSync();
1956 ASSERT_NO_FATAL_FAILURE(
1957 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
1958
1959 // Send a move event with the stylus tool without BTN_TOUCH to generate a hover enter.
1960 // The policy should be notified of the stylus presence.
1961 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1962 mDevice->sendToolType(MT_TOOL_PEN);
1963 mDevice->sendMove(centerPoint);
1964 mDevice->sendSync();
1965 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1966 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07001967 WithToolType(ToolType::STYLUS))));
Prabir Pradhanda20b172022-09-26 17:01:18 +00001968
1969 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
1970}
1971
Arpit Singh440bf652023-08-09 09:23:43 +00001972TEST_P(TouchIntegrationTest, ExternalStylusConnectedDuringTouchGesture) {
Prabir Pradhan85cf63e2023-08-07 21:02:13 +00001973 const Point centerPoint = mDevice->getCenterPoint();
1974
1975 // Down
1976 mDevice->sendSlot(FIRST_SLOT);
1977 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1978 mDevice->sendDown(centerPoint);
1979 mDevice->sendSync();
1980 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1981 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
1982
1983 // Move
1984 mDevice->sendMove(centerPoint + Point(1, 1));
1985 mDevice->sendSync();
1986 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1987 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
1988
1989 // Connecting an external stylus mid-gesture should not interrupt the ongoing gesture stream.
1990 auto externalStylus = createUinputDevice<UinputExternalStylus>();
1991 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1992 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1993 const auto stylusInfo = findDeviceByName(externalStylus->getName());
1994 ASSERT_TRUE(stylusInfo);
Prabir Pradhan85cf63e2023-08-07 21:02:13 +00001995
1996 // Move
1997 mDevice->sendMove(centerPoint + Point(2, 2));
1998 mDevice->sendSync();
1999 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2000 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
2001
2002 // Disconnecting an external stylus mid-gesture should not interrupt the ongoing gesture stream.
2003 externalStylus.reset();
2004 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2005 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2006 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2007
2008 // Up
2009 mDevice->sendUp();
2010 mDevice->sendSync();
2011 ASSERT_NO_FATAL_FAILURE(
2012 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
2013
2014 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2015}
2016
Arpit Singh440bf652023-08-09 09:23:43 +00002017INSTANTIATE_TEST_SUITE_P(TouchIntegrationTestDisplayVariants, TouchIntegrationTest,
2018 testing::Values(TouchIntegrationTestDisplays::DISPLAY_INTERNAL,
2019 TouchIntegrationTestDisplays::DISPLAY_INPUT_PORT,
2020 TouchIntegrationTestDisplays::DISPLAY_UNIQUE_ID));
2021
Prabir Pradhan124ea442022-10-28 20:27:44 +00002022// --- StylusButtonIntegrationTest ---
Prabir Pradhane1a41a82022-10-14 18:06:50 +00002023
Prabir Pradhan124ea442022-10-28 20:27:44 +00002024// Verify the behavior of button presses reported by various kinds of styluses, including buttons
2025// reported by the touchscreen's device, by a fused external stylus, and by an un-fused external
2026// stylus.
2027template <typename UinputStylusDevice>
Arpit Singh440bf652023-08-09 09:23:43 +00002028class StylusButtonIntegrationTest : public BaseTouchIntegrationTest {
Prabir Pradhan124ea442022-10-28 20:27:44 +00002029protected:
2030 void SetUp() override {
2031#if !defined(__ANDROID__)
2032 GTEST_SKIP();
2033#endif
Arpit Singh440bf652023-08-09 09:23:43 +00002034 BaseTouchIntegrationTest::SetUp();
Prabir Pradhan124ea442022-10-28 20:27:44 +00002035 mTouchscreen = mDevice.get();
2036 mTouchscreenInfo = mDeviceInfo;
2037
2038 setUpStylusDevice();
2039 }
2040
2041 UinputStylusDevice* mStylus{nullptr};
2042 InputDeviceInfo mStylusInfo{};
2043
2044 UinputTouchScreen* mTouchscreen{nullptr};
2045 InputDeviceInfo mTouchscreenInfo{};
2046
2047private:
2048 // When we are attempting to test stylus button events that are sent from the touchscreen,
2049 // use the same Uinput device for the touchscreen and the stylus.
2050 template <typename T = UinputStylusDevice>
2051 std::enable_if_t<std::is_same_v<UinputTouchScreen, T>, void> setUpStylusDevice() {
2052 mStylus = mDevice.get();
2053 mStylusInfo = mDeviceInfo;
2054 }
2055
2056 // When we are attempting to stylus buttons from an external stylus being merged with touches
2057 // from a touchscreen, create a new Uinput device through which stylus buttons can be injected.
2058 template <typename T = UinputStylusDevice>
2059 std::enable_if_t<!std::is_same_v<UinputTouchScreen, T>, void> setUpStylusDevice() {
2060 mStylusDeviceLifecycleTracker = createUinputDevice<T>();
2061 mStylus = mStylusDeviceLifecycleTracker.get();
2062 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2063 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2064 const auto info = findDeviceByName(mStylus->getName());
2065 ASSERT_TRUE(info);
2066 mStylusInfo = *info;
2067 }
2068
2069 std::unique_ptr<UinputStylusDevice> mStylusDeviceLifecycleTracker{};
2070
2071 // Hide the base class's device to expose it with a different name for readability.
Arpit Singh440bf652023-08-09 09:23:43 +00002072 using BaseTouchIntegrationTest::mDevice;
2073 using BaseTouchIntegrationTest::mDeviceInfo;
Prabir Pradhan124ea442022-10-28 20:27:44 +00002074};
2075
2076using StylusButtonIntegrationTestTypes =
2077 ::testing::Types<UinputTouchScreen, UinputExternalStylus, UinputExternalStylusWithPressure>;
2078TYPED_TEST_SUITE(StylusButtonIntegrationTest, StylusButtonIntegrationTestTypes);
2079
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002080TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsGenerateKeyEvents) {
Prabir Pradhan124ea442022-10-28 20:27:44 +00002081 const auto stylusId = TestFixture::mStylusInfo.getId();
2082
2083 TestFixture::mStylus->pressKey(BTN_STYLUS);
2084 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2085 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
2086 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2087
2088 TestFixture::mStylus->releaseKey(BTN_STYLUS);
2089 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhane1a41a82022-10-14 18:06:50 +00002090 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002091 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
Prabir Pradhane1a41a82022-10-14 18:06:50 +00002092}
2093
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002094TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsSurroundingTouchGesture) {
Prabir Pradhan124ea442022-10-28 20:27:44 +00002095 const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
2096 const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
2097 const auto stylusId = TestFixture::mStylusInfo.getId();
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002098
2099 // Press the stylus button.
Prabir Pradhan124ea442022-10-28 20:27:44 +00002100 TestFixture::mStylus->pressKey(BTN_STYLUS);
2101 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002102 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002103 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002104
2105 // Start and finish a stylus gesture.
Prabir Pradhan124ea442022-10-28 20:27:44 +00002106 TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
2107 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2108 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2109 TestFixture::mTouchscreen->sendDown(centerPoint);
2110 TestFixture::mTouchscreen->sendSync();
2111 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002112 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002113 WithToolType(ToolType::STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002114 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2115 WithDeviceId(touchscreenId))));
2116 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002117 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002118 WithToolType(ToolType::STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002119 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2120 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002121
Prabir Pradhan124ea442022-10-28 20:27:44 +00002122 TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
2123 TestFixture::mTouchscreen->sendSync();
2124 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002125 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002126 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002127 WithDeviceId(touchscreenId))));
2128 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002129 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002130 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002131 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002132
2133 // Release the stylus button.
Prabir Pradhan124ea442022-10-28 20:27:44 +00002134 TestFixture::mStylus->releaseKey(BTN_STYLUS);
2135 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002136 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002137 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002138}
2139
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002140TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsSurroundingHoveringTouchGesture) {
Prabir Pradhan9a561c22022-11-07 16:11:23 +00002141 const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
2142 const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
2143 const auto stylusId = TestFixture::mStylusInfo.getId();
2144 auto toolTypeDevice =
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002145 AllOf(WithToolType(ToolType::STYLUS), WithDeviceId(touchscreenId));
Prabir Pradhan9a561c22022-11-07 16:11:23 +00002146
2147 // Press the stylus button.
2148 TestFixture::mStylus->pressKey(BTN_STYLUS);
2149 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2150 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
2151 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2152
2153 // Start hovering with the stylus.
2154 TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
2155 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2156 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2157 TestFixture::mTouchscreen->sendMove(centerPoint);
2158 TestFixture::mTouchscreen->sendSync();
2159 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2160 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
2161 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2162 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2163 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
2164 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2165 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2166 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
2167 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2168
2169 // Touch down with the stylus.
2170 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2171 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2172 TestFixture::mTouchscreen->sendDown(centerPoint);
2173 TestFixture::mTouchscreen->sendSync();
2174 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2175 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
2176 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2177
2178 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2179 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2180 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2181
2182 // Stop touching with the stylus, and start hovering.
2183 TestFixture::mTouchscreen->sendUp();
2184 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2185 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2186 TestFixture::mTouchscreen->sendMove(centerPoint);
2187 TestFixture::mTouchscreen->sendSync();
2188 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2189 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_UP),
2190 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2191 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2192 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
2193 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2194 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2195 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
2196 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2197
2198 // Stop hovering.
2199 TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
2200 TestFixture::mTouchscreen->sendSync();
2201 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2202 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
2203 WithButtonState(0))));
2204 // TODO(b/257971675): Fix inconsistent button state when exiting hover.
2205 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2206 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
2207 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2208
2209 // Release the stylus button.
2210 TestFixture::mStylus->releaseKey(BTN_STYLUS);
2211 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2212 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
2213 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2214}
2215
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002216TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsWithinTouchGesture) {
Prabir Pradhan124ea442022-10-28 20:27:44 +00002217 const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
2218 const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
2219 const auto stylusId = TestFixture::mStylusInfo.getId();
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002220
2221 // Start a stylus gesture.
Prabir Pradhan124ea442022-10-28 20:27:44 +00002222 TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
2223 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2224 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2225 TestFixture::mTouchscreen->sendDown(centerPoint);
2226 TestFixture::mTouchscreen->sendSync();
2227 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002228 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002229 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002230 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002231
2232 // Press and release a stylus button. Each change in button state also generates a MOVE event.
Prabir Pradhan124ea442022-10-28 20:27:44 +00002233 TestFixture::mStylus->pressKey(BTN_STYLUS);
2234 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002235 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002236 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2237 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002238 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002239 WithToolType(ToolType::STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002240 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2241 WithDeviceId(touchscreenId))));
2242 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002243 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002244 WithToolType(ToolType::STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002245 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2246 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002247
Prabir Pradhan124ea442022-10-28 20:27:44 +00002248 TestFixture::mStylus->releaseKey(BTN_STYLUS);
2249 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002250 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002251 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2252 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002253 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002254 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002255 WithDeviceId(touchscreenId))));
2256 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002257 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002258 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002259 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002260
2261 // Finish the stylus gesture.
Prabir Pradhan124ea442022-10-28 20:27:44 +00002262 TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
2263 TestFixture::mTouchscreen->sendSync();
2264 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002265 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002266 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002267 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002268}
2269
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002270TYPED_TEST(StylusButtonIntegrationTest, StylusButtonMotionEventsDisabled) {
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00002271 TestFixture::mFakePolicy->setStylusButtonMotionEventsEnabled(false);
2272 TestFixture::mReader->requestRefreshConfiguration(
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002273 InputReaderConfiguration::Change::STYLUS_BUTTON_REPORTING);
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00002274
2275 const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
2276 const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
2277 const auto stylusId = TestFixture::mStylusInfo.getId();
2278
2279 // Start a stylus gesture. By the time this event is processed, the configuration change that
2280 // was requested is guaranteed to be completed.
2281 TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
2282 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2283 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2284 TestFixture::mTouchscreen->sendDown(centerPoint);
2285 TestFixture::mTouchscreen->sendSync();
2286 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2287 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002288 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00002289 WithDeviceId(touchscreenId))));
2290
2291 // Press and release a stylus button. Each change only generates a MOVE motion event.
2292 // Key events are unaffected.
2293 TestFixture::mStylus->pressKey(BTN_STYLUS);
2294 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2295 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
2296 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2297 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2298 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002299 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00002300 WithDeviceId(touchscreenId))));
2301
2302 TestFixture::mStylus->releaseKey(BTN_STYLUS);
2303 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2304 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
2305 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2306 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2307 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002308 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00002309 WithDeviceId(touchscreenId))));
2310
2311 // Finish the stylus gesture.
2312 TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
2313 TestFixture::mTouchscreen->sendSync();
2314 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2315 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002316 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00002317 WithDeviceId(touchscreenId))));
2318}
2319
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002320// --- ExternalStylusIntegrationTest ---
2321
2322// Verify the behavior of an external stylus. An external stylus can report pressure or button
2323// data independently of the touchscreen, which is then sent as a MotionEvent as part of an
2324// ongoing stylus gesture that is being emitted by the touchscreen.
Arpit Singh440bf652023-08-09 09:23:43 +00002325using ExternalStylusIntegrationTest = BaseTouchIntegrationTest;
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002326
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00002327TEST_F(ExternalStylusIntegrationTest, ExternalStylusConnectionChangesTouchscreenSource) {
2328 // Create an external stylus capable of reporting pressure data that
2329 // should be fused with a touch pointer.
2330 std::unique_ptr<UinputExternalStylusWithPressure> stylus =
2331 createUinputDevice<UinputExternalStylusWithPressure>();
2332 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2333 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2334 const auto stylusInfo = findDeviceByName(stylus->getName());
2335 ASSERT_TRUE(stylusInfo);
2336
2337 // Connecting an external stylus changes the source of the touchscreen.
2338 const auto deviceInfo = findDeviceByName(mDevice->getName());
2339 ASSERT_TRUE(deviceInfo);
2340 ASSERT_TRUE(isFromSource(deviceInfo->getSources(), STYLUS_FUSION_SOURCE));
2341}
2342
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002343TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureReported) {
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002344 const Point centerPoint = mDevice->getCenterPoint();
2345
2346 // Create an external stylus capable of reporting pressure data that
2347 // should be fused with a touch pointer.
2348 std::unique_ptr<UinputExternalStylusWithPressure> stylus =
2349 createUinputDevice<UinputExternalStylusWithPressure>();
2350 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2351 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2352 const auto stylusInfo = findDeviceByName(stylus->getName());
2353 ASSERT_TRUE(stylusInfo);
2354
2355 ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2356
2357 const auto touchscreenId = mDeviceInfo.getId();
2358
2359 // Set a pressure value on the stylus. It doesn't generate any events.
2360 const auto& RAW_PRESSURE_MAX = UinputExternalStylusWithPressure::RAW_PRESSURE_MAX;
2361 stylus->setPressure(100);
2362 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2363
2364 // Start a finger gesture, and ensure it shows up as stylus gesture
2365 // with the pressure set by the external stylus.
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002366 mDevice->sendSlot(FIRST_SLOT);
Chris Ye1b0c7342020-07-28 21:57:03 -07002367 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002368 mDevice->sendToolType(MT_TOOL_FINGER);
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00002369 mDevice->sendDown(centerPoint);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002370 mDevice->sendSync();
2371 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00002372 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithToolType(ToolType::STYLUS),
2373 WithButtonState(0), WithSource(STYLUS_FUSION_SOURCE), WithDeviceId(touchscreenId),
2374 WithPressure(100.f / RAW_PRESSURE_MAX))));
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002375
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002376 // Change the pressure on the external stylus, and ensure the touchscreen generates a MOVE
2377 // event with the updated pressure.
2378 stylus->setPressure(200);
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +00002379 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00002380 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithToolType(ToolType::STYLUS),
2381 WithButtonState(0), WithSource(STYLUS_FUSION_SOURCE), WithDeviceId(touchscreenId),
2382 WithPressure(200.f / RAW_PRESSURE_MAX))));
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002383
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002384 // The external stylus did not generate any events.
2385 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2386 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
2387}
2388
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002389TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureNotReported) {
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002390 const Point centerPoint = mDevice->getCenterPoint();
2391
2392 // Create an external stylus capable of reporting pressure data that
2393 // should be fused with a touch pointer.
2394 std::unique_ptr<UinputExternalStylusWithPressure> stylus =
2395 createUinputDevice<UinputExternalStylusWithPressure>();
2396 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2397 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2398 const auto stylusInfo = findDeviceByName(stylus->getName());
2399 ASSERT_TRUE(stylusInfo);
2400
2401 ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2402
2403 const auto touchscreenId = mDeviceInfo.getId();
2404
2405 // Set a pressure value of 0 on the stylus. It doesn't generate any events.
2406 const auto& RAW_PRESSURE_MAX = UinputExternalStylusWithPressure::RAW_PRESSURE_MAX;
Prabir Pradhan3f7545f2022-10-19 16:56:39 +00002407 // Send a non-zero value first to prevent the kernel from consuming the zero event.
2408 stylus->setPressure(100);
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002409 stylus->setPressure(0);
Prabir Pradhan3f7545f2022-10-19 16:56:39 +00002410 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002411
2412 // Start a finger gesture. The touch device will withhold generating any touches for
2413 // up to 72 milliseconds while waiting for pressure data from the external stylus.
2414 mDevice->sendSlot(FIRST_SLOT);
2415 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2416 mDevice->sendToolType(MT_TOOL_FINGER);
2417 mDevice->sendDown(centerPoint);
2418 auto waitUntil = std::chrono::system_clock::now() +
2419 std::chrono::milliseconds(ns2ms(EXTERNAL_STYLUS_DATA_TIMEOUT));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07002420 mDevice->sendSync();
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002421 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled(waitUntil));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002422
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002423 // Since the external stylus did not report a pressure value within the timeout,
2424 // it shows up as a finger pointer.
2425 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2426 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00002427 WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
2428 WithToolType(ToolType::FINGER), WithDeviceId(touchscreenId), WithPressure(1.f))));
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002429
2430 // Change the pressure on the external stylus. Since the pressure was not present at the start
2431 // of the gesture, it is ignored for now.
2432 stylus->setPressure(200);
2433 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2434
2435 // Finish the finger gesture.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002436 mDevice->sendTrackingId(INVALID_TRACKING_ID);
2437 mDevice->sendSync();
2438 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2439 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00002440 WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002441 WithToolType(ToolType::FINGER))));
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002442
2443 // Start a new gesture. Since we have a valid pressure value, it shows up as a stylus.
2444 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2445 mDevice->sendToolType(MT_TOOL_FINGER);
2446 mDevice->sendDown(centerPoint);
2447 mDevice->sendSync();
2448 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00002449 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithSource(STYLUS_FUSION_SOURCE),
2450 WithToolType(ToolType::STYLUS), WithButtonState(0), WithDeviceId(touchscreenId),
2451 WithPressure(200.f / RAW_PRESSURE_MAX))));
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002452
2453 // The external stylus did not generate any events.
2454 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2455 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002456}
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00002457
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002458TEST_F(ExternalStylusIntegrationTest, UnfusedExternalStylus) {
Prabir Pradhan3f7545f2022-10-19 16:56:39 +00002459 const Point centerPoint = mDevice->getCenterPoint();
2460
2461 // Create an external stylus device that does not support pressure. It should not affect any
2462 // touch pointers.
2463 std::unique_ptr<UinputExternalStylus> stylus = createUinputDevice<UinputExternalStylus>();
2464 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2465 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2466 const auto stylusInfo = findDeviceByName(stylus->getName());
2467 ASSERT_TRUE(stylusInfo);
2468
2469 ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2470
2471 const auto touchscreenId = mDeviceInfo.getId();
2472
2473 // Start a finger gesture and ensure a finger pointer is generated for it, without waiting for
2474 // pressure data from the external stylus.
2475 mDevice->sendSlot(FIRST_SLOT);
2476 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2477 mDevice->sendToolType(MT_TOOL_FINGER);
2478 mDevice->sendDown(centerPoint);
2479 auto waitUntil = std::chrono::system_clock::now() +
2480 std::chrono::milliseconds(ns2ms(EXTERNAL_STYLUS_DATA_TIMEOUT));
2481 mDevice->sendSync();
2482 ASSERT_NO_FATAL_FAILURE(
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00002483 mTestListener->assertNotifyMotionWasCalled(AllOf(WithMotionAction(
2484 AMOTION_EVENT_ACTION_DOWN),
2485 WithToolType(ToolType::FINGER),
2486 WithSource(AINPUT_SOURCE_TOUCHSCREEN |
2487 AINPUT_SOURCE_STYLUS),
2488 WithButtonState(0),
2489 WithDeviceId(touchscreenId),
2490 WithPressure(1.f)),
2491 waitUntil));
Prabir Pradhan3f7545f2022-10-19 16:56:39 +00002492
2493 // The external stylus did not generate any events.
2494 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2495 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
2496}
2497
Michael Wrightd02c5b62014-02-10 15:10:22 -08002498// --- InputDeviceTest ---
2499class InputDeviceTest : public testing::Test {
2500protected:
2501 static const char* DEVICE_NAME;
2502 static const char* DEVICE_LOCATION;
2503 static const int32_t DEVICE_ID;
2504 static const int32_t DEVICE_GENERATION;
2505 static const int32_t DEVICE_CONTROLLER_NUMBER;
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01002506 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002507 static const int32_t EVENTHUB_ID;
2508 static const std::string DEVICE_BLUETOOTH_ADDRESS;
2509
2510 std::shared_ptr<FakeEventHub> mFakeEventHub;
2511 sp<FakeInputReaderPolicy> mFakePolicy;
2512 std::unique_ptr<TestInputListener> mFakeListener;
2513 std::unique_ptr<InstrumentedInputReader> mReader;
2514 std::shared_ptr<InputDevice> mDevice;
2515
2516 void SetUp() override {
2517 mFakeEventHub = std::make_unique<FakeEventHub>();
2518 mFakePolicy = sp<FakeInputReaderPolicy>::make();
2519 mFakeListener = std::make_unique<TestInputListener>();
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002520 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002521 *mFakeListener);
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002522 InputDeviceIdentifier identifier;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002523 identifier.name = DEVICE_NAME;
2524 identifier.location = DEVICE_LOCATION;
2525 identifier.bluetoothAddress = DEVICE_BLUETOOTH_ADDRESS;
2526 mDevice = std::make_shared<InputDevice>(mReader->getContext(), DEVICE_ID, DEVICE_GENERATION,
2527 identifier);
2528 mReader->pushNextDevice(mDevice);
2529 mFakeEventHub->addDevice(EVENTHUB_ID, DEVICE_NAME, ftl::Flags<InputDeviceClass>(0));
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002530 mReader->loopOnce();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002531 }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002532
2533 void TearDown() override {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002534 mFakeListener.reset();
2535 mFakePolicy.clear();
2536 }
2537};
2538
2539const char* InputDeviceTest::DEVICE_NAME = "device";
2540const char* InputDeviceTest::DEVICE_LOCATION = "USB1";
2541const int32_t InputDeviceTest::DEVICE_ID = END_RESERVED_ID + 1000;
2542const int32_t InputDeviceTest::DEVICE_GENERATION = 2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002543const int32_t InputDeviceTest::DEVICE_CONTROLLER_NUMBER = 0;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002544const ftl::Flags<InputDeviceClass> InputDeviceTest::DEVICE_CLASSES =
2545 InputDeviceClass::KEYBOARD | InputDeviceClass::TOUCH | InputDeviceClass::JOYSTICK;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002546const int32_t InputDeviceTest::EVENTHUB_ID = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002547const std::string InputDeviceTest::DEVICE_BLUETOOTH_ADDRESS = "11:AA:22:BB:33:CC";
2548
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002549TEST_F(InputDeviceTest, ImmutableProperties) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002550 ASSERT_EQ(DEVICE_ID, mDevice->getId());
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002551 ASSERT_STREQ(DEVICE_NAME, mDevice->getName().c_str());
2552 ASSERT_EQ(ftl::Flags<InputDeviceClass>(0), mDevice->getClasses());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002553}
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002554
Michael Wrightd02c5b62014-02-10 15:10:22 -08002555TEST_F(InputDeviceTest, WhenDeviceCreated_EnabledIsFalse) {
2556 ASSERT_EQ(mDevice->isEnabled(), false);
2557}
2558
2559TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
2560 // Configuration.
2561 InputReaderConfiguration config;
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002562 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
Michael Wrightd02c5b62014-02-10 15:10:22 -08002563
2564 // Reset.
2565 unused += mDevice->reset(ARBITRARY_TIME);
2566
2567 NotifyDeviceResetArgs resetArgs;
2568 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2569 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
2570 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
2571
2572 // Metadata.
2573 ASSERT_TRUE(mDevice->isIgnored());
2574 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mDevice->getSources());
2575
2576 InputDeviceInfo info = mDevice->getDeviceInfo();
2577 ASSERT_EQ(DEVICE_ID, info.getId());
2578 ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
2579 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType());
2580 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources());
2581
2582 // State queries.
2583 ASSERT_EQ(0, mDevice->getMetaState());
2584
2585 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, 0))
2586 << "Ignored device should return unknown key code state.";
2587 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 0))
2588 << "Ignored device should return unknown scan code state.";
2589 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 0))
2590 << "Ignored device should return unknown switch state.";
2591
2592 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B};
2593 uint8_t flags[2] = { 0, 1 };
2594 ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, keyCodes, flags))
2595 << "Ignored device should never mark any key codes.";
2596 ASSERT_EQ(0, flags[0]) << "Flag for unsupported key should be unchanged.";
2597 ASSERT_EQ(1, flags[1]) << "Flag for unsupported key should be unchanged.";
2598}
2599
2600TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) {
2601 // Configuration.
2602 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "key", "value");
2603
2604 FakeInputMapper& mapper1 =
Arpit Singh8e6fb252023-04-06 11:49:17 +00002605 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2606 AINPUT_SOURCE_KEYBOARD);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002607 mapper1.setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC);
2608 mapper1.setMetaState(AMETA_ALT_ON);
2609 mapper1.addSupportedKeyCode(AKEYCODE_A);
2610 mapper1.addSupportedKeyCode(AKEYCODE_B);
2611 mapper1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
2612 mapper1.setKeyCodeState(AKEYCODE_B, AKEY_STATE_UP);
2613 mapper1.setScanCodeState(2, AKEY_STATE_DOWN);
2614 mapper1.setScanCodeState(3, AKEY_STATE_UP);
2615 mapper1.setSwitchState(4, AKEY_STATE_DOWN);
2616
2617 FakeInputMapper& mapper2 =
Arpit Singh8e6fb252023-04-06 11:49:17 +00002618 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2619 AINPUT_SOURCE_TOUCHSCREEN);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002620 mapper2.setMetaState(AMETA_SHIFT_ON);
2621
2622 InputReaderConfiguration config;
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002623 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
Michael Wrightd02c5b62014-02-10 15:10:22 -08002624
Harry Cuttsf13161a2023-03-08 14:15:49 +00002625 std::optional<std::string> propertyValue = mDevice->getConfiguration().getString("key");
2626 ASSERT_TRUE(propertyValue.has_value())
Michael Wrightd02c5b62014-02-10 15:10:22 -08002627 << "Device should have read configuration during configuration phase.";
Harry Cuttsf13161a2023-03-08 14:15:49 +00002628 ASSERT_EQ("value", *propertyValue);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002629
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002630 ASSERT_NO_FATAL_FAILURE(mapper1.assertConfigureWasCalled());
2631 ASSERT_NO_FATAL_FAILURE(mapper2.assertConfigureWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002632
2633 // Reset
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002634 unused += mDevice->reset(ARBITRARY_TIME);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002635 ASSERT_NO_FATAL_FAILURE(mapper1.assertResetWasCalled());
2636 ASSERT_NO_FATAL_FAILURE(mapper2.assertResetWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002637
2638 NotifyDeviceResetArgs resetArgs;
2639 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2640 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
2641 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
2642
2643 // Metadata.
2644 ASSERT_FALSE(mDevice->isIgnored());
2645 ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), mDevice->getSources());
2646
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00002647 InputDeviceInfo info = mDevice->getDeviceInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002648 ASSERT_EQ(DEVICE_ID, info.getId());
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01002649 ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002650 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType());
2651 ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources());
2652
2653 // State queries.
2654 ASSERT_EQ(AMETA_ALT_ON | AMETA_SHIFT_ON, mDevice->getMetaState())
2655 << "Should query mappers and combine meta states.";
2656
2657 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2658 << "Should return unknown key code state when source not supported.";
2659 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2660 << "Should return unknown scan code state when source not supported.";
2661 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2662 << "Should return unknown switch state when source not supported.";
2663
2664 ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, AKEYCODE_A))
2665 << "Should query mapper when source is supported.";
2666 ASSERT_EQ(AKEY_STATE_UP, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 3))
2667 << "Should query mapper when source is supported.";
2668 ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 4))
2669 << "Should query mapper when source is supported.";
2670
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002671 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2};
Michael Wrightd02c5b62014-02-10 15:10:22 -08002672 uint8_t flags[4] = { 0, 0, 0, 1 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002673 ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -08002674 << "Should do nothing when source is unsupported.";
2675 ASSERT_EQ(0, flags[0]) << "Flag should be unchanged when source is unsupported.";
2676 ASSERT_EQ(0, flags[1]) << "Flag should be unchanged when source is unsupported.";
2677 ASSERT_EQ(0, flags[2]) << "Flag should be unchanged when source is unsupported.";
2678 ASSERT_EQ(1, flags[3]) << "Flag should be unchanged when source is unsupported.";
2679
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002680 ASSERT_TRUE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -08002681 << "Should query mapper when source is supported.";
2682 ASSERT_EQ(1, flags[0]) << "Flag for supported key should be set.";
2683 ASSERT_EQ(1, flags[1]) << "Flag for supported key should be set.";
2684 ASSERT_EQ(0, flags[2]) << "Flag for unsupported key should be unchanged.";
2685 ASSERT_EQ(1, flags[3]) << "Flag for unsupported key should be unchanged.";
2686
2687 // Event handling.
2688 RawEvent event;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002689 event.deviceId = EVENTHUB_ID;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002690 unused += mDevice->process(&event, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002691
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002692 ASSERT_NO_FATAL_FAILURE(mapper1.assertProcessWasCalled());
2693 ASSERT_NO_FATAL_FAILURE(mapper2.assertProcessWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002694}
2695
Yeabkal Wubshite03e8b12023-06-27 16:23:12 -07002696TEST_F(InputDeviceTest, WakeDevice_AddsWakeFlagToProcessNotifyArgs) {
2697 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "1");
2698 FakeInputMapper& mapper =
2699 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2700 AINPUT_SOURCE_KEYBOARD);
2701 NotifyMotionArgs args1;
2702 NotifySwitchArgs args2;
2703 NotifyKeyArgs args3;
2704 mapper.setProcessResult({args1, args2, args3});
2705
2706 InputReaderConfiguration config;
2707 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
2708
2709 RawEvent event;
2710 event.deviceId = EVENTHUB_ID;
2711 std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1);
2712
2713 for (auto& arg : notifyArgs) {
2714 if (const auto notifyMotionArgs = std::get_if<NotifyMotionArgs>(&arg)) {
2715 ASSERT_EQ(POLICY_FLAG_WAKE, notifyMotionArgs->policyFlags);
2716 } else if (const auto notifySwitchArgs = std::get_if<NotifySwitchArgs>(&arg)) {
2717 ASSERT_EQ(POLICY_FLAG_WAKE, notifySwitchArgs->policyFlags);
2718 } else if (const auto notifyKeyArgs = std::get_if<NotifyKeyArgs>(&arg)) {
2719 ASSERT_EQ(POLICY_FLAG_WAKE, notifyKeyArgs->policyFlags);
2720 }
2721 }
2722}
2723
2724TEST_F(InputDeviceTest, NotWakeDevice_DoesNotAddWakeFlagToProcessNotifyArgs) {
2725 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "0");
2726 FakeInputMapper& mapper =
2727 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2728 AINPUT_SOURCE_KEYBOARD);
2729 NotifyMotionArgs args;
2730 mapper.setProcessResult({args});
2731
2732 InputReaderConfiguration config;
2733 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
2734
2735 RawEvent event;
2736 event.deviceId = EVENTHUB_ID;
2737 std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1);
2738
2739 // POLICY_FLAG_WAKE is not added to the NotifyArgs.
2740 ASSERT_EQ(0u, std::get<NotifyMotionArgs>(notifyArgs.front()).policyFlags);
2741}
2742
2743TEST_F(InputDeviceTest, NotWakeDevice_DoesNotRemoveExistingWakeFlagFromProcessNotifyArgs) {
2744 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "0");
2745 FakeInputMapper& mapper =
2746 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2747 AINPUT_SOURCE_KEYBOARD);
2748 NotifyMotionArgs args;
2749 args.policyFlags = POLICY_FLAG_WAKE;
2750 mapper.setProcessResult({args});
2751
2752 InputReaderConfiguration config;
2753 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
2754
2755 RawEvent event;
2756 event.deviceId = EVENTHUB_ID;
2757 std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1);
2758
2759 // The POLICY_FLAG_WAKE is preserved, despite the device being a non-wake device.
2760 ASSERT_EQ(POLICY_FLAG_WAKE, std::get<NotifyMotionArgs>(notifyArgs.front()).policyFlags);
2761}
2762
Arthur Hung2c9a3342019-07-23 14:18:59 +08002763// A single input device is associated with a specific display. Check that:
2764// 1. Device is disabled if the viewport corresponding to the associated display is not found
Arpit Singh48189772023-05-30 14:12:49 +00002765// 2. Device is disabled when configure API is called
Arthur Hung2c9a3342019-07-23 14:18:59 +08002766TEST_F(InputDeviceTest, Configure_AssignsDisplayPort) {
Arpit Singh8e6fb252023-04-06 11:49:17 +00002767 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2768 AINPUT_SOURCE_TOUCHSCREEN);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002769
2770 // First Configuration.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002771 std::list<NotifyArgs> unused =
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002772 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2773 /*changes=*/{});
Arthur Hung2c9a3342019-07-23 14:18:59 +08002774
2775 // Device should be enabled by default.
2776 ASSERT_TRUE(mDevice->isEnabled());
2777
2778 // Prepare associated info.
2779 constexpr uint8_t hdmi = 1;
2780 const std::string UNIQUE_ID = "local:1";
2781
2782 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002783 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002784 InputReaderConfiguration::Change::DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002785 // Device should be disabled because it is associated with a specific display via
2786 // input port <-> display port association, but the corresponding display is not found
2787 ASSERT_FALSE(mDevice->isEnabled());
2788
2789 // Prepare displays.
2790 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +00002791 ui::ROTATION_0, /*isActive=*/true, UNIQUE_ID, hdmi,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00002792 ViewportType::INTERNAL);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002793 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002794 InputReaderConfiguration::Change::DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002795 ASSERT_TRUE(mDevice->isEnabled());
2796
2797 // Device should be disabled after set disable.
2798 mFakePolicy->addDisabledDevice(mDevice->getId());
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002799 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002800 InputReaderConfiguration::Change::ENABLED_STATE);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002801 ASSERT_FALSE(mDevice->isEnabled());
2802
2803 // Device should still be disabled even found the associated display.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002804 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002805 InputReaderConfiguration::Change::DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002806 ASSERT_FALSE(mDevice->isEnabled());
2807}
Michael Wrightd02c5b62014-02-10 15:10:22 -08002808
Christine Franks1ba71cc2021-04-07 14:37:42 -07002809TEST_F(InputDeviceTest, Configure_AssignsDisplayUniqueId) {
2810 // Device should be enabled by default.
2811 mFakePolicy->clearViewports();
Arpit Singh8e6fb252023-04-06 11:49:17 +00002812 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2813 AINPUT_SOURCE_KEYBOARD);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002814 std::list<NotifyArgs> unused =
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002815 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2816 /*changes=*/{});
Christine Franks1ba71cc2021-04-07 14:37:42 -07002817 ASSERT_TRUE(mDevice->isEnabled());
2818
2819 // Device should be disabled because it is associated with a specific display, but the
2820 // corresponding display is not found.
Christine Franks2a2293c2022-01-18 11:51:16 -08002821 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002822 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002823 InputReaderConfiguration::Change::DISPLAY_INFO);
Christine Franks1ba71cc2021-04-07 14:37:42 -07002824 ASSERT_FALSE(mDevice->isEnabled());
2825
2826 // Device should be enabled when a display is found.
2827 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +00002828 ui::ROTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID,
Christine Franks1ba71cc2021-04-07 14:37:42 -07002829 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002830 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002831 InputReaderConfiguration::Change::DISPLAY_INFO);
Christine Franks1ba71cc2021-04-07 14:37:42 -07002832 ASSERT_TRUE(mDevice->isEnabled());
2833
2834 // Device should be disabled after set disable.
2835 mFakePolicy->addDisabledDevice(mDevice->getId());
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002836 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002837 InputReaderConfiguration::Change::ENABLED_STATE);
Christine Franks1ba71cc2021-04-07 14:37:42 -07002838 ASSERT_FALSE(mDevice->isEnabled());
2839
2840 // Device should still be disabled even found the associated display.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002841 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002842 InputReaderConfiguration::Change::DISPLAY_INFO);
Christine Franks1ba71cc2021-04-07 14:37:42 -07002843 ASSERT_FALSE(mDevice->isEnabled());
2844}
2845
Christine Franks2a2293c2022-01-18 11:51:16 -08002846TEST_F(InputDeviceTest, Configure_UniqueId_CorrectlyMatches) {
2847 mFakePolicy->clearViewports();
Arpit Singh8e6fb252023-04-06 11:49:17 +00002848 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2849 AINPUT_SOURCE_KEYBOARD);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002850 std::list<NotifyArgs> unused =
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002851 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2852 /*changes=*/{});
Christine Franks2a2293c2022-01-18 11:51:16 -08002853
Christine Franks2a2293c2022-01-18 11:51:16 -08002854 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
2855 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +00002856 ui::ROTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID,
Christine Franks2a2293c2022-01-18 11:51:16 -08002857 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002858 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002859 InputReaderConfiguration::Change::DISPLAY_INFO);
Christine Franks2a2293c2022-01-18 11:51:16 -08002860 ASSERT_EQ(DISPLAY_UNIQUE_ID, mDevice->getAssociatedDisplayUniqueId());
2861}
2862
Siarhei Vishniakou30feb8c2022-09-28 10:48:29 -07002863/**
2864 * This test reproduces a crash caused by a dangling reference that remains after device is added
2865 * and removed. The reference is accessed in InputDevice::dump(..);
2866 */
2867TEST_F(InputDeviceTest, DumpDoesNotCrash) {
2868 constexpr int32_t TEST_EVENTHUB_ID = 10;
2869 mFakeEventHub->addDevice(TEST_EVENTHUB_ID, "Test EventHub device", InputDeviceClass::BATTERY);
2870
Harry Cutts33476232023-01-30 19:57:29 +00002871 InputDevice device(mReader->getContext(), /*id=*/1, /*generation=*/2, /*identifier=*/{});
Arpit Singh82f29a12023-06-13 15:05:53 +00002872 auto _ = device.addEventHubDevice(ARBITRARY_TIME, TEST_EVENTHUB_ID,
2873 mFakePolicy->getReaderConfiguration());
Siarhei Vishniakou30feb8c2022-09-28 10:48:29 -07002874 device.removeEventHubDevice(TEST_EVENTHUB_ID);
2875 std::string dumpStr, eventHubDevStr;
2876 device.dump(dumpStr, eventHubDevStr);
2877}
2878
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00002879TEST_F(InputDeviceTest, GetBluetoothAddress) {
2880 const auto& address = mReader->getBluetoothAddress(DEVICE_ID);
2881 ASSERT_TRUE(address);
2882 ASSERT_EQ(DEVICE_BLUETOOTH_ADDRESS, *address);
2883}
2884
Prabir Pradhanf8d9e442023-12-06 22:06:13 +00002885TEST_F(InputDeviceTest, KernelBufferOverflowResetsMappers) {
2886 mFakePolicy->clearViewports();
2887 FakeInputMapper& mapper =
2888 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2889 AINPUT_SOURCE_KEYBOARD);
2890 std::list<NotifyArgs> unused =
2891 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2892 /*changes=*/{});
2893
2894 mapper.assertConfigureWasCalled();
2895 mapper.assertResetWasNotCalled();
2896
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002897 RawEvent event{.when = ARBITRARY_TIME,
Prabir Pradhanf8d9e442023-12-06 22:06:13 +00002898 .readTime = ARBITRARY_TIME,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002899 .deviceId = EVENTHUB_ID,
Prabir Pradhanf8d9e442023-12-06 22:06:13 +00002900 .type = EV_SYN,
2901 .code = SYN_REPORT,
2902 .value = 0};
2903
2904 // Events are processed normally.
2905 unused = mDevice->process(&event, /*count=*/1);
2906 mapper.assertProcessWasCalled();
2907
2908 // Simulate a kernel buffer overflow, which generates a SYN_DROPPED event.
2909 // This should reset the mapper.
2910 event.type = EV_SYN;
2911 event.code = SYN_DROPPED;
2912 event.value = 0;
2913 unused = mDevice->process(&event, /*count=*/1);
2914 mapper.assertProcessWasNotCalled();
2915 mapper.assertResetWasCalled();
2916
2917 // All events until the next SYN_REPORT should be dropped.
2918 event.type = EV_KEY;
2919 event.code = KEY_A;
2920 event.value = 1;
2921 unused = mDevice->process(&event, /*count=*/1);
2922 mapper.assertProcessWasNotCalled();
2923
2924 // We get the SYN_REPORT event now, which is not forwarded to mappers.
2925 event.type = EV_SYN;
2926 event.code = SYN_REPORT;
2927 event.value = 0;
2928 unused = mDevice->process(&event, /*count=*/1);
2929 mapper.assertProcessWasNotCalled();
2930
2931 // The mapper receives events normally now.
2932 event.type = EV_KEY;
2933 event.code = KEY_B;
2934 event.value = 1;
2935 unused = mDevice->process(&event, /*count=*/1);
2936 mapper.assertProcessWasCalled();
2937}
2938
Michael Wrightd02c5b62014-02-10 15:10:22 -08002939// --- SwitchInputMapperTest ---
2940
2941class SwitchInputMapperTest : public InputMapperTest {
2942protected:
2943};
2944
2945TEST_F(SwitchInputMapperTest, GetSources) {
Arpit Singhdf992eb2023-04-26 16:12:10 +00002946 SwitchInputMapper& mapper = constructAndAddMapper<SwitchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002947
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002948 ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002949}
2950
2951TEST_F(SwitchInputMapperTest, GetSwitchState) {
Arpit Singhdf992eb2023-04-26 16:12:10 +00002952 SwitchInputMapper& mapper = constructAndAddMapper<SwitchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002953
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002954 mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002955 ASSERT_EQ(1, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002956
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002957 mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002958 ASSERT_EQ(0, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002959}
2960
2961TEST_F(SwitchInputMapperTest, Process) {
Arpit Singhdf992eb2023-04-26 16:12:10 +00002962 SwitchInputMapper& mapper = constructAndAddMapper<SwitchInputMapper>();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002963 std::list<NotifyArgs> out;
2964 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_LID, 1);
2965 ASSERT_TRUE(out.empty());
2966 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_JACK_PHYSICAL_INSERT, 1);
2967 ASSERT_TRUE(out.empty());
2968 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_HEADPHONE_INSERT, 0);
2969 ASSERT_TRUE(out.empty());
2970 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002971
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002972 ASSERT_EQ(1u, out.size());
2973 const NotifySwitchArgs& args = std::get<NotifySwitchArgs>(*out.begin());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002974 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
Dan Albert1bd2fc02016-02-02 15:11:57 -08002975 ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT), args.switchValues);
2976 ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT) | (1 << SW_HEADPHONE_INSERT),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002977 args.switchMask);
2978 ASSERT_EQ(uint32_t(0), args.policyFlags);
2979}
2980
Chris Ye87143712020-11-10 05:05:58 +00002981// --- VibratorInputMapperTest ---
2982class VibratorInputMapperTest : public InputMapperTest {
2983protected:
2984 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::VIBRATOR); }
2985};
2986
2987TEST_F(VibratorInputMapperTest, GetSources) {
Arpit Singh0f26b302023-04-26 16:23:13 +00002988 VibratorInputMapper& mapper = constructAndAddMapper<VibratorInputMapper>();
Chris Ye87143712020-11-10 05:05:58 +00002989
2990 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mapper.getSources());
2991}
2992
2993TEST_F(VibratorInputMapperTest, GetVibratorIds) {
Arpit Singh0f26b302023-04-26 16:23:13 +00002994 VibratorInputMapper& mapper = constructAndAddMapper<VibratorInputMapper>();
Chris Ye87143712020-11-10 05:05:58 +00002995
2996 ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
2997}
2998
2999TEST_F(VibratorInputMapperTest, Vibrate) {
3000 constexpr uint8_t DEFAULT_AMPLITUDE = 192;
Chris Yefb552902021-02-03 17:18:37 -08003001 constexpr int32_t VIBRATION_TOKEN = 100;
Arpit Singh0f26b302023-04-26 16:23:13 +00003002 VibratorInputMapper& mapper = constructAndAddMapper<VibratorInputMapper>();
Chris Ye87143712020-11-10 05:05:58 +00003003
3004 VibrationElement pattern(2);
3005 VibrationSequence sequence(2);
3006 pattern.duration = std::chrono::milliseconds(200);
Harry Cutts33476232023-01-30 19:57:29 +00003007 pattern.channels = {{/*vibratorId=*/0, DEFAULT_AMPLITUDE / 2},
3008 {/*vibratorId=*/1, DEFAULT_AMPLITUDE}};
Chris Ye87143712020-11-10 05:05:58 +00003009 sequence.addElement(pattern);
3010 pattern.duration = std::chrono::milliseconds(500);
Harry Cutts33476232023-01-30 19:57:29 +00003011 pattern.channels = {{/*vibratorId=*/0, DEFAULT_AMPLITUDE / 4},
3012 {/*vibratorId=*/1, DEFAULT_AMPLITUDE}};
Chris Ye87143712020-11-10 05:05:58 +00003013 sequence.addElement(pattern);
3014
3015 std::vector<int64_t> timings = {0, 1};
3016 std::vector<uint8_t> amplitudes = {DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE / 2};
3017
3018 ASSERT_FALSE(mapper.isVibrating());
Chris Yefb552902021-02-03 17:18:37 -08003019 // Start vibrating
Harry Cutts33476232023-01-30 19:57:29 +00003020 std::list<NotifyArgs> out = mapper.vibrate(sequence, /*repeat=*/-1, VIBRATION_TOKEN);
Chris Ye87143712020-11-10 05:05:58 +00003021 ASSERT_TRUE(mapper.isVibrating());
Chris Yefb552902021-02-03 17:18:37 -08003022 // Verify vibrator state listener was notified.
3023 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003024 ASSERT_EQ(1u, out.size());
3025 const NotifyVibratorStateArgs& vibrateArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
3026 ASSERT_EQ(DEVICE_ID, vibrateArgs.deviceId);
3027 ASSERT_TRUE(vibrateArgs.isOn);
Chris Yefb552902021-02-03 17:18:37 -08003028 // Stop vibrating
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003029 out = mapper.cancelVibrate(VIBRATION_TOKEN);
Chris Yefb552902021-02-03 17:18:37 -08003030 ASSERT_FALSE(mapper.isVibrating());
3031 // Verify vibrator state listener was notified.
3032 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003033 ASSERT_EQ(1u, out.size());
3034 const NotifyVibratorStateArgs& cancelArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
3035 ASSERT_EQ(DEVICE_ID, cancelArgs.deviceId);
3036 ASSERT_FALSE(cancelArgs.isOn);
Chris Ye87143712020-11-10 05:05:58 +00003037}
Michael Wrightd02c5b62014-02-10 15:10:22 -08003038
Chris Yef59a2f42020-10-16 12:55:26 -07003039// --- SensorInputMapperTest ---
3040
3041class SensorInputMapperTest : public InputMapperTest {
3042protected:
3043 static const int32_t ACCEL_RAW_MIN;
3044 static const int32_t ACCEL_RAW_MAX;
3045 static const int32_t ACCEL_RAW_FUZZ;
3046 static const int32_t ACCEL_RAW_FLAT;
3047 static const int32_t ACCEL_RAW_RESOLUTION;
3048
3049 static const int32_t GYRO_RAW_MIN;
3050 static const int32_t GYRO_RAW_MAX;
3051 static const int32_t GYRO_RAW_FUZZ;
3052 static const int32_t GYRO_RAW_FLAT;
3053 static const int32_t GYRO_RAW_RESOLUTION;
3054
3055 static const float GRAVITY_MS2_UNIT;
3056 static const float DEGREE_RADIAN_UNIT;
3057
3058 void prepareAccelAxes();
3059 void prepareGyroAxes();
3060 void setAccelProperties();
3061 void setGyroProperties();
3062 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::SENSOR); }
3063};
3064
3065const int32_t SensorInputMapperTest::ACCEL_RAW_MIN = -32768;
3066const int32_t SensorInputMapperTest::ACCEL_RAW_MAX = 32768;
3067const int32_t SensorInputMapperTest::ACCEL_RAW_FUZZ = 16;
3068const int32_t SensorInputMapperTest::ACCEL_RAW_FLAT = 0;
3069const int32_t SensorInputMapperTest::ACCEL_RAW_RESOLUTION = 8192;
3070
3071const int32_t SensorInputMapperTest::GYRO_RAW_MIN = -2097152;
3072const int32_t SensorInputMapperTest::GYRO_RAW_MAX = 2097152;
3073const int32_t SensorInputMapperTest::GYRO_RAW_FUZZ = 16;
3074const int32_t SensorInputMapperTest::GYRO_RAW_FLAT = 0;
3075const int32_t SensorInputMapperTest::GYRO_RAW_RESOLUTION = 1024;
3076
3077const float SensorInputMapperTest::GRAVITY_MS2_UNIT = 9.80665f;
3078const float SensorInputMapperTest::DEGREE_RADIAN_UNIT = 0.0174533f;
3079
3080void SensorInputMapperTest::prepareAccelAxes() {
3081 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
3082 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
3083 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
3084 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
3085 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Z, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
3086 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
3087}
3088
3089void SensorInputMapperTest::prepareGyroAxes() {
3090 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RX, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
3091 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
3092 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RY, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
3093 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
3094 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RZ, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
3095 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
3096}
3097
3098void SensorInputMapperTest::setAccelProperties() {
3099 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 0, InputDeviceSensorType::ACCELEROMETER,
3100 /* sensorDataIndex */ 0);
3101 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 1, InputDeviceSensorType::ACCELEROMETER,
3102 /* sensorDataIndex */ 1);
3103 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 2, InputDeviceSensorType::ACCELEROMETER,
3104 /* sensorDataIndex */ 2);
3105 mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP);
3106 addConfigurationProperty("sensor.accelerometer.reportingMode", "0");
3107 addConfigurationProperty("sensor.accelerometer.maxDelay", "100000");
3108 addConfigurationProperty("sensor.accelerometer.minDelay", "5000");
3109 addConfigurationProperty("sensor.accelerometer.power", "1.5");
3110}
3111
3112void SensorInputMapperTest::setGyroProperties() {
3113 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 3, InputDeviceSensorType::GYROSCOPE,
3114 /* sensorDataIndex */ 0);
3115 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 4, InputDeviceSensorType::GYROSCOPE,
3116 /* sensorDataIndex */ 1);
3117 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 5, InputDeviceSensorType::GYROSCOPE,
3118 /* sensorDataIndex */ 2);
3119 mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP);
3120 addConfigurationProperty("sensor.gyroscope.reportingMode", "0");
3121 addConfigurationProperty("sensor.gyroscope.maxDelay", "100000");
3122 addConfigurationProperty("sensor.gyroscope.minDelay", "5000");
3123 addConfigurationProperty("sensor.gyroscope.power", "0.8");
3124}
3125
3126TEST_F(SensorInputMapperTest, GetSources) {
Arpit Singhfb706c32023-04-26 15:07:55 +00003127 SensorInputMapper& mapper = constructAndAddMapper<SensorInputMapper>();
Chris Yef59a2f42020-10-16 12:55:26 -07003128
3129 ASSERT_EQ(static_cast<uint32_t>(AINPUT_SOURCE_SENSOR), mapper.getSources());
3130}
3131
3132TEST_F(SensorInputMapperTest, ProcessAccelerometerSensor) {
3133 setAccelProperties();
3134 prepareAccelAxes();
Arpit Singhfb706c32023-04-26 15:07:55 +00003135 SensorInputMapper& mapper = constructAndAddMapper<SensorInputMapper>();
Chris Yef59a2f42020-10-16 12:55:26 -07003136
3137 ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::ACCELEROMETER,
3138 std::chrono::microseconds(10000),
3139 std::chrono::microseconds(0)));
Chris Yee14523a2020-12-19 13:46:00 -08003140 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003141 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, 20000);
3142 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, -20000);
3143 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Z, 40000);
3144 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
3145 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Chris Yef59a2f42020-10-16 12:55:26 -07003146
3147 NotifySensorArgs args;
3148 std::vector<float> values = {20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT,
3149 -20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT,
3150 40000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT};
3151
3152 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args));
3153 ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR);
3154 ASSERT_EQ(args.deviceId, DEVICE_ID);
3155 ASSERT_EQ(args.sensorType, InputDeviceSensorType::ACCELEROMETER);
3156 ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
3157 ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME);
3158 ASSERT_EQ(args.values, values);
3159 mapper.flushSensor(InputDeviceSensorType::ACCELEROMETER);
3160}
3161
3162TEST_F(SensorInputMapperTest, ProcessGyroscopeSensor) {
3163 setGyroProperties();
3164 prepareGyroAxes();
Arpit Singhfb706c32023-04-26 15:07:55 +00003165 SensorInputMapper& mapper = constructAndAddMapper<SensorInputMapper>();
Chris Yef59a2f42020-10-16 12:55:26 -07003166
3167 ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::GYROSCOPE,
3168 std::chrono::microseconds(10000),
3169 std::chrono::microseconds(0)));
Chris Yee14523a2020-12-19 13:46:00 -08003170 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003171 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RX, 20000);
3172 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RY, -20000);
3173 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RZ, 40000);
3174 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
3175 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Chris Yef59a2f42020-10-16 12:55:26 -07003176
3177 NotifySensorArgs args;
3178 std::vector<float> values = {20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT,
3179 -20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT,
3180 40000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT};
3181
3182 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args));
3183 ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR);
3184 ASSERT_EQ(args.deviceId, DEVICE_ID);
3185 ASSERT_EQ(args.sensorType, InputDeviceSensorType::GYROSCOPE);
3186 ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
3187 ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME);
3188 ASSERT_EQ(args.values, values);
3189 mapper.flushSensor(InputDeviceSensorType::GYROSCOPE);
3190}
3191
Michael Wrightd02c5b62014-02-10 15:10:22 -08003192// --- KeyboardInputMapperTest ---
3193
3194class KeyboardInputMapperTest : public InputMapperTest {
3195protected:
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003196 const std::string UNIQUE_ID = "local:0";
Zixuan Qufecb6062022-11-12 04:44:31 +00003197 const KeyboardLayoutInfo DEVICE_KEYBOARD_LAYOUT_INFO = KeyboardLayoutInfo("en-US", "qwerty");
Michael Wrighta9cf4192022-12-01 23:46:39 +00003198 void prepareDisplay(ui::Rotation orientation);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003199
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003200 void testDPadKeyRotation(KeyboardInputMapper& mapper, int32_t originalScanCode,
Arthur Hung2c9a3342019-07-23 14:18:59 +08003201 int32_t originalKeyCode, int32_t rotatedKeyCode,
3202 int32_t displayId = ADISPLAY_ID_NONE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003203};
3204
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003205/* Similar to setDisplayInfoAndReconfigure, but pre-populates all parameters except for the
3206 * orientation.
3207 */
Michael Wrighta9cf4192022-12-01 23:46:39 +00003208void KeyboardInputMapperTest::prepareDisplay(ui::Rotation orientation) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003209 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation, UNIQUE_ID,
3210 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003211}
3212
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003213void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper& mapper,
Arthur Hung2c9a3342019-07-23 14:18:59 +08003214 int32_t originalScanCode, int32_t originalKeyCode,
3215 int32_t rotatedKeyCode, int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003216 NotifyKeyArgs args;
3217
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003218 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003219 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3220 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3221 ASSERT_EQ(originalScanCode, args.scanCode);
3222 ASSERT_EQ(rotatedKeyCode, args.keyCode);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003223 ASSERT_EQ(displayId, args.displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003224
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003225 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003226 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3227 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3228 ASSERT_EQ(originalScanCode, args.scanCode);
3229 ASSERT_EQ(rotatedKeyCode, args.keyCode);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003230 ASSERT_EQ(displayId, args.displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003231}
3232
Michael Wrightd02c5b62014-02-10 15:10:22 -08003233TEST_F(KeyboardInputMapperTest, GetSources) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003234 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003235 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003236 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003237
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003238 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003239}
3240
3241TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) {
3242 const int32_t USAGE_A = 0x070004;
3243 const int32_t USAGE_UNKNOWN = 0x07ffff;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003244 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3245 mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
Chris Yea52ade12020-08-27 16:49:20 -07003246 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, POLICY_FLAG_WAKE);
3247 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, POLICY_FLAG_WAKE);
3248 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, POLICY_FLAG_WAKE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003249
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003250 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003251 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003252 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003253 // Initial metastate is AMETA_NONE.
3254 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003255
3256 // Key down by scan code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003257 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003258 NotifyKeyArgs args;
3259 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3260 ASSERT_EQ(DEVICE_ID, args.deviceId);
3261 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3262 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3263 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3264 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3265 ASSERT_EQ(KEY_HOME, args.scanCode);
3266 ASSERT_EQ(AMETA_NONE, args.metaState);
3267 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3268 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3269 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3270
3271 // Key up by scan code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003272 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003273 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3274 ASSERT_EQ(DEVICE_ID, args.deviceId);
3275 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3276 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3277 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3278 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3279 ASSERT_EQ(KEY_HOME, args.scanCode);
3280 ASSERT_EQ(AMETA_NONE, args.metaState);
3281 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3282 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3283 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3284
3285 // Key down by usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003286 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_A);
3287 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, 0, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003288 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3289 ASSERT_EQ(DEVICE_ID, args.deviceId);
3290 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3291 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3292 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3293 ASSERT_EQ(AKEYCODE_A, args.keyCode);
3294 ASSERT_EQ(0, args.scanCode);
3295 ASSERT_EQ(AMETA_NONE, args.metaState);
3296 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3297 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3298 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3299
3300 // Key up by usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003301 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_A);
3302 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003303 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3304 ASSERT_EQ(DEVICE_ID, args.deviceId);
3305 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3306 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3307 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3308 ASSERT_EQ(AKEYCODE_A, args.keyCode);
3309 ASSERT_EQ(0, args.scanCode);
3310 ASSERT_EQ(AMETA_NONE, args.metaState);
3311 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3312 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3313 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3314
3315 // Key down with unknown scan code or usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003316 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
3317 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UNKNOWN, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003318 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3319 ASSERT_EQ(DEVICE_ID, args.deviceId);
3320 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3321 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3322 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3323 ASSERT_EQ(0, args.keyCode);
3324 ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
3325 ASSERT_EQ(AMETA_NONE, args.metaState);
3326 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3327 ASSERT_EQ(0U, args.policyFlags);
3328 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3329
3330 // Key up with unknown scan code or usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003331 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
3332 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_UNKNOWN, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003333 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3334 ASSERT_EQ(DEVICE_ID, args.deviceId);
3335 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3336 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3337 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3338 ASSERT_EQ(0, args.keyCode);
3339 ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
3340 ASSERT_EQ(AMETA_NONE, args.metaState);
3341 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3342 ASSERT_EQ(0U, args.policyFlags);
3343 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3344}
3345
Vaibhav Devmuraricbba14c2022-10-10 16:54:49 +00003346TEST_F(KeyboardInputMapperTest, Process_KeyRemapping) {
3347 mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
3348 mFakeEventHub->addKey(EVENTHUB_ID, KEY_B, 0, AKEYCODE_B, 0);
3349 mFakeEventHub->addKeyRemapping(EVENTHUB_ID, AKEYCODE_A, AKEYCODE_B);
3350
3351 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003352 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Vaibhav Devmuraricbba14c2022-10-10 16:54:49 +00003353 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3354
3355 // Key down by scan code.
3356 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_A, 1);
3357 NotifyKeyArgs args;
3358 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3359 ASSERT_EQ(AKEYCODE_B, args.keyCode);
3360
3361 // Key up by scan code.
3362 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_A, 0);
3363 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3364 ASSERT_EQ(AKEYCODE_B, args.keyCode);
3365}
3366
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003367/**
3368 * Ensure that the readTime is set to the time when the EV_KEY is received.
3369 */
3370TEST_F(KeyboardInputMapperTest, Process_SendsReadTime) {
3371 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3372
3373 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003374 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003375 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3376 NotifyKeyArgs args;
3377
3378 // Key down
Harry Cutts33476232023-01-30 19:57:29 +00003379 process(mapper, ARBITRARY_TIME, /*readTime=*/12, EV_KEY, KEY_HOME, 1);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003380 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3381 ASSERT_EQ(12, args.readTime);
3382
3383 // Key up
Harry Cutts33476232023-01-30 19:57:29 +00003384 process(mapper, ARBITRARY_TIME, /*readTime=*/15, EV_KEY, KEY_HOME, 1);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003385 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3386 ASSERT_EQ(15, args.readTime);
3387}
3388
Michael Wrightd02c5b62014-02-10 15:10:22 -08003389TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003390 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFTSHIFT, 0, AKEYCODE_SHIFT_LEFT, 0);
3391 mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
Chris Yea52ade12020-08-27 16:49:20 -07003392 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, 0);
3393 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, 0);
3394 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003395
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003396 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003397 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003398 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003399
Arthur Hung95f68612022-04-07 14:08:22 +08003400 // Initial metastate is AMETA_NONE.
3401 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003402
3403 // Metakey down.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003404 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_LEFTSHIFT, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003405 NotifyKeyArgs args;
3406 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3407 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003408 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
arthurhungdcef2dc2020-08-11 14:47:50 +08003409 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertUpdateGlobalMetaStateWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003410
3411 // Key down.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003412 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_A, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003413 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3414 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003415 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003416
3417 // Key up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003418 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, KEY_A, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003419 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3420 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003421 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003422
3423 // Metakey up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003424 process(mapper, ARBITRARY_TIME + 3, READ_TIME, EV_KEY, KEY_LEFTSHIFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003425 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3426 ASSERT_EQ(AMETA_NONE, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003427 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
arthurhungdcef2dc2020-08-11 14:47:50 +08003428 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertUpdateGlobalMetaStateWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003429}
3430
3431TEST_F(KeyboardInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateDPad) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003432 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3433 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3434 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3435 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003436
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003437 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003438 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003439 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003440
Michael Wrighta9cf4192022-12-01 23:46:39 +00003441 prepareDisplay(ui::ROTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003442 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3443 KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP));
3444 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3445 KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT));
3446 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3447 KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN));
3448 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3449 KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT));
3450}
3451
3452TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003453 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3454 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3455 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3456 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003457
Michael Wrightd02c5b62014-02-10 15:10:22 -08003458 addConfigurationProperty("keyboard.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003459 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003460 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003461 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003462
Michael Wrighta9cf4192022-12-01 23:46:39 +00003463 prepareDisplay(ui::ROTATION_0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003464 ASSERT_NO_FATAL_FAILURE(
3465 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID));
3466 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3467 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3468 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3469 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3470 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3471 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003472
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003473 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003474 prepareDisplay(ui::ROTATION_90);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003475 ASSERT_NO_FATAL_FAILURE(
3476 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3477 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3478 AKEYCODE_DPAD_UP, DISPLAY_ID));
3479 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3480 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3481 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3482 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003483
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003484 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003485 prepareDisplay(ui::ROTATION_180);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003486 ASSERT_NO_FATAL_FAILURE(
3487 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3488 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3489 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3490 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3491 AKEYCODE_DPAD_UP, DISPLAY_ID));
3492 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3493 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003494
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003495 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003496 prepareDisplay(ui::ROTATION_270);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003497 ASSERT_NO_FATAL_FAILURE(
3498 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3499 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3500 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3501 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3502 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3503 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3504 AKEYCODE_DPAD_UP, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003505
3506 // Special case: if orientation changes while key is down, we still emit the same keycode
3507 // in the key up as we did in the key down.
3508 NotifyKeyArgs args;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003509 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003510 prepareDisplay(ui::ROTATION_270);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003511 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003512 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3513 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3514 ASSERT_EQ(KEY_UP, args.scanCode);
3515 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
3516
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003517 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003518 prepareDisplay(ui::ROTATION_180);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003519 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003520 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3521 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3522 ASSERT_EQ(KEY_UP, args.scanCode);
3523 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
3524}
3525
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003526TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_NotOrientationAware) {
3527 // If the keyboard is not orientation aware,
3528 // key events should not be associated with a specific display id
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003529 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003530
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003531 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003532 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003533 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003534 NotifyKeyArgs args;
3535
3536 // Display id should be ADISPLAY_ID_NONE without any display configuration.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003537 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003538 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003539 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003540 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3541 ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
3542
Michael Wrighta9cf4192022-12-01 23:46:39 +00003543 prepareDisplay(ui::ROTATION_0);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003544 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003545 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003546 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003547 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3548 ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
3549}
3550
3551TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_OrientationAware) {
3552 // If the keyboard is orientation aware,
3553 // key events should be associated with the internal viewport
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003554 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003555
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003556 addConfigurationProperty("keyboard.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003557 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003558 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003559 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003560 NotifyKeyArgs args;
3561
3562 // Display id should be ADISPLAY_ID_NONE without any display configuration.
3563 // ^--- already checked by the previous test
3564
Michael Wrighta9cf4192022-12-01 23:46:39 +00003565 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003566 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003567 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003568 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003569 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003570 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3571 ASSERT_EQ(DISPLAY_ID, args.displayId);
3572
3573 constexpr int32_t newDisplayId = 2;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003574 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003575 setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003576 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003577 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003578 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003579 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003580 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3581 ASSERT_EQ(newDisplayId, args.displayId);
3582}
3583
Michael Wrightd02c5b62014-02-10 15:10:22 -08003584TEST_F(KeyboardInputMapperTest, GetKeyCodeState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003585 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003586 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003587 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003588
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003589 mFakeEventHub->setKeyCodeState(EVENTHUB_ID, AKEYCODE_A, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003590 ASSERT_EQ(1, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003591
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003592 mFakeEventHub->setKeyCodeState(EVENTHUB_ID, AKEYCODE_A, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003593 ASSERT_EQ(0, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003594}
3595
Philip Junker4af3b3d2021-12-14 10:36:55 +01003596TEST_F(KeyboardInputMapperTest, GetKeyCodeForKeyLocation) {
3597 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003598 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Philip Junker4af3b3d2021-12-14 10:36:55 +01003599 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3600
3601 mFakeEventHub->addKeyCodeMapping(EVENTHUB_ID, AKEYCODE_Y, AKEYCODE_Z);
3602 ASSERT_EQ(AKEYCODE_Z, mapper.getKeyCodeForKeyLocation(AKEYCODE_Y))
3603 << "If a mapping is available, the result is equal to the mapping";
3604
3605 ASSERT_EQ(AKEYCODE_A, mapper.getKeyCodeForKeyLocation(AKEYCODE_A))
3606 << "If no mapping is available, the result is the key location";
3607}
3608
Michael Wrightd02c5b62014-02-10 15:10:22 -08003609TEST_F(KeyboardInputMapperTest, GetScanCodeState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003610 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003611 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003612 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003613
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003614 mFakeEventHub->setScanCodeState(EVENTHUB_ID, KEY_A, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003615 ASSERT_EQ(1, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003616
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003617 mFakeEventHub->setScanCodeState(EVENTHUB_ID, KEY_A, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003618 ASSERT_EQ(0, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003619}
3620
3621TEST_F(KeyboardInputMapperTest, MarkSupportedKeyCodes) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003622 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003623 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003624 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003625
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003626 mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003627
Michael Wrightd02c5b62014-02-10 15:10:22 -08003628 uint8_t flags[2] = { 0, 0 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07003629 ASSERT_TRUE(mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, {AKEYCODE_A, AKEYCODE_B}, flags));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003630 ASSERT_TRUE(flags[0]);
3631 ASSERT_FALSE(flags[1]);
3632}
3633
3634TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003635 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3636 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3637 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3638 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3639 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3640 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003641
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003642 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003643 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003644 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003645 // Initial metastate is AMETA_NONE.
3646 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003647
3648 // Initialization should have turned all of the lights off.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003649 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3650 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3651 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003652
3653 // Toggle caps lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003654 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3655 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003656 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3657 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3658 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003659 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003660
3661 // Toggle num lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003662 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3663 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003664 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3665 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3666 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003667 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003668
3669 // Toggle caps lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003670 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3671 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003672 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3673 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3674 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003675 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003676
3677 // Toggle scroll lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003678 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3679 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003680 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3681 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3682 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003683 ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003684
3685 // Toggle num lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003686 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3687 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003688 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3689 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3690 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003691 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003692
3693 // Toggle scroll lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003694 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3695 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003696 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3697 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3698 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003699 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003700}
3701
Chris Yea52ade12020-08-27 16:49:20 -07003702TEST_F(KeyboardInputMapperTest, NoMetaStateWhenMetaKeysNotPresent) {
3703 mFakeEventHub->addKey(EVENTHUB_ID, BTN_A, 0, AKEYCODE_BUTTON_A, 0);
3704 mFakeEventHub->addKey(EVENTHUB_ID, BTN_B, 0, AKEYCODE_BUTTON_B, 0);
3705 mFakeEventHub->addKey(EVENTHUB_ID, BTN_X, 0, AKEYCODE_BUTTON_X, 0);
3706 mFakeEventHub->addKey(EVENTHUB_ID, BTN_Y, 0, AKEYCODE_BUTTON_Y, 0);
3707
3708 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003709 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Chris Yea52ade12020-08-27 16:49:20 -07003710 AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
3711
Chris Yea52ade12020-08-27 16:49:20 -07003712 // Meta state should be AMETA_NONE after reset
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003713 std::list<NotifyArgs> unused = mapper.reset(ARBITRARY_TIME);
Chris Yea52ade12020-08-27 16:49:20 -07003714 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3715 // Meta state should be AMETA_NONE with update, as device doesn't have the keys.
3716 mapper.updateMetaState(AKEYCODE_NUM_LOCK);
3717 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3718
3719 NotifyKeyArgs args;
3720 // Press button "A"
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003721 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_A, 1);
Chris Yea52ade12020-08-27 16:49:20 -07003722 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3723 ASSERT_EQ(AMETA_NONE, args.metaState);
3724 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3725 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3726 ASSERT_EQ(AKEYCODE_BUTTON_A, args.keyCode);
3727
3728 // Button up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003729 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, BTN_A, 0);
Chris Yea52ade12020-08-27 16:49:20 -07003730 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3731 ASSERT_EQ(AMETA_NONE, args.metaState);
3732 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3733 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3734 ASSERT_EQ(AKEYCODE_BUTTON_A, args.keyCode);
3735}
3736
Arthur Hung2c9a3342019-07-23 14:18:59 +08003737TEST_F(KeyboardInputMapperTest, Configure_AssignsDisplayPort) {
3738 // keyboard 1.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003739 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3740 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3741 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3742 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003743
3744 // keyboard 2.
3745 const std::string USB2 = "USB2";
arthurhungdcef2dc2020-08-11 14:47:50 +08003746 const std::string DEVICE_NAME2 = "KEYBOARD2";
Arthur Hung2c9a3342019-07-23 14:18:59 +08003747 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003748 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
arthurhungdcef2dc2020-08-11 14:47:50 +08003749 std::shared_ptr<InputDevice> device2 =
3750 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07003751 ftl::Flags<InputDeviceClass>(0));
arthurhungdcef2dc2020-08-11 14:47:50 +08003752
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003753 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3754 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3755 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3756 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003757
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003758 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003759 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003760 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003761
Arpit Singh67ca6842023-04-26 14:43:16 +00003762 device2->addEmptyEventHubDevice(SECOND_EVENTHUB_ID);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003763 KeyboardInputMapper& mapper2 =
Arpit Singh67ca6842023-04-26 14:43:16 +00003764 device2->constructAndAddMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID,
3765 mFakePolicy
3766 ->getReaderConfiguration(),
3767 AINPUT_SOURCE_KEYBOARD,
3768 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003769 std::list<NotifyArgs> unused =
3770 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00003771 /*changes=*/{});
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003772 unused += device2->reset(ARBITRARY_TIME);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003773
3774 // Prepared displays and associated info.
3775 constexpr uint8_t hdmi1 = 0;
3776 constexpr uint8_t hdmi2 = 1;
3777 const std::string SECONDARY_UNIQUE_ID = "local:1";
3778
3779 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
3780 mFakePolicy->addInputPortAssociation(USB2, hdmi2);
3781
3782 // No associated display viewport found, should disable the device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003783 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00003784 InputReaderConfiguration::Change::DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003785 ASSERT_FALSE(device2->isEnabled());
3786
3787 // Prepare second display.
3788 constexpr int32_t newDisplayId = 2;
Michael Wrighta9cf4192022-12-01 23:46:39 +00003789 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003790 UNIQUE_ID, hdmi1, ViewportType::INTERNAL);
Michael Wrighta9cf4192022-12-01 23:46:39 +00003791 setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003792 SECONDARY_UNIQUE_ID, hdmi2, ViewportType::EXTERNAL);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003793 // Default device will reconfigure above, need additional reconfiguration for another device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003794 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00003795 InputReaderConfiguration::Change::DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003796
3797 // Device should be enabled after the associated display is found.
3798 ASSERT_TRUE(mDevice->isEnabled());
3799 ASSERT_TRUE(device2->isEnabled());
3800
3801 // Test pad key events
3802 ASSERT_NO_FATAL_FAILURE(
3803 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID));
3804 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3805 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3806 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3807 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3808 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3809 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3810
3811 ASSERT_NO_FATAL_FAILURE(
3812 testDPadKeyRotation(mapper2, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, newDisplayId));
3813 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3814 AKEYCODE_DPAD_RIGHT, newDisplayId));
3815 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3816 AKEYCODE_DPAD_DOWN, newDisplayId));
3817 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3818 AKEYCODE_DPAD_LEFT, newDisplayId));
3819}
Michael Wrightd02c5b62014-02-10 15:10:22 -08003820
arthurhungc903df12020-08-11 15:08:42 +08003821TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleAfterReattach) {
3822 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3823 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3824 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3825 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3826 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3827 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3828
3829 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003830 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
arthurhungc903df12020-08-11 15:08:42 +08003831 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003832 // Initial metastate is AMETA_NONE.
3833 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
arthurhungc903df12020-08-11 15:08:42 +08003834
3835 // Initialization should have turned all of the lights off.
3836 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3837 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3838 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3839
3840 // Toggle caps lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003841 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3842 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003843 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3844 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
3845
3846 // Toggle num lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003847 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3848 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003849 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3850 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState());
3851
3852 // Toggle scroll lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003853 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3854 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003855 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3856 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
3857
3858 mFakeEventHub->removeDevice(EVENTHUB_ID);
3859 mReader->loopOnce();
3860
3861 // keyboard 2 should default toggle keys.
3862 const std::string USB2 = "USB2";
3863 const std::string DEVICE_NAME2 = "KEYBOARD2";
3864 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
3865 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
3866 std::shared_ptr<InputDevice> device2 =
3867 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07003868 ftl::Flags<InputDeviceClass>(0));
arthurhungc903df12020-08-11 15:08:42 +08003869 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3870 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/);
3871 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3872 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3873 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3874 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3875
Arpit Singh67ca6842023-04-26 14:43:16 +00003876 device2->addEmptyEventHubDevice(SECOND_EVENTHUB_ID);
arthurhung6fe95782020-10-05 22:41:16 +08003877 KeyboardInputMapper& mapper2 =
Arpit Singh67ca6842023-04-26 14:43:16 +00003878 device2->constructAndAddMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID,
3879 mFakePolicy
3880 ->getReaderConfiguration(),
3881 AINPUT_SOURCE_KEYBOARD,
3882 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003883 std::list<NotifyArgs> unused =
3884 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00003885 /*changes=*/{});
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003886 unused += device2->reset(ARBITRARY_TIME);
arthurhungc903df12020-08-11 15:08:42 +08003887
3888 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_CAPSL));
3889 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_NUML));
3890 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_SCROLLL));
arthurhung6fe95782020-10-05 22:41:16 +08003891 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON,
3892 mapper2.getMetaState());
arthurhungc903df12020-08-11 15:08:42 +08003893}
3894
Arthur Hungcb40a002021-08-03 14:31:01 +00003895TEST_F(KeyboardInputMapperTest, Process_toggleCapsLockState) {
3896 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3897 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3898 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3899
3900 // Suppose we have two mappers. (DPAD + KEYBOARD)
Arpit Singh67ca6842023-04-26 14:43:16 +00003901 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_DPAD,
Arthur Hungcb40a002021-08-03 14:31:01 +00003902 AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
3903 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003904 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Arthur Hungcb40a002021-08-03 14:31:01 +00003905 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003906 // Initial metastate is AMETA_NONE.
3907 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Arthur Hungcb40a002021-08-03 14:31:01 +00003908
3909 mReader->toggleCapsLockState(DEVICE_ID);
3910 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
3911}
3912
Arthur Hungfb3cc112022-04-13 07:39:50 +00003913TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleInMultiDevices) {
3914 // keyboard 1.
3915 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3916 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3917 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3918 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3919 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3920 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3921
3922 KeyboardInputMapper& mapper1 =
Arpit Singh67ca6842023-04-26 14:43:16 +00003923 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Arthur Hungfb3cc112022-04-13 07:39:50 +00003924 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3925
3926 // keyboard 2.
3927 const std::string USB2 = "USB2";
3928 const std::string DEVICE_NAME2 = "KEYBOARD2";
3929 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
3930 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
3931 std::shared_ptr<InputDevice> device2 =
3932 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
3933 ftl::Flags<InputDeviceClass>(0));
3934 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3935 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/);
3936 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3937 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3938 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3939 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3940
Arpit Singh67ca6842023-04-26 14:43:16 +00003941 device2->addEmptyEventHubDevice(SECOND_EVENTHUB_ID);
Arthur Hungfb3cc112022-04-13 07:39:50 +00003942 KeyboardInputMapper& mapper2 =
Arpit Singh67ca6842023-04-26 14:43:16 +00003943 device2->constructAndAddMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID,
3944 mFakePolicy
3945 ->getReaderConfiguration(),
3946 AINPUT_SOURCE_KEYBOARD,
3947 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003948 std::list<NotifyArgs> unused =
3949 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00003950 /*changes=*/{});
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003951 unused += device2->reset(ARBITRARY_TIME);
Arthur Hungfb3cc112022-04-13 07:39:50 +00003952
Arthur Hung95f68612022-04-07 14:08:22 +08003953 // Initial metastate is AMETA_NONE.
3954 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3955 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3956
3957 // Toggle num lock on and off.
3958 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3959 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Arthur Hungfb3cc112022-04-13 07:39:50 +00003960 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3961 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper1.getMetaState());
3962 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper2.getMetaState());
3963
3964 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3965 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
3966 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3967 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3968 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3969
3970 // Toggle caps lock on and off.
3971 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3972 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
3973 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3974 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper1.getMetaState());
3975 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper2.getMetaState());
3976
3977 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3978 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
3979 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3980 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3981 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3982
3983 // Toggle scroll lock on and off.
3984 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3985 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
3986 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3987 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper1.getMetaState());
3988 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper2.getMetaState());
3989
3990 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3991 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
3992 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3993 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3994 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3995}
3996
Arthur Hung2141d542022-08-23 07:45:21 +00003997TEST_F(KeyboardInputMapperTest, Process_DisabledDevice) {
3998 const int32_t USAGE_A = 0x070004;
3999 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
4000 mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
4001
4002 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00004003 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Arthur Hung2141d542022-08-23 07:45:21 +00004004 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
4005 // Key down by scan code.
4006 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
4007 NotifyKeyArgs args;
4008 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4009 ASSERT_EQ(DEVICE_ID, args.deviceId);
4010 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
4011 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
4012 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
4013 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
4014 ASSERT_EQ(KEY_HOME, args.scanCode);
4015 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
4016
4017 // Disable device, it should synthesize cancellation events for down events.
4018 mFakePolicy->addDisabledDevice(DEVICE_ID);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004019 configureDevice(InputReaderConfiguration::Change::ENABLED_STATE);
Arthur Hung2141d542022-08-23 07:45:21 +00004020
4021 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4022 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
4023 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
4024 ASSERT_EQ(KEY_HOME, args.scanCode);
4025 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED, args.flags);
4026}
4027
Zixuan Qufecb6062022-11-12 04:44:31 +00004028TEST_F(KeyboardInputMapperTest, Configure_AssignKeyboardLayoutInfo) {
Arpit Singh67ca6842023-04-26 14:43:16 +00004029 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
4030 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Zixuan Qufecb6062022-11-12 04:44:31 +00004031 std::list<NotifyArgs> unused =
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004032 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
4033 /*changes=*/{});
Zixuan Qufecb6062022-11-12 04:44:31 +00004034
Vaibhav Devmurari0a6fee82023-04-11 18:53:04 +00004035 uint32_t generation = mReader->getContext()->getGeneration();
Zixuan Qufecb6062022-11-12 04:44:31 +00004036 mFakePolicy->addKeyboardLayoutAssociation(DEVICE_LOCATION, DEVICE_KEYBOARD_LAYOUT_INFO);
4037
4038 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004039 InputReaderConfiguration::Change::KEYBOARD_LAYOUT_ASSOCIATION);
Zixuan Qufecb6062022-11-12 04:44:31 +00004040
4041 InputDeviceInfo deviceInfo = mDevice->getDeviceInfo();
4042 ASSERT_EQ(DEVICE_KEYBOARD_LAYOUT_INFO.languageTag,
4043 deviceInfo.getKeyboardLayoutInfo()->languageTag);
4044 ASSERT_EQ(DEVICE_KEYBOARD_LAYOUT_INFO.layoutType,
4045 deviceInfo.getKeyboardLayoutInfo()->layoutType);
Vaibhav Devmurari0a6fee82023-04-11 18:53:04 +00004046 ASSERT_TRUE(mReader->getContext()->getGeneration() != generation);
4047
4048 // Call change layout association with the same values: Generation shouldn't change
4049 generation = mReader->getContext()->getGeneration();
4050 mFakePolicy->addKeyboardLayoutAssociation(DEVICE_LOCATION, DEVICE_KEYBOARD_LAYOUT_INFO);
4051 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
4052 InputReaderConfiguration::Change::KEYBOARD_LAYOUT_ASSOCIATION);
4053 ASSERT_TRUE(mReader->getContext()->getGeneration() == generation);
Zixuan Qufecb6062022-11-12 04:44:31 +00004054}
4055
Vaibhav Devmurari7fb41132023-01-02 13:30:26 +00004056TEST_F(KeyboardInputMapperTest, LayoutInfoCorrectlyMapped) {
4057 mFakeEventHub->setRawLayoutInfo(EVENTHUB_ID,
4058 RawLayoutInfo{.languageTag = "en", .layoutType = "extended"});
4059
4060 // Configuration
Arpit Singh67ca6842023-04-26 14:43:16 +00004061 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Vaibhav Devmurari7fb41132023-01-02 13:30:26 +00004062 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
4063 InputReaderConfiguration config;
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004064 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
Vaibhav Devmurari7fb41132023-01-02 13:30:26 +00004065
4066 ASSERT_EQ("en", mDevice->getDeviceInfo().getKeyboardLayoutInfo()->languageTag);
4067 ASSERT_EQ("extended", mDevice->getDeviceInfo().getKeyboardLayoutInfo()->layoutType);
4068}
4069
Justin Chung71ddb432023-03-27 04:29:07 +00004070TEST_F(KeyboardInputMapperTest, Process_GesureEventToSetFlagKeepTouchMode) {
4071 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, POLICY_FLAG_GESTURE);
4072 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00004073 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Justin Chung71ddb432023-03-27 04:29:07 +00004074 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
4075 NotifyKeyArgs args;
4076
4077 // Key down
4078 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_LEFT, 1);
4079 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4080 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_KEEP_TOUCH_MODE, args.flags);
4081}
4082
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004083// --- KeyboardInputMapperTest_ExternalDevice ---
4084
4085class KeyboardInputMapperTest_ExternalDevice : public InputMapperTest {
4086protected:
Chris Yea52ade12020-08-27 16:49:20 -07004087 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004088};
4089
4090TEST_F(KeyboardInputMapperTest_ExternalDevice, WakeBehavior) {
Vaibhav Devmurari16257862023-03-06 10:06:32 +00004091 // For external devices, keys will trigger wake on key down. Media keys should also trigger
4092 // wake if triggered from external devices.
Powei Fengd041c5d2019-05-03 17:11:33 -07004093
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004094 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, 0);
4095 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, 0);
4096 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAYPAUSE, 0, AKEYCODE_MEDIA_PLAY_PAUSE,
4097 POLICY_FLAG_WAKE);
Powei Fengd041c5d2019-05-03 17:11:33 -07004098
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004099 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00004100 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004101 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Powei Fengd041c5d2019-05-03 17:11:33 -07004102
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004103 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004104 NotifyKeyArgs args;
4105 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4106 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4107
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004108 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004109 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4110 ASSERT_EQ(uint32_t(0), args.policyFlags);
4111
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004112 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAY, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004113 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Vaibhav Devmurari16257862023-03-06 10:06:32 +00004114 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
Powei Fengd041c5d2019-05-03 17:11:33 -07004115
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004116 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAY, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004117 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4118 ASSERT_EQ(uint32_t(0), args.policyFlags);
4119
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004120 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAYPAUSE, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004121 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4122 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4123
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004124 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAYPAUSE, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004125 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4126 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4127}
4128
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004129TEST_F(KeyboardInputMapperTest_ExternalDevice, DoNotWakeByDefaultBehavior) {
Powei Fengd041c5d2019-05-03 17:11:33 -07004130 // Tv Remote key's wake behavior is prescribed by the keylayout file.
Powei Fengd041c5d2019-05-03 17:11:33 -07004131
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004132 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
4133 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
4134 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, POLICY_FLAG_WAKE);
Powei Fengd041c5d2019-05-03 17:11:33 -07004135
Powei Fengd041c5d2019-05-03 17:11:33 -07004136 addConfigurationProperty("keyboard.doNotWakeByDefault", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004137 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00004138 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004139 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Powei Fengd041c5d2019-05-03 17:11:33 -07004140
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004141 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004142 NotifyKeyArgs args;
4143 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4144 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4145
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004146 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004147 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4148 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4149
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004150 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_DOWN, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004151 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4152 ASSERT_EQ(uint32_t(0), args.policyFlags);
4153
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004154 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_DOWN, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004155 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4156 ASSERT_EQ(uint32_t(0), args.policyFlags);
4157
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004158 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAY, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004159 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4160 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4161
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004162 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAY, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004163 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4164 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4165}
4166
Byoungho Jungda10dd32023-10-06 17:03:45 +09004167// --- CursorInputMapperTestBase ---
Michael Wrightd02c5b62014-02-10 15:10:22 -08004168
Byoungho Jungda10dd32023-10-06 17:03:45 +09004169class CursorInputMapperTestBase : public InputMapperTest {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004170protected:
4171 static const int32_t TRACKBALL_MOVEMENT_THRESHOLD;
4172
Michael Wright17db18e2020-06-26 20:51:44 +01004173 std::shared_ptr<FakePointerController> mFakePointerController;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004174
Chris Yea52ade12020-08-27 16:49:20 -07004175 void SetUp() override {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004176 InputMapperTest::SetUp();
4177
Michael Wright17db18e2020-06-26 20:51:44 +01004178 mFakePointerController = std::make_shared<FakePointerController>();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00004179 mFakePolicy->setPointerController(mFakePointerController);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004180 }
4181
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004182 void testMotionRotation(CursorInputMapper& mapper, int32_t originalX, int32_t originalY,
4183 int32_t rotatedX, int32_t rotatedY);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004184
Michael Wrighta9cf4192022-12-01 23:46:39 +00004185 void prepareDisplay(ui::Rotation orientation) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004186 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation,
4187 DISPLAY_UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
4188 }
4189
4190 void prepareSecondaryDisplay() {
4191 setDisplayInfoAndReconfigure(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +00004192 ui::ROTATION_0, SECONDARY_DISPLAY_UNIQUE_ID, NO_PORT,
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004193 ViewportType::EXTERNAL);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004194 }
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004195
4196 static void assertCursorPointerCoords(const PointerCoords& coords, float x, float y,
4197 float pressure) {
4198 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(coords, x, y, pressure, 0.0f, 0.0f, 0.0f, 0.0f,
4199 0.0f, 0.0f, 0.0f, EPSILON));
4200 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004201};
4202
Byoungho Jungda10dd32023-10-06 17:03:45 +09004203const int32_t CursorInputMapperTestBase::TRACKBALL_MOVEMENT_THRESHOLD = 6;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004204
Byoungho Jungda10dd32023-10-06 17:03:45 +09004205void CursorInputMapperTestBase::testMotionRotation(CursorInputMapper& mapper, int32_t originalX,
4206 int32_t originalY, int32_t rotatedX,
4207 int32_t rotatedY) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004208 NotifyMotionArgs args;
4209
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004210 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, originalX);
4211 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, originalY);
4212 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004213 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4214 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004215 ASSERT_NO_FATAL_FAILURE(
4216 assertCursorPointerCoords(args.pointerCoords[0],
4217 float(rotatedX) / TRACKBALL_MOVEMENT_THRESHOLD,
4218 float(rotatedY) / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004219}
4220
Byoungho Jungda10dd32023-10-06 17:03:45 +09004221// --- CursorInputMapperTest ---
4222
4223class CursorInputMapperTest : public CursorInputMapperTestBase {
4224protected:
4225 void SetUp() override {
4226 input_flags::enable_pointer_choreographer(false);
4227 CursorInputMapperTestBase::SetUp();
4228 }
4229};
4230
Michael Wrightd02c5b62014-02-10 15:10:22 -08004231TEST_F(CursorInputMapperTest, WhenModeIsPointer_GetSources_ReturnsMouse) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004232 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00004233 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004234
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004235 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004236}
4237
4238TEST_F(CursorInputMapperTest, WhenModeIsNavigation_GetSources_ReturnsTrackball) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004239 addConfigurationProperty("cursor.mode", "navigation");
Arpit Singhe036ad72023-04-27 12:48:15 +00004240 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004241
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004242 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004243}
4244
4245TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeFromPointerController) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004246 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00004247 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004248
4249 InputDeviceInfo info;
Harry Cuttsd02ea102023-03-17 18:21:30 +00004250 mapper.populateDeviceInfo(info);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004251
4252 // Initially there may not be a valid motion range.
Yi Kong9b14ac62018-07-17 13:48:38 -07004253 ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE));
4254 ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004255 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
4256 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE, 0.0f, 1.0f, 0.0f, 0.0f));
4257
4258 // When the bounds are set, then there should be a valid motion range.
4259 mFakePointerController->setBounds(1, 2, 800 - 1, 480 - 1);
Byoungho Jungda10dd32023-10-06 17:03:45 +09004260 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004261
4262 InputDeviceInfo info2;
Harry Cuttsd02ea102023-03-17 18:21:30 +00004263 mapper.populateDeviceInfo(info2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004264
4265 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
4266 AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE,
4267 1, 800 - 1, 0.0f, 0.0f));
4268 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
4269 AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE,
4270 2, 480 - 1, 0.0f, 0.0f));
4271 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
4272 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE,
4273 0.0f, 1.0f, 0.0f, 0.0f));
4274}
4275
4276TEST_F(CursorInputMapperTest, WhenModeIsNavigation_PopulateDeviceInfo_ReturnsScaledRange) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004277 addConfigurationProperty("cursor.mode", "navigation");
Arpit Singhe036ad72023-04-27 12:48:15 +00004278 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004279
4280 InputDeviceInfo info;
Harry Cuttsd02ea102023-03-17 18:21:30 +00004281 mapper.populateDeviceInfo(info);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004282
4283 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
4284 AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_TRACKBALL,
4285 -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
4286 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
4287 AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_TRACKBALL,
4288 -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
4289 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
4290 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TRACKBALL,
4291 0.0f, 1.0f, 0.0f, 0.0f));
4292}
4293
4294TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004295 addConfigurationProperty("cursor.mode", "navigation");
Arpit Singhe036ad72023-04-27 12:48:15 +00004296 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004297
arthurhungdcef2dc2020-08-11 14:47:50 +08004298 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004299
4300 NotifyMotionArgs args;
4301
4302 // Button press.
4303 // Mostly testing non x/y behavior here so we don't need to check again elsewhere.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004304 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4305 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004306 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4307 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
4308 ASSERT_EQ(DEVICE_ID, args.deviceId);
4309 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4310 ASSERT_EQ(uint32_t(0), args.policyFlags);
4311 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
4312 ASSERT_EQ(0, args.flags);
4313 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4314 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
4315 ASSERT_EQ(0, args.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004316 ASSERT_EQ(uint32_t(1), args.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004317 ASSERT_EQ(0, args.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07004318 ASSERT_EQ(ToolType::MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004319 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004320 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4321 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4322 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4323
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004324 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4325 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
4326 ASSERT_EQ(DEVICE_ID, args.deviceId);
4327 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4328 ASSERT_EQ(uint32_t(0), args.policyFlags);
4329 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
4330 ASSERT_EQ(0, args.flags);
4331 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4332 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
4333 ASSERT_EQ(0, args.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004334 ASSERT_EQ(uint32_t(1), args.getPointerCount());
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004335 ASSERT_EQ(0, args.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07004336 ASSERT_EQ(ToolType::MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004337 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004338 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4339 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4340 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4341
Michael Wrightd02c5b62014-02-10 15:10:22 -08004342 // Button release. Should have same down time.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004343 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4344 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004345 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4346 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
4347 ASSERT_EQ(DEVICE_ID, args.deviceId);
4348 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4349 ASSERT_EQ(uint32_t(0), args.policyFlags);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004350 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
4351 ASSERT_EQ(0, args.flags);
4352 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4353 ASSERT_EQ(0, args.buttonState);
4354 ASSERT_EQ(0, args.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004355 ASSERT_EQ(uint32_t(1), args.getPointerCount());
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004356 ASSERT_EQ(0, args.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07004357 ASSERT_EQ(ToolType::MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004358 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004359 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4360 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4361 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4362
4363 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4364 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
4365 ASSERT_EQ(DEVICE_ID, args.deviceId);
4366 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4367 ASSERT_EQ(uint32_t(0), args.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004368 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
4369 ASSERT_EQ(0, args.flags);
4370 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4371 ASSERT_EQ(0, args.buttonState);
4372 ASSERT_EQ(0, args.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004373 ASSERT_EQ(uint32_t(1), args.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004374 ASSERT_EQ(0, args.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07004375 ASSERT_EQ(ToolType::MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004376 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004377 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4378 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4379 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4380}
4381
4382TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentXYUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004383 addConfigurationProperty("cursor.mode", "navigation");
Arpit Singhe036ad72023-04-27 12:48:15 +00004384 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004385
4386 NotifyMotionArgs args;
4387
4388 // Motion in X but not Y.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004389 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4390 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004391 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4392 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004393 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4394 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f,
4395 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004396
4397 // Motion in Y but not X.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004398 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, -2);
4399 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004400 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4401 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004402 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f,
4403 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004404}
4405
4406TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004407 addConfigurationProperty("cursor.mode", "navigation");
Arpit Singhe036ad72023-04-27 12:48:15 +00004408 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004409
4410 NotifyMotionArgs args;
4411
4412 // Button press.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004413 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4414 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004415 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4416 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004417 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004418
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004419 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4420 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004421 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004422
Michael Wrightd02c5b62014-02-10 15:10:22 -08004423 // Button release.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004424 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4425 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004426 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004427 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004428 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004429
4430 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004431 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004432 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004433}
4434
4435TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004436 addConfigurationProperty("cursor.mode", "navigation");
Arpit Singhe036ad72023-04-27 12:48:15 +00004437 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004438
4439 NotifyMotionArgs args;
4440
4441 // Combined X, Y and Button.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004442 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4443 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, -2);
4444 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4445 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004446 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4447 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004448 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4449 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4450 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004451
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004452 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4453 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004454 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4455 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4456 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004457
Michael Wrightd02c5b62014-02-10 15:10:22 -08004458 // Move X, Y a bit while pressed.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004459 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 2);
4460 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 1);
4461 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004462 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4463 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004464 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4465 2.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4466 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004467
4468 // Release Button.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004469 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4470 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004471 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004472 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004473 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004474
4475 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004476 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004477 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004478}
4479
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004480TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldNotRotateMotions) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004481 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004482 addConfigurationProperty("cursor.mode", "navigation");
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004483 // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
4484 // need to be rotated.
4485 addConfigurationProperty("cursor.orientationAware", "1");
Arpit Singhe036ad72023-04-27 12:48:15 +00004486 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004487
Michael Wrighta9cf4192022-12-01 23:46:39 +00004488 prepareDisplay(ui::ROTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004489 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1));
4490 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1));
4491 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0));
4492 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, -1));
4493 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1));
4494 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
4495 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0));
4496 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1));
4497}
4498
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004499TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldRotateMotions) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004500 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004501 addConfigurationProperty("cursor.mode", "navigation");
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004502 // Since InputReader works in the un-rotated coordinate space, only devices that are not
4503 // orientation-aware are affected by display rotation.
Arpit Singhe036ad72023-04-27 12:48:15 +00004504 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004505
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004506 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00004507 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004508 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1));
4509 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1));
4510 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0));
4511 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, -1));
4512 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1));
4513 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
4514 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0));
4515 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1));
4516
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004517 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00004518 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004519 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, -1, 0));
4520 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, -1, 1));
4521 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 0, 1));
4522 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, 1));
4523 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 1, 0));
4524 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, -1));
4525 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, -1));
4526 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, -1));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004527
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004528 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00004529 prepareDisplay(ui::ROTATION_180);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004530 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, -1));
4531 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, -1, -1));
4532 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, -1, 0));
4533 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, -1, 1));
4534 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, 1));
4535 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, 1));
4536 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 1, 0));
4537 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, -1));
4538
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004539 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00004540 prepareDisplay(ui::ROTATION_270);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004541 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 1, 0));
4542 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, -1));
4543 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 0, -1));
4544 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, -1, -1));
4545 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, -1, 0));
4546 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, 1));
4547 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, 1));
4548 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, 1));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004549}
4550
4551TEST_F(CursorInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004552 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00004553 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004554
4555 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
4556 mFakePointerController->setPosition(100, 200);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004557
4558 NotifyMotionArgs motionArgs;
4559 NotifyKeyArgs keyArgs;
4560
4561 // press BTN_LEFT, release BTN_LEFT
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004562 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_LEFT, 1);
4563 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004564 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4565 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4566 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004567 ASSERT_NO_FATAL_FAILURE(
4568 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004569
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004570 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4571 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4572 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004573 ASSERT_NO_FATAL_FAILURE(
4574 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004575
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004576 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_LEFT, 0);
4577 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004578 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004579 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004580 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004581 ASSERT_NO_FATAL_FAILURE(
4582 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004583
4584 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004585 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004586 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004587 ASSERT_NO_FATAL_FAILURE(
4588 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004589
4590 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004591 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004592 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004593 ASSERT_NO_FATAL_FAILURE(
4594 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004595
4596 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004597 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_RIGHT, 1);
4598 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 1);
4599 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004600 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4601 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4602 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
Siarhei Vishniakou10ce1572023-03-15 09:15:21 -07004603 motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004604 ASSERT_NO_FATAL_FAILURE(
4605 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004606
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004607 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4608 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4609 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004610 ASSERT_NO_FATAL_FAILURE(
4611 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004612
4613 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4614 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4615 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
Siarhei Vishniakou10ce1572023-03-15 09:15:21 -07004616 motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004617 ASSERT_NO_FATAL_FAILURE(
4618 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004619
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004620 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_RIGHT, 0);
4621 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004622 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004623 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004624 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004625 ASSERT_NO_FATAL_FAILURE(
4626 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004627
4628 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004629 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004630 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004631 ASSERT_NO_FATAL_FAILURE(
4632 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004633
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004634 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
4635 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004636 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004637 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4638 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004639 ASSERT_NO_FATAL_FAILURE(
4640 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004641 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
4642 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004643
4644 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004645 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004646 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004647 ASSERT_NO_FATAL_FAILURE(
4648 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004649
Michael Wrightd02c5b62014-02-10 15:10:22 -08004650 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4651 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004652 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004653 ASSERT_NO_FATAL_FAILURE(
4654 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004655
4656 // press BTN_BACK, release BTN_BACK
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004657 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_BACK, 1);
4658 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004659 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4660 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4661 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004662
Michael Wrightd02c5b62014-02-10 15:10:22 -08004663 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004664 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004665 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004666 ASSERT_NO_FATAL_FAILURE(
4667 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004668
4669 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4670 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4671 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004672 ASSERT_NO_FATAL_FAILURE(
4673 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004674
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004675 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_BACK, 0);
4676 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004677 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004678 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004679 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004680 ASSERT_NO_FATAL_FAILURE(
4681 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004682
4683 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004684 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004685 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004686
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004687 ASSERT_NO_FATAL_FAILURE(
4688 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004689 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4690 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4691 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4692
4693 // press BTN_SIDE, release BTN_SIDE
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004694 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_SIDE, 1);
4695 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004696 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4697 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4698 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004699
Michael Wrightd02c5b62014-02-10 15:10:22 -08004700 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004701 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004702 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004703 ASSERT_NO_FATAL_FAILURE(
4704 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004705
4706 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4707 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4708 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004709 ASSERT_NO_FATAL_FAILURE(
4710 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004711
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004712 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_SIDE, 0);
4713 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004714 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004715 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004716 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004717 ASSERT_NO_FATAL_FAILURE(
4718 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004719
4720 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4721 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4722 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004723 ASSERT_NO_FATAL_FAILURE(
4724 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004725
Michael Wrightd02c5b62014-02-10 15:10:22 -08004726 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4727 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4728 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4729
4730 // press BTN_FORWARD, release BTN_FORWARD
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004731 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_FORWARD, 1);
4732 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004733 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4734 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4735 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004736
Michael Wrightd02c5b62014-02-10 15:10:22 -08004737 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004738 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004739 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004740 ASSERT_NO_FATAL_FAILURE(
4741 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004742
4743 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4744 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4745 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004746 ASSERT_NO_FATAL_FAILURE(
4747 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004748
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004749 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_FORWARD, 0);
4750 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004751 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004752 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004753 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004754 ASSERT_NO_FATAL_FAILURE(
4755 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004756
4757 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4758 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4759 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004760 ASSERT_NO_FATAL_FAILURE(
4761 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004762
Michael Wrightd02c5b62014-02-10 15:10:22 -08004763 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4764 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4765 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4766
4767 // press BTN_EXTRA, release BTN_EXTRA
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004768 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_EXTRA, 1);
4769 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004770 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4771 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4772 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004773
Michael Wrightd02c5b62014-02-10 15:10:22 -08004774 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004775 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004776 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004777 ASSERT_NO_FATAL_FAILURE(
4778 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004779
4780 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4781 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4782 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004783 ASSERT_NO_FATAL_FAILURE(
4784 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004785
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004786 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_EXTRA, 0);
4787 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004788 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004789 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004790 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004791 ASSERT_NO_FATAL_FAILURE(
4792 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004793
4794 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4795 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4796 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004797 ASSERT_NO_FATAL_FAILURE(
4798 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004799
Michael Wrightd02c5b62014-02-10 15:10:22 -08004800 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4801 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4802 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4803}
4804
4805TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerAround) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004806 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00004807 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004808
4809 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
4810 mFakePointerController->setPosition(100, 200);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004811
4812 NotifyMotionArgs args;
4813
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004814 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4815 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4816 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004817 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004818 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4819 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4820 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4821 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
Harry Cuttsce86cc32022-12-14 20:36:33 +00004822 ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(110.0f, 220.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004823}
4824
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00004825/**
4826 * When Pointer Capture is enabled, we expect to report unprocessed relative movements, so any
4827 * pointer acceleration or speed processing should not be applied.
4828 */
4829TEST_F(CursorInputMapperTest, PointerCaptureDisablesVelocityProcessing) {
4830 addConfigurationProperty("cursor.mode", "pointer");
Harry Cutts33476232023-01-30 19:57:29 +00004831 const VelocityControlParameters testParams(/*scale=*/5.f, /*low threshold=*/0.f,
4832 /*high threshold=*/100.f, /*acceleration=*/10.f);
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00004833 mFakePolicy->setVelocityControlParams(testParams);
Arpit Singhe036ad72023-04-27 12:48:15 +00004834 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00004835
4836 NotifyDeviceResetArgs resetArgs;
4837 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
4838 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
4839 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4840
4841 NotifyMotionArgs args;
4842
4843 // Move and verify scale is applied.
4844 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4845 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4846 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4847 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4848 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4849 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4850 const float relX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
4851 const float relY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
4852 ASSERT_GT(relX, 10);
4853 ASSERT_GT(relY, 20);
4854
4855 // Enable Pointer Capture
4856 mFakePolicy->setPointerCapture(true);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004857 configureDevice(InputReaderConfiguration::Change::POINTER_CAPTURE);
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00004858 NotifyPointerCaptureChangedArgs captureArgs;
4859 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
4860 ASSERT_TRUE(captureArgs.request.enable);
4861
4862 // Move and verify scale is not applied.
4863 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4864 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4865 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4866 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4867 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4868 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4869 ASSERT_EQ(10, args.pointerCoords[0].getX());
4870 ASSERT_EQ(20, args.pointerCoords[0].getY());
4871}
4872
Prabir Pradhan208360b2022-06-24 18:37:04 +00004873TEST_F(CursorInputMapperTest, PointerCaptureDisablesOrientationChanges) {
4874 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00004875 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Prabir Pradhan208360b2022-06-24 18:37:04 +00004876
4877 NotifyDeviceResetArgs resetArgs;
4878 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
4879 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
4880 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4881
4882 // Ensure the display is rotated.
Michael Wrighta9cf4192022-12-01 23:46:39 +00004883 prepareDisplay(ui::ROTATION_90);
Prabir Pradhan208360b2022-06-24 18:37:04 +00004884
4885 NotifyMotionArgs args;
4886
4887 // Verify that the coordinates are rotated.
4888 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4889 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4890 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4891 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4892 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4893 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4894 ASSERT_EQ(-20, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X));
4895 ASSERT_EQ(10, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
4896
4897 // Enable Pointer Capture.
4898 mFakePolicy->setPointerCapture(true);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004899 configureDevice(InputReaderConfiguration::Change::POINTER_CAPTURE);
Prabir Pradhan208360b2022-06-24 18:37:04 +00004900 NotifyPointerCaptureChangedArgs captureArgs;
4901 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
4902 ASSERT_TRUE(captureArgs.request.enable);
4903
4904 // Move and verify rotation is not applied.
4905 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4906 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4907 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4908 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4909 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4910 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4911 ASSERT_EQ(10, args.pointerCoords[0].getX());
4912 ASSERT_EQ(20, args.pointerCoords[0].getY());
4913}
4914
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004915TEST_F(CursorInputMapperTest, ConfigureDisplayId_NoAssociatedViewport) {
Arpit Singhe036ad72023-04-27 12:48:15 +00004916 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004917
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004918 // Set up the default display.
Michael Wrighta9cf4192022-12-01 23:46:39 +00004919 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004920
4921 // Set up the secondary display as the display on which the pointer should be shown.
4922 // The InputDevice is not associated with any display.
4923 prepareSecondaryDisplay();
4924 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004925 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Garfield Tan888a6a42020-01-09 11:39:16 -08004926
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004927 mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004928 mFakePointerController->setPosition(100, 200);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004929
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004930 // Ensure input events are generated for the secondary display.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004931 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4932 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4933 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004934 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan739dca42022-09-09 20:12:01 +00004935 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4936 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(SECONDARY_DISPLAY_ID),
4937 WithCoords(110.0f, 220.0f))));
Harry Cuttsce86cc32022-12-14 20:36:33 +00004938 ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(110.0f, 220.0f));
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004939}
4940
4941TEST_F(CursorInputMapperTest, ConfigureDisplayId_WithAssociatedViewport) {
Arpit Singhe036ad72023-04-27 12:48:15 +00004942 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004943
4944 // Set up the default display.
Michael Wrighta9cf4192022-12-01 23:46:39 +00004945 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004946
4947 // Set up the secondary display as the display on which the pointer should be shown,
4948 // and associate the InputDevice with the secondary display.
4949 prepareSecondaryDisplay();
4950 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
4951 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, SECONDARY_DISPLAY_UNIQUE_ID);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004952 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004953
4954 mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
4955 mFakePointerController->setPosition(100, 200);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004956
4957 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4958 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4959 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4960 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan739dca42022-09-09 20:12:01 +00004961 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4962 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(SECONDARY_DISPLAY_ID),
4963 WithCoords(110.0f, 220.0f))));
Harry Cuttsce86cc32022-12-14 20:36:33 +00004964 ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(110.0f, 220.0f));
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004965}
4966
4967TEST_F(CursorInputMapperTest, ConfigureDisplayId_IgnoresEventsForMismatchedPointerDisplay) {
Arpit Singhe036ad72023-04-27 12:48:15 +00004968 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004969
4970 // Set up the default display as the display on which the pointer should be shown.
Michael Wrighta9cf4192022-12-01 23:46:39 +00004971 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004972 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
4973
4974 // Associate the InputDevice with the secondary display.
4975 prepareSecondaryDisplay();
4976 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, SECONDARY_DISPLAY_UNIQUE_ID);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004977 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004978
4979 // The mapper should not generate any events because it is associated with a display that is
4980 // different from the pointer display.
4981 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4982 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4983 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4984 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004985}
4986
Byoungho Jungda10dd32023-10-06 17:03:45 +09004987// --- CursorInputMapperTestWithChoreographer ---
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00004988
Prabir Pradhancc7268a2023-11-16 18:54:13 +00004989// TODO(b/311416205): De-duplicate the test cases after the refactoring is complete and the flagging
4990// logic can be removed.
Byoungho Jungda10dd32023-10-06 17:03:45 +09004991class CursorInputMapperTestWithChoreographer : public CursorInputMapperTestBase {
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00004992protected:
4993 void SetUp() override {
Byoungho Jungda10dd32023-10-06 17:03:45 +09004994 input_flags::enable_pointer_choreographer(true);
4995 CursorInputMapperTestBase::SetUp();
4996 }
4997};
4998
Prabir Pradhan19767602023-11-03 16:53:31 +00004999TEST_F(CursorInputMapperTestWithChoreographer, PopulateDeviceInfoReturnsRangeFromPolicy) {
Byoungho Jungda10dd32023-10-06 17:03:45 +09005000 addConfigurationProperty("cursor.mode", "pointer");
5001 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
5002
5003 InputDeviceInfo info;
5004 mapper.populateDeviceInfo(info);
5005
5006 // Initially there may not be a valid motion range.
5007 ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE));
5008 ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE));
5009 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_PRESSURE,
5010 AINPUT_SOURCE_MOUSE, 0.0f, 1.0f, 0.0f, 0.0f));
5011
5012 // When the viewport and the default pointer display ID is set, then there should be a valid
5013 // motion range.
5014 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
5015 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
5016 /*isActive=*/true, "local:0", NO_PORT, ViewportType::INTERNAL);
5017 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
5018
5019 InputDeviceInfo info2;
5020 mapper.populateDeviceInfo(info2);
5021
5022 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2, AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE, 0,
5023 DISPLAY_WIDTH - 1, 0.0f, 0.0f));
5024 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2, AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE, 0,
5025 DISPLAY_HEIGHT - 1, 0.0f, 0.0f));
5026 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2, AINPUT_MOTION_RANGE_PRESSURE,
5027 AINPUT_SOURCE_MOUSE, 0.0f, 1.0f, 0.0f, 0.0f));
5028}
5029
Prabir Pradhan19767602023-11-03 16:53:31 +00005030TEST_F(CursorInputMapperTestWithChoreographer, ProcessShouldHandleAllButtonsWithZeroCoords) {
Byoungho Jungda10dd32023-10-06 17:03:45 +09005031 addConfigurationProperty("cursor.mode", "pointer");
5032 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
5033
5034 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
5035 prepareDisplay(ui::ROTATION_0);
5036
5037 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
5038 mFakePointerController->setPosition(100, 200);
5039
5040 NotifyMotionArgs motionArgs;
5041 NotifyKeyArgs keyArgs;
5042
5043 // press BTN_LEFT, release BTN_LEFT
5044 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_LEFT, 1);
5045 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5046 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5047 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5048 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
5049 ASSERT_NO_FATAL_FAILURE(
5050 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 1.0f));
5051
5052 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5053 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5054 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
5055 ASSERT_NO_FATAL_FAILURE(
5056 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 1.0f));
5057
5058 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_LEFT, 0);
5059 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5060 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5061 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
5062 ASSERT_EQ(0, motionArgs.buttonState);
5063 ASSERT_NO_FATAL_FAILURE(
5064 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5065
5066 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5067 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5068 ASSERT_EQ(0, motionArgs.buttonState);
5069 ASSERT_NO_FATAL_FAILURE(
5070 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5071
5072 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5073 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
5074 ASSERT_EQ(0, motionArgs.buttonState);
5075 ASSERT_NO_FATAL_FAILURE(
5076 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5077
5078 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
5079 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_RIGHT, 1);
5080 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 1);
5081 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5082 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5083 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5084 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
5085 motionArgs.buttonState);
5086 ASSERT_NO_FATAL_FAILURE(
5087 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 1.0f));
5088
5089 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5090 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5091 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
5092 ASSERT_NO_FATAL_FAILURE(
5093 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 1.0f));
5094
5095 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5096 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5097 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
5098 motionArgs.buttonState);
5099 ASSERT_NO_FATAL_FAILURE(
5100 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 1.0f));
5101
5102 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_RIGHT, 0);
5103 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5104 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5105 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
5106 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
5107 ASSERT_NO_FATAL_FAILURE(
5108 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 1.0f));
5109
5110 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5111 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5112 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
5113 ASSERT_NO_FATAL_FAILURE(
5114 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 1.0f));
5115
5116 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
5117 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5118 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5119 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
5120 ASSERT_EQ(0, motionArgs.buttonState);
5121 ASSERT_NO_FATAL_FAILURE(
5122 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5123 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
5124 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5125
5126 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5127 ASSERT_EQ(0, motionArgs.buttonState);
5128 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5129 ASSERT_NO_FATAL_FAILURE(
5130 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5131
5132 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5133 ASSERT_EQ(0, motionArgs.buttonState);
5134 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
5135 ASSERT_NO_FATAL_FAILURE(
5136 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5137
5138 // press BTN_BACK, release BTN_BACK
5139 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_BACK, 1);
5140 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5141 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5142 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5143 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
5144
5145 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5146 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
5147 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
5148 ASSERT_NO_FATAL_FAILURE(
5149 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5150
5151 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5152 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5153 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
5154 ASSERT_NO_FATAL_FAILURE(
5155 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5156
5157 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_BACK, 0);
5158 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5159 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5160 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
5161 ASSERT_EQ(0, motionArgs.buttonState);
5162 ASSERT_NO_FATAL_FAILURE(
5163 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5164
5165 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5166 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
5167 ASSERT_EQ(0, motionArgs.buttonState);
5168
5169 ASSERT_NO_FATAL_FAILURE(
5170 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5171 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5172 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5173 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
5174
5175 // press BTN_SIDE, release BTN_SIDE
5176 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_SIDE, 1);
5177 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5178 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5179 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5180 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
5181
5182 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5183 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
5184 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
5185 ASSERT_NO_FATAL_FAILURE(
5186 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5187
5188 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5189 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5190 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
5191 ASSERT_NO_FATAL_FAILURE(
5192 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5193
5194 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_SIDE, 0);
5195 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5196 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5197 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
5198 ASSERT_EQ(0, motionArgs.buttonState);
5199 ASSERT_NO_FATAL_FAILURE(
5200 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5201
5202 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5203 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
5204 ASSERT_EQ(0, motionArgs.buttonState);
5205 ASSERT_NO_FATAL_FAILURE(
5206 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5207
5208 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5209 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5210 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
5211
5212 // press BTN_FORWARD, release BTN_FORWARD
5213 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_FORWARD, 1);
5214 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5215 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5216 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5217 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
5218
5219 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5220 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
5221 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
5222 ASSERT_NO_FATAL_FAILURE(
5223 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5224
5225 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5226 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5227 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
5228 ASSERT_NO_FATAL_FAILURE(
5229 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5230
5231 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_FORWARD, 0);
5232 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5233 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5234 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
5235 ASSERT_EQ(0, motionArgs.buttonState);
5236 ASSERT_NO_FATAL_FAILURE(
5237 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5238
5239 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5240 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
5241 ASSERT_EQ(0, motionArgs.buttonState);
5242 ASSERT_NO_FATAL_FAILURE(
5243 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5244
5245 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5246 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5247 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
5248
5249 // press BTN_EXTRA, release BTN_EXTRA
5250 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_EXTRA, 1);
5251 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5252 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5253 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5254 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
5255
5256 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5257 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
5258 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
5259 ASSERT_NO_FATAL_FAILURE(
5260 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5261
5262 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5263 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
5264 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
5265 ASSERT_NO_FATAL_FAILURE(
5266 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5267
5268 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_EXTRA, 0);
5269 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5270 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5271 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
5272 ASSERT_EQ(0, motionArgs.buttonState);
5273 ASSERT_NO_FATAL_FAILURE(
5274 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5275
5276 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5277 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
5278 ASSERT_EQ(0, motionArgs.buttonState);
5279 ASSERT_NO_FATAL_FAILURE(
5280 assertCursorPointerCoords(motionArgs.pointerCoords[0], 0.0f, 0.0f, 0.0f));
5281
5282 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5283 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5284 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
5285}
5286
Prabir Pradhan19767602023-11-03 16:53:31 +00005287TEST_F(CursorInputMapperTestWithChoreographer, ProcessWhenModeIsPointerShouldKeepZeroCoords) {
Byoungho Jungda10dd32023-10-06 17:03:45 +09005288 addConfigurationProperty("cursor.mode", "pointer");
5289 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
5290
5291 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
5292 prepareDisplay(ui::ROTATION_0);
5293
5294 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
5295 mFakePointerController->setPosition(100, 200);
5296
5297 NotifyMotionArgs args;
5298
5299 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5300 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5301 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5302 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5303 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
5304 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
5305 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
5306 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
5307}
5308
5309TEST_F(CursorInputMapperTestWithChoreographer, PointerCaptureDisablesVelocityProcessing) {
5310 addConfigurationProperty("cursor.mode", "pointer");
Prabir Pradhan19767602023-11-03 16:53:31 +00005311 const VelocityControlParameters testParams(/*scale=*/5.f, /*lowThreshold=*/0.f,
5312 /*highThreshold=*/100.f, /*acceleration=*/10.f);
Byoungho Jungda10dd32023-10-06 17:03:45 +09005313 mFakePolicy->setVelocityControlParams(testParams);
5314 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
5315
5316 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
5317 prepareDisplay(ui::ROTATION_0);
5318
5319 NotifyDeviceResetArgs resetArgs;
5320 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
5321 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
5322 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
5323
5324 NotifyMotionArgs args;
5325
5326 // Move and verify scale is applied.
5327 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5328 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5329 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5330 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5331 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
5332 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
5333 const float relX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
5334 const float relY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
5335 ASSERT_GT(relX, 10);
5336 ASSERT_GT(relY, 20);
5337
5338 // Enable Pointer Capture
5339 mFakePolicy->setPointerCapture(true);
5340 configureDevice(InputReaderConfiguration::Change::POINTER_CAPTURE);
5341 NotifyPointerCaptureChangedArgs captureArgs;
5342 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
5343 ASSERT_TRUE(captureArgs.request.enable);
5344
5345 // Move and verify scale is not applied.
5346 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5347 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5348 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5349 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5350 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
5351 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
5352 const float relX2 = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
5353 const float relY2 = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
5354 ASSERT_EQ(10, relX2);
5355 ASSERT_EQ(20, relY2);
5356}
5357
Prabir Pradhan19767602023-11-03 16:53:31 +00005358TEST_F(CursorInputMapperTestWithChoreographer, ConfigureDisplayIdNoAssociatedViewport) {
Byoungho Jungda10dd32023-10-06 17:03:45 +09005359 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
5360
5361 // Set up the default display.
5362 prepareDisplay(ui::ROTATION_90);
5363
5364 // Set up the secondary display as the display on which the pointer should be shown.
5365 // The InputDevice is not associated with any display.
5366 prepareSecondaryDisplay();
5367 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
5368 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
5369
5370 mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
5371 mFakePointerController->setPosition(100, 200);
5372
5373 // Ensure input events are generated without display ID and coords,
5374 // because they will be decided later by PointerChoreographer.
5375 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5376 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5377 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5378 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5379 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5380 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(ADISPLAY_ID_NONE),
5381 WithCoords(0.0f, 0.0f))));
5382}
5383
Prabir Pradhan19767602023-11-03 16:53:31 +00005384TEST_F(CursorInputMapperTestWithChoreographer, ConfigureDisplayIdWithAssociatedViewport) {
Byoungho Jungda10dd32023-10-06 17:03:45 +09005385 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
5386
5387 // Set up the default display.
5388 prepareDisplay(ui::ROTATION_90);
5389
5390 // Set up the secondary display as the display on which the pointer should be shown,
5391 // and associate the InputDevice with the secondary display.
5392 prepareSecondaryDisplay();
5393 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
5394 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, SECONDARY_DISPLAY_UNIQUE_ID);
5395 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
5396
5397 mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
5398 mFakePointerController->setPosition(100, 200);
5399
5400 // Ensure input events are generated with associated display ID but not with coords,
5401 // because the coords will be decided later by PointerChoreographer.
5402 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5403 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5404 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5405 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5406 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5407 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(SECONDARY_DISPLAY_ID),
5408 WithCoords(0.0f, 0.0f))));
5409}
5410
5411TEST_F(CursorInputMapperTestWithChoreographer,
Prabir Pradhan19767602023-11-03 16:53:31 +00005412 ConfigureDisplayIdShouldGenerateEventWithMismatchedPointerDisplay) {
Byoungho Jungda10dd32023-10-06 17:03:45 +09005413 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
5414
5415 // Set up the default display as the display on which the pointer should be shown.
5416 prepareDisplay(ui::ROTATION_90);
5417 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
5418
5419 // Associate the InputDevice with the secondary display.
5420 prepareSecondaryDisplay();
5421 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, SECONDARY_DISPLAY_UNIQUE_ID);
5422 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
5423
5424 // With PointerChoreographer enabled, there could be a PointerController for the associated
5425 // display even if it is different from the pointer display. So the mapper should generate an
5426 // event.
5427 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
5428 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
5429 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5430 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5431 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5432 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(SECONDARY_DISPLAY_ID),
5433 WithCoords(0.0f, 0.0f))));
5434}
5435
5436// --- BluetoothCursorInputMapperTest ---
5437
5438class BluetoothCursorInputMapperTest : public CursorInputMapperTestBase {
5439protected:
5440 void SetUp() override {
5441 input_flags::enable_pointer_choreographer(false);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00005442 InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL, BUS_BLUETOOTH);
5443
5444 mFakePointerController = std::make_shared<FakePointerController>();
5445 mFakePolicy->setPointerController(mFakePointerController);
5446 }
5447};
5448
5449TEST_F(BluetoothCursorInputMapperTest, TimestampSmoothening) {
5450 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00005451 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00005452
5453 nsecs_t kernelEventTime = ARBITRARY_TIME;
5454 nsecs_t expectedEventTime = ARBITRARY_TIME;
5455 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
5456 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
5457 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5458 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5459 WithEventTime(expectedEventTime))));
5460
5461 // Process several events that come in quick succession, according to their timestamps.
5462 for (int i = 0; i < 3; i++) {
5463 constexpr static nsecs_t delta = ms2ns(1);
5464 static_assert(delta < MIN_BLUETOOTH_TIMESTAMP_DELTA);
5465 kernelEventTime += delta;
5466 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
5467
5468 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
5469 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
5470 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5471 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5472 WithEventTime(expectedEventTime))));
5473 }
5474}
5475
5476TEST_F(BluetoothCursorInputMapperTest, TimestampSmootheningIsCapped) {
5477 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00005478 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00005479
5480 nsecs_t expectedEventTime = ARBITRARY_TIME;
5481 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
5482 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5483 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5484 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5485 WithEventTime(expectedEventTime))));
5486
5487 // Process several events with the same timestamp from the kernel.
5488 // Ensure that we do not generate events too far into the future.
5489 constexpr static int32_t numEvents =
5490 MAX_BLUETOOTH_SMOOTHING_DELTA / MIN_BLUETOOTH_TIMESTAMP_DELTA;
5491 for (int i = 0; i < numEvents; i++) {
5492 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
5493
5494 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
5495 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5496 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5497 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5498 WithEventTime(expectedEventTime))));
5499 }
5500
5501 // By processing more events with the same timestamp, we should not generate events with a
5502 // timestamp that is more than the specified max time delta from the timestamp at its injection.
5503 const nsecs_t cappedEventTime = ARBITRARY_TIME + MAX_BLUETOOTH_SMOOTHING_DELTA;
5504 for (int i = 0; i < 3; i++) {
5505 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
5506 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5507 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5508 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5509 WithEventTime(cappedEventTime))));
5510 }
5511}
5512
5513TEST_F(BluetoothCursorInputMapperTest, TimestampSmootheningNotUsed) {
5514 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00005515 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00005516
5517 nsecs_t kernelEventTime = ARBITRARY_TIME;
5518 nsecs_t expectedEventTime = ARBITRARY_TIME;
5519 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
5520 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
5521 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5522 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5523 WithEventTime(expectedEventTime))));
5524
5525 // If the next event has a timestamp that is sufficiently spaced out so that Bluetooth timestamp
5526 // smoothening is not needed, its timestamp is not affected.
5527 kernelEventTime += MAX_BLUETOOTH_SMOOTHING_DELTA + ms2ns(1);
5528 expectedEventTime = kernelEventTime;
5529
5530 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
5531 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
5532 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5533 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5534 WithEventTime(expectedEventTime))));
5535}
5536
Byoungho Jungda10dd32023-10-06 17:03:45 +09005537// --- BluetoothCursorInputMapperTestWithChoreographer ---
5538
5539class BluetoothCursorInputMapperTestWithChoreographer : public CursorInputMapperTestBase {
5540protected:
5541 void SetUp() override {
5542 input_flags::enable_pointer_choreographer(true);
5543 InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL, BUS_BLUETOOTH);
5544
5545 mFakePointerController = std::make_shared<FakePointerController>();
5546 mFakePolicy->setPointerController(mFakePointerController);
5547 }
5548};
5549
5550TEST_F(BluetoothCursorInputMapperTestWithChoreographer, TimestampSmoothening) {
5551 addConfigurationProperty("cursor.mode", "pointer");
5552 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
5553
5554 // Set up the default display.
5555 prepareDisplay(ui::ROTATION_0);
5556 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
5557 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
5558
5559 nsecs_t kernelEventTime = ARBITRARY_TIME;
5560 nsecs_t expectedEventTime = ARBITRARY_TIME;
5561 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
5562 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
5563 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5564 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5565 WithEventTime(expectedEventTime))));
5566
5567 // Process several events that come in quick succession, according to their timestamps.
5568 for (int i = 0; i < 3; i++) {
5569 constexpr static nsecs_t delta = ms2ns(1);
5570 static_assert(delta < MIN_BLUETOOTH_TIMESTAMP_DELTA);
5571 kernelEventTime += delta;
5572 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
5573
5574 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
5575 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
5576 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5577 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5578 WithEventTime(expectedEventTime))));
5579 }
5580}
5581
5582TEST_F(BluetoothCursorInputMapperTestWithChoreographer, TimestampSmootheningIsCapped) {
5583 addConfigurationProperty("cursor.mode", "pointer");
5584 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
5585
5586 // Set up the default display.
5587 prepareDisplay(ui::ROTATION_0);
5588 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
5589 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
5590
5591 nsecs_t expectedEventTime = ARBITRARY_TIME;
5592 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
5593 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5594 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5595 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5596 WithEventTime(expectedEventTime))));
5597
5598 // Process several events with the same timestamp from the kernel.
5599 // Ensure that we do not generate events too far into the future.
5600 constexpr static int32_t numEvents =
5601 MAX_BLUETOOTH_SMOOTHING_DELTA / MIN_BLUETOOTH_TIMESTAMP_DELTA;
5602 for (int i = 0; i < numEvents; i++) {
5603 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
5604
5605 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
5606 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5607 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5608 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5609 WithEventTime(expectedEventTime))));
5610 }
5611
5612 // By processing more events with the same timestamp, we should not generate events with a
5613 // timestamp that is more than the specified max time delta from the timestamp at its injection.
5614 const nsecs_t cappedEventTime = ARBITRARY_TIME + MAX_BLUETOOTH_SMOOTHING_DELTA;
5615 for (int i = 0; i < 3; i++) {
5616 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
5617 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5618 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5619 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5620 WithEventTime(cappedEventTime))));
5621 }
5622}
5623
5624TEST_F(BluetoothCursorInputMapperTestWithChoreographer, TimestampSmootheningNotUsed) {
5625 addConfigurationProperty("cursor.mode", "pointer");
5626 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
5627
5628 // Set up the default display.
5629 prepareDisplay(ui::ROTATION_0);
5630 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
5631 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
5632
5633 nsecs_t kernelEventTime = ARBITRARY_TIME;
5634 nsecs_t expectedEventTime = ARBITRARY_TIME;
5635 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
5636 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
5637 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5638 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5639 WithEventTime(expectedEventTime))));
5640
5641 // If the next event has a timestamp that is sufficiently spaced out so that Bluetooth timestamp
5642 // smoothening is not needed, its timestamp is not affected.
5643 kernelEventTime += MAX_BLUETOOTH_SMOOTHING_DELTA + ms2ns(1);
5644 expectedEventTime = kernelEventTime;
5645
5646 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
5647 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
5648 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5649 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5650 WithEventTime(expectedEventTime))));
5651}
5652
Michael Wrightd02c5b62014-02-10 15:10:22 -08005653// --- TouchInputMapperTest ---
5654
5655class TouchInputMapperTest : public InputMapperTest {
5656protected:
5657 static const int32_t RAW_X_MIN;
5658 static const int32_t RAW_X_MAX;
5659 static const int32_t RAW_Y_MIN;
5660 static const int32_t RAW_Y_MAX;
5661 static const int32_t RAW_TOUCH_MIN;
5662 static const int32_t RAW_TOUCH_MAX;
5663 static const int32_t RAW_TOOL_MIN;
5664 static const int32_t RAW_TOOL_MAX;
5665 static const int32_t RAW_PRESSURE_MIN;
5666 static const int32_t RAW_PRESSURE_MAX;
5667 static const int32_t RAW_ORIENTATION_MIN;
5668 static const int32_t RAW_ORIENTATION_MAX;
5669 static const int32_t RAW_DISTANCE_MIN;
5670 static const int32_t RAW_DISTANCE_MAX;
5671 static const int32_t RAW_TILT_MIN;
5672 static const int32_t RAW_TILT_MAX;
5673 static const int32_t RAW_ID_MIN;
5674 static const int32_t RAW_ID_MAX;
5675 static const int32_t RAW_SLOT_MIN;
5676 static const int32_t RAW_SLOT_MAX;
5677 static const float X_PRECISION;
5678 static const float Y_PRECISION;
Santos Cordonfa5cf462017-04-05 10:37:00 -07005679 static const float X_PRECISION_VIRTUAL;
5680 static const float Y_PRECISION_VIRTUAL;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005681
5682 static const float GEOMETRIC_SCALE;
Jason Gerecke489fda82012-09-07 17:19:40 -07005683 static const TouchAffineTransformation AFFINE_TRANSFORM;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005684
5685 static const VirtualKeyDefinition VIRTUAL_KEYS[2];
5686
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005687 const std::string UNIQUE_ID = "local:0";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07005688 const std::string SECONDARY_UNIQUE_ID = "local:1";
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005689
Michael Wrightd02c5b62014-02-10 15:10:22 -08005690 enum Axes {
5691 POSITION = 1 << 0,
5692 TOUCH = 1 << 1,
5693 TOOL = 1 << 2,
5694 PRESSURE = 1 << 3,
5695 ORIENTATION = 1 << 4,
5696 MINOR = 1 << 5,
5697 ID = 1 << 6,
5698 DISTANCE = 1 << 7,
5699 TILT = 1 << 8,
5700 SLOT = 1 << 9,
5701 TOOL_TYPE = 1 << 10,
5702 };
5703
Michael Wrighta9cf4192022-12-01 23:46:39 +00005704 void prepareDisplay(ui::Rotation orientation, std::optional<uint8_t> port = NO_PORT);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07005705 void prepareSecondaryDisplay(ViewportType type, std::optional<uint8_t> port = NO_PORT);
Michael Wrighta9cf4192022-12-01 23:46:39 +00005706 void prepareVirtualDisplay(ui::Rotation orientation);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005707 void prepareVirtualKeys();
Jason Gerecke489fda82012-09-07 17:19:40 -07005708 void prepareLocationCalibration();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005709 int32_t toRawX(float displayX);
5710 int32_t toRawY(float displayY);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005711 int32_t toRotatedRawX(float displayX);
5712 int32_t toRotatedRawY(float displayY);
Jason Gerecke489fda82012-09-07 17:19:40 -07005713 float toCookedX(float rawX, float rawY);
5714 float toCookedY(float rawX, float rawY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005715 float toDisplayX(int32_t rawX);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005716 float toDisplayX(int32_t rawX, int32_t displayWidth);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005717 float toDisplayY(int32_t rawY);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005718 float toDisplayY(int32_t rawY, int32_t displayHeight);
5719
Michael Wrightd02c5b62014-02-10 15:10:22 -08005720};
5721
5722const int32_t TouchInputMapperTest::RAW_X_MIN = 25;
5723const int32_t TouchInputMapperTest::RAW_X_MAX = 1019;
5724const int32_t TouchInputMapperTest::RAW_Y_MIN = 30;
5725const int32_t TouchInputMapperTest::RAW_Y_MAX = 1009;
5726const int32_t TouchInputMapperTest::RAW_TOUCH_MIN = 0;
5727const int32_t TouchInputMapperTest::RAW_TOUCH_MAX = 31;
5728const int32_t TouchInputMapperTest::RAW_TOOL_MIN = 0;
5729const int32_t TouchInputMapperTest::RAW_TOOL_MAX = 15;
Michael Wrightaa449c92017-12-13 21:21:43 +00005730const int32_t TouchInputMapperTest::RAW_PRESSURE_MIN = 0;
5731const int32_t TouchInputMapperTest::RAW_PRESSURE_MAX = 255;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005732const int32_t TouchInputMapperTest::RAW_ORIENTATION_MIN = -7;
5733const int32_t TouchInputMapperTest::RAW_ORIENTATION_MAX = 7;
5734const int32_t TouchInputMapperTest::RAW_DISTANCE_MIN = 0;
5735const int32_t TouchInputMapperTest::RAW_DISTANCE_MAX = 7;
5736const int32_t TouchInputMapperTest::RAW_TILT_MIN = 0;
5737const int32_t TouchInputMapperTest::RAW_TILT_MAX = 150;
5738const int32_t TouchInputMapperTest::RAW_ID_MIN = 0;
5739const int32_t TouchInputMapperTest::RAW_ID_MAX = 9;
5740const int32_t TouchInputMapperTest::RAW_SLOT_MIN = 0;
5741const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9;
5742const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH;
5743const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT;
Santos Cordonfa5cf462017-04-05 10:37:00 -07005744const float TouchInputMapperTest::X_PRECISION_VIRTUAL =
5745 float(RAW_X_MAX - RAW_X_MIN + 1) / VIRTUAL_DISPLAY_WIDTH;
5746const float TouchInputMapperTest::Y_PRECISION_VIRTUAL =
5747 float(RAW_Y_MAX - RAW_Y_MIN + 1) / VIRTUAL_DISPLAY_HEIGHT;
Jason Gerecke489fda82012-09-07 17:19:40 -07005748const TouchAffineTransformation TouchInputMapperTest::AFFINE_TRANSFORM =
5749 TouchAffineTransformation(1, -2, 3, -4, 5, -6);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005750
5751const float TouchInputMapperTest::GEOMETRIC_SCALE =
5752 avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN + 1),
5753 float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN + 1));
5754
5755const VirtualKeyDefinition TouchInputMapperTest::VIRTUAL_KEYS[2] = {
5756 { KEY_HOME, 60, DISPLAY_HEIGHT + 15, 20, 20 },
5757 { KEY_MENU, DISPLAY_HEIGHT - 60, DISPLAY_WIDTH + 15, 20, 20 },
5758};
5759
Michael Wrighta9cf4192022-12-01 23:46:39 +00005760void TouchInputMapperTest::prepareDisplay(ui::Rotation orientation, std::optional<uint8_t> port) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01005761 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation, UNIQUE_ID,
5762 port, ViewportType::INTERNAL);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07005763}
5764
5765void TouchInputMapperTest::prepareSecondaryDisplay(ViewportType type, std::optional<uint8_t> port) {
5766 setDisplayInfoAndReconfigure(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +00005767 ui::ROTATION_0, SECONDARY_UNIQUE_ID, port, type);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005768}
5769
Michael Wrighta9cf4192022-12-01 23:46:39 +00005770void TouchInputMapperTest::prepareVirtualDisplay(ui::Rotation orientation) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01005771 setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH, VIRTUAL_DISPLAY_HEIGHT,
5772 orientation, VIRTUAL_DISPLAY_UNIQUE_ID, NO_PORT,
5773 ViewportType::VIRTUAL);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005774}
5775
Michael Wrightd02c5b62014-02-10 15:10:22 -08005776void TouchInputMapperTest::prepareVirtualKeys() {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005777 mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[0]);
5778 mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[1]);
5779 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
5780 mFakeEventHub->addKey(EVENTHUB_ID, KEY_MENU, 0, AKEYCODE_MENU, POLICY_FLAG_WAKE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005781}
5782
Jason Gerecke489fda82012-09-07 17:19:40 -07005783void TouchInputMapperTest::prepareLocationCalibration() {
5784 mFakePolicy->setTouchAffineTransformation(AFFINE_TRANSFORM);
5785}
5786
Michael Wrightd02c5b62014-02-10 15:10:22 -08005787int32_t TouchInputMapperTest::toRawX(float displayX) {
5788 return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH + RAW_X_MIN);
5789}
5790
5791int32_t TouchInputMapperTest::toRawY(float displayY) {
5792 return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT + RAW_Y_MIN);
5793}
5794
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005795int32_t TouchInputMapperTest::toRotatedRawX(float displayX) {
5796 return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_HEIGHT + RAW_X_MIN);
5797}
5798
5799int32_t TouchInputMapperTest::toRotatedRawY(float displayY) {
5800 return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_WIDTH + RAW_Y_MIN);
5801}
5802
Jason Gerecke489fda82012-09-07 17:19:40 -07005803float TouchInputMapperTest::toCookedX(float rawX, float rawY) {
5804 AFFINE_TRANSFORM.applyTo(rawX, rawY);
5805 return rawX;
5806}
5807
5808float TouchInputMapperTest::toCookedY(float rawX, float rawY) {
5809 AFFINE_TRANSFORM.applyTo(rawX, rawY);
5810 return rawY;
5811}
5812
Michael Wrightd02c5b62014-02-10 15:10:22 -08005813float TouchInputMapperTest::toDisplayX(int32_t rawX) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005814 return toDisplayX(rawX, DISPLAY_WIDTH);
5815}
5816
5817float TouchInputMapperTest::toDisplayX(int32_t rawX, int32_t displayWidth) {
5818 return float(rawX - RAW_X_MIN) * displayWidth / (RAW_X_MAX - RAW_X_MIN + 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005819}
5820
5821float TouchInputMapperTest::toDisplayY(int32_t rawY) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005822 return toDisplayY(rawY, DISPLAY_HEIGHT);
5823}
5824
5825float TouchInputMapperTest::toDisplayY(int32_t rawY, int32_t displayHeight) {
5826 return float(rawY - RAW_Y_MIN) * displayHeight / (RAW_Y_MAX - RAW_Y_MIN + 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005827}
5828
5829
5830// --- SingleTouchInputMapperTest ---
5831
5832class SingleTouchInputMapperTest : public TouchInputMapperTest {
5833protected:
5834 void prepareButtons();
5835 void prepareAxes(int axes);
5836
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005837 void processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
5838 void processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
5839 void processUp(SingleTouchInputMapper& mappery);
5840 void processPressure(SingleTouchInputMapper& mapper, int32_t pressure);
5841 void processToolMajor(SingleTouchInputMapper& mapper, int32_t toolMajor);
5842 void processDistance(SingleTouchInputMapper& mapper, int32_t distance);
5843 void processTilt(SingleTouchInputMapper& mapper, int32_t tiltX, int32_t tiltY);
5844 void processKey(SingleTouchInputMapper& mapper, int32_t code, int32_t value);
5845 void processSync(SingleTouchInputMapper& mapper);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005846};
5847
5848void SingleTouchInputMapperTest::prepareButtons() {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005849 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005850}
5851
5852void SingleTouchInputMapperTest::prepareAxes(int axes) {
5853 if (axes & POSITION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005854 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
5855 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005856 }
5857 if (axes & PRESSURE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005858 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MIN,
5859 RAW_PRESSURE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005860 }
5861 if (axes & TOOL) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005862 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TOOL_WIDTH, RAW_TOOL_MIN, RAW_TOOL_MAX, 0,
5863 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005864 }
5865 if (axes & DISTANCE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005866 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_DISTANCE, RAW_DISTANCE_MIN,
5867 RAW_DISTANCE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005868 }
5869 if (axes & TILT) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005870 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_X, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
5871 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_Y, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005872 }
5873}
5874
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005875void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005876 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
5877 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
5878 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005879}
5880
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005881void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005882 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
5883 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005884}
5885
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005886void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005887 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005888}
5889
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005890void SingleTouchInputMapperTest::processPressure(SingleTouchInputMapper& mapper, int32_t pressure) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005891 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_PRESSURE, pressure);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005892}
5893
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005894void SingleTouchInputMapperTest::processToolMajor(SingleTouchInputMapper& mapper,
5895 int32_t toolMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005896 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TOOL_WIDTH, toolMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005897}
5898
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005899void SingleTouchInputMapperTest::processDistance(SingleTouchInputMapper& mapper, int32_t distance) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005900 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_DISTANCE, distance);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005901}
5902
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005903void SingleTouchInputMapperTest::processTilt(SingleTouchInputMapper& mapper, int32_t tiltX,
5904 int32_t tiltY) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005905 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_X, tiltX);
5906 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_Y, tiltY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005907}
5908
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005909void SingleTouchInputMapperTest::processKey(SingleTouchInputMapper& mapper, int32_t code,
5910 int32_t value) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005911 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005912}
5913
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005914void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005915 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005916}
5917
Michael Wrightd02c5b62014-02-10 15:10:22 -08005918TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndNotACursor_ReturnsPointer) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005919 prepareButtons();
5920 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00005921 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005922
Josep del Río2d8c79a2023-01-23 19:33:50 +00005923 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005924}
5925
Michael Wrightd02c5b62014-02-10 15:10:22 -08005926TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005927 prepareButtons();
5928 prepareAxes(POSITION);
5929 addConfigurationProperty("touch.deviceType", "touchScreen");
Arpit Singha8c236b2023-04-25 13:56:05 +00005930 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005931
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005932 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005933}
5934
5935TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005936 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005937 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005938 prepareButtons();
5939 prepareAxes(POSITION);
5940 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00005941 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005942
5943 // Unknown key.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005944 ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005945
5946 // Virtual key is down.
5947 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5948 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5949 processDown(mapper, x, y);
5950 processSync(mapper);
5951 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5952
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005953 ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005954
5955 // Virtual key is up.
5956 processUp(mapper);
5957 processSync(mapper);
5958 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5959
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005960 ASSERT_EQ(AKEY_STATE_UP, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005961}
5962
5963TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005964 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005965 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005966 prepareButtons();
5967 prepareAxes(POSITION);
5968 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00005969 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005970
5971 // Unknown key.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005972 ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005973
5974 // Virtual key is down.
5975 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5976 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5977 processDown(mapper, x, y);
5978 processSync(mapper);
5979 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5980
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005981 ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005982
5983 // Virtual key is up.
5984 processUp(mapper);
5985 processSync(mapper);
5986 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5987
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005988 ASSERT_EQ(AKEY_STATE_UP, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005989}
5990
5991TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005992 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005993 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005994 prepareButtons();
5995 prepareAxes(POSITION);
5996 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00005997 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005998
Michael Wrightd02c5b62014-02-10 15:10:22 -08005999 uint8_t flags[2] = { 0, 0 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07006000 ASSERT_TRUE(
6001 mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, {AKEYCODE_HOME, AKEYCODE_A}, flags));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006002 ASSERT_TRUE(flags[0]);
6003 ASSERT_FALSE(flags[1]);
6004}
6005
6006TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006007 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006008 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006009 prepareButtons();
6010 prepareAxes(POSITION);
6011 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00006012 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006013
arthurhungdcef2dc2020-08-11 14:47:50 +08006014 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006015
6016 NotifyKeyArgs args;
6017
6018 // Press virtual key.
6019 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
6020 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
6021 processDown(mapper, x, y);
6022 processSync(mapper);
6023
6024 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
6025 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
6026 ASSERT_EQ(DEVICE_ID, args.deviceId);
6027 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
6028 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
6029 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
6030 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
6031 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
6032 ASSERT_EQ(KEY_HOME, args.scanCode);
6033 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
6034 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
6035
6036 // Release virtual key.
6037 processUp(mapper);
6038 processSync(mapper);
6039
6040 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
6041 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
6042 ASSERT_EQ(DEVICE_ID, args.deviceId);
6043 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
6044 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
6045 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
6046 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
6047 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
6048 ASSERT_EQ(KEY_HOME, args.scanCode);
6049 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
6050 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
6051
6052 // Should not have sent any motions.
6053 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6054}
6055
6056TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006057 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006058 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006059 prepareButtons();
6060 prepareAxes(POSITION);
6061 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00006062 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006063
arthurhungdcef2dc2020-08-11 14:47:50 +08006064 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006065
6066 NotifyKeyArgs keyArgs;
6067
6068 // Press virtual key.
6069 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
6070 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
6071 processDown(mapper, x, y);
6072 processSync(mapper);
6073
6074 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6075 ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
6076 ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
6077 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
6078 ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
6079 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6080 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, keyArgs.flags);
6081 ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
6082 ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
6083 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
6084 ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
6085
6086 // Move out of bounds. This should generate a cancel and a pointer down since we moved
6087 // into the display area.
6088 y -= 100;
6089 processMove(mapper, x, y);
6090 processSync(mapper);
6091
6092 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6093 ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
6094 ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
6095 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
6096 ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
6097 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6098 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
6099 | AKEY_EVENT_FLAG_CANCELED, keyArgs.flags);
6100 ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
6101 ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
6102 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
6103 ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
6104
6105 NotifyMotionArgs motionArgs;
6106 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6107 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6108 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6109 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6110 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6111 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6112 ASSERT_EQ(0, motionArgs.flags);
6113 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6114 ASSERT_EQ(0, motionArgs.buttonState);
6115 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07006116 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006117 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006118 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006119 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6120 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
6121 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6122 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6123 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6124
6125 // Keep moving out of bounds. Should generate a pointer move.
6126 y -= 50;
6127 processMove(mapper, x, y);
6128 processSync(mapper);
6129
6130 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6131 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6132 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6133 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6134 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6135 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6136 ASSERT_EQ(0, motionArgs.flags);
6137 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6138 ASSERT_EQ(0, motionArgs.buttonState);
6139 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07006140 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006141 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006142 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006143 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6144 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
6145 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6146 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6147 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6148
6149 // Release out of bounds. Should generate a pointer up.
6150 processUp(mapper);
6151 processSync(mapper);
6152
6153 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6154 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6155 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6156 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6157 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6158 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6159 ASSERT_EQ(0, motionArgs.flags);
6160 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6161 ASSERT_EQ(0, motionArgs.buttonState);
6162 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07006163 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006164 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006165 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006166 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6167 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
6168 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6169 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6170 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6171
6172 // Should not have sent any more keys or motions.
6173 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6174 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6175}
6176
6177TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006178 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006179 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006180 prepareButtons();
6181 prepareAxes(POSITION);
6182 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00006183 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006184
arthurhungdcef2dc2020-08-11 14:47:50 +08006185 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006186
6187 NotifyMotionArgs motionArgs;
6188
6189 // Initially go down out of bounds.
6190 int32_t x = -10;
6191 int32_t y = -10;
6192 processDown(mapper, x, y);
6193 processSync(mapper);
6194
6195 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6196
6197 // Move into the display area. Should generate a pointer down.
6198 x = 50;
6199 y = 75;
6200 processMove(mapper, x, y);
6201 processSync(mapper);
6202
6203 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6204 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6205 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6206 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6207 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6208 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6209 ASSERT_EQ(0, motionArgs.flags);
6210 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6211 ASSERT_EQ(0, motionArgs.buttonState);
6212 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07006213 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006214 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006215 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006216 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6217 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
6218 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6219 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6220 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6221
6222 // Release. Should generate a pointer up.
6223 processUp(mapper);
6224 processSync(mapper);
6225
6226 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6227 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6228 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6229 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6230 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6231 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6232 ASSERT_EQ(0, motionArgs.flags);
6233 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6234 ASSERT_EQ(0, motionArgs.buttonState);
6235 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07006236 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006237 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006238 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006239 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6240 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
6241 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6242 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6243 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6244
6245 // Should not have sent any more keys or motions.
6246 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6247 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6248}
6249
Santos Cordonfa5cf462017-04-05 10:37:00 -07006250TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture_VirtualDisplay) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07006251 addConfigurationProperty("touch.deviceType", "touchScreen");
6252 addConfigurationProperty("touch.displayId", VIRTUAL_DISPLAY_UNIQUE_ID);
6253
Michael Wrighta9cf4192022-12-01 23:46:39 +00006254 prepareVirtualDisplay(ui::ROTATION_0);
Santos Cordonfa5cf462017-04-05 10:37:00 -07006255 prepareButtons();
6256 prepareAxes(POSITION);
6257 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00006258 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Santos Cordonfa5cf462017-04-05 10:37:00 -07006259
arthurhungdcef2dc2020-08-11 14:47:50 +08006260 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Santos Cordonfa5cf462017-04-05 10:37:00 -07006261
6262 NotifyMotionArgs motionArgs;
6263
6264 // Down.
6265 int32_t x = 100;
6266 int32_t y = 125;
6267 processDown(mapper, x, y);
6268 processSync(mapper);
6269
6270 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6271 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6272 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6273 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
6274 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6275 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6276 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6277 ASSERT_EQ(0, motionArgs.flags);
6278 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6279 ASSERT_EQ(0, motionArgs.buttonState);
6280 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07006281 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Santos Cordonfa5cf462017-04-05 10:37:00 -07006282 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006283 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Santos Cordonfa5cf462017-04-05 10:37:00 -07006284 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6285 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
6286 1, 0, 0, 0, 0, 0, 0, 0));
6287 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
6288 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
6289 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6290
6291 // Move.
6292 x += 50;
6293 y += 75;
6294 processMove(mapper, x, y);
6295 processSync(mapper);
6296
6297 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6298 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6299 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6300 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
6301 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6302 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6303 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6304 ASSERT_EQ(0, motionArgs.flags);
6305 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6306 ASSERT_EQ(0, motionArgs.buttonState);
6307 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07006308 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Santos Cordonfa5cf462017-04-05 10:37:00 -07006309 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006310 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Santos Cordonfa5cf462017-04-05 10:37:00 -07006311 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6312 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
6313 1, 0, 0, 0, 0, 0, 0, 0));
6314 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
6315 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
6316 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6317
6318 // Up.
6319 processUp(mapper);
6320 processSync(mapper);
6321
6322 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6323 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6324 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6325 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
6326 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6327 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6328 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6329 ASSERT_EQ(0, motionArgs.flags);
6330 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6331 ASSERT_EQ(0, motionArgs.buttonState);
6332 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07006333 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Santos Cordonfa5cf462017-04-05 10:37:00 -07006334 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006335 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Santos Cordonfa5cf462017-04-05 10:37:00 -07006336 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6337 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
6338 1, 0, 0, 0, 0, 0, 0, 0));
6339 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
6340 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
6341 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6342
6343 // Should not have sent any more keys or motions.
6344 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6345 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6346}
6347
Michael Wrightd02c5b62014-02-10 15:10:22 -08006348TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006349 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006350 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006351 prepareButtons();
6352 prepareAxes(POSITION);
6353 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00006354 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006355
arthurhungdcef2dc2020-08-11 14:47:50 +08006356 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006357
6358 NotifyMotionArgs motionArgs;
6359
6360 // Down.
6361 int32_t x = 100;
6362 int32_t y = 125;
6363 processDown(mapper, x, y);
6364 processSync(mapper);
6365
6366 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6367 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6368 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6369 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6370 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6371 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6372 ASSERT_EQ(0, motionArgs.flags);
6373 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6374 ASSERT_EQ(0, motionArgs.buttonState);
6375 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07006376 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006377 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006378 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006379 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6380 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
6381 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6382 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6383 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6384
6385 // Move.
6386 x += 50;
6387 y += 75;
6388 processMove(mapper, x, y);
6389 processSync(mapper);
6390
6391 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6392 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6393 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6394 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6395 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6396 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6397 ASSERT_EQ(0, motionArgs.flags);
6398 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6399 ASSERT_EQ(0, motionArgs.buttonState);
6400 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07006401 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006402 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006403 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006404 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6405 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
6406 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6407 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6408 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6409
6410 // Up.
6411 processUp(mapper);
6412 processSync(mapper);
6413
6414 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6415 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6416 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6417 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6418 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6419 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6420 ASSERT_EQ(0, motionArgs.flags);
6421 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6422 ASSERT_EQ(0, motionArgs.buttonState);
6423 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07006424 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006425 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006426 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006427 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6428 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
6429 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6430 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6431 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6432
6433 // Should not have sent any more keys or motions.
6434 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6435 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6436}
6437
Prabir Pradhanc14266f2021-05-12 15:56:24 -07006438TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_DoesNotRotateMotions) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006439 addConfigurationProperty("touch.deviceType", "touchScreen");
6440 prepareButtons();
6441 prepareAxes(POSITION);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07006442 // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
6443 // need to be rotated. Touchscreens are orientation-aware by default.
Arpit Singha8c236b2023-04-25 13:56:05 +00006444 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006445
6446 NotifyMotionArgs args;
6447
6448 // Rotation 90.
Michael Wrighta9cf4192022-12-01 23:46:39 +00006449 prepareDisplay(ui::ROTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006450 processDown(mapper, toRawX(50), toRawY(75));
6451 processSync(mapper);
6452
6453 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6454 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6455 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6456
6457 processUp(mapper);
6458 processSync(mapper);
6459 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6460}
6461
Prabir Pradhanc14266f2021-05-12 15:56:24 -07006462TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_RotatesMotions) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006463 addConfigurationProperty("touch.deviceType", "touchScreen");
6464 prepareButtons();
6465 prepareAxes(POSITION);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07006466 // Since InputReader works in the un-rotated coordinate space, only devices that are not
6467 // orientation-aware are affected by display rotation.
6468 addConfigurationProperty("touch.orientationAware", "0");
Arpit Singha8c236b2023-04-25 13:56:05 +00006469 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006470
6471 NotifyMotionArgs args;
6472
6473 // Rotation 0.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07006474 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006475 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006476 processDown(mapper, toRawX(50), toRawY(75));
6477 processSync(mapper);
6478
6479 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6480 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6481 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6482
6483 processUp(mapper);
6484 processSync(mapper);
6485 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6486
6487 // Rotation 90.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07006488 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006489 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanea31d4f2022-11-10 20:48:01 +00006490 processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006491 processSync(mapper);
6492
6493 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6494 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6495 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6496
6497 processUp(mapper);
6498 processSync(mapper);
6499 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6500
6501 // Rotation 180.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07006502 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006503 prepareDisplay(ui::ROTATION_180);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006504 processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
6505 processSync(mapper);
6506
6507 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6508 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6509 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6510
6511 processUp(mapper);
6512 processSync(mapper);
6513 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6514
6515 // Rotation 270.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07006516 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006517 prepareDisplay(ui::ROTATION_270);
Prabir Pradhanea31d4f2022-11-10 20:48:01 +00006518 processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006519 processSync(mapper);
6520
6521 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6522 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6523 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6524
6525 processUp(mapper);
6526 processSync(mapper);
6527 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6528}
6529
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006530TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation0_RotatesMotions) {
6531 addConfigurationProperty("touch.deviceType", "touchScreen");
6532 prepareButtons();
6533 prepareAxes(POSITION);
6534 addConfigurationProperty("touch.orientationAware", "1");
6535 addConfigurationProperty("touch.orientation", "ORIENTATION_0");
6536 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006537 prepareDisplay(ui::ROTATION_0);
Arpit Singha8c236b2023-04-25 13:56:05 +00006538 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006539 NotifyMotionArgs args;
6540
6541 // Orientation 0.
6542 processDown(mapper, toRawX(50), toRawY(75));
6543 processSync(mapper);
6544
6545 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6546 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6547 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6548
6549 processUp(mapper);
6550 processSync(mapper);
6551 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6552}
6553
6554TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation90_RotatesMotions) {
6555 addConfigurationProperty("touch.deviceType", "touchScreen");
6556 prepareButtons();
6557 prepareAxes(POSITION);
6558 addConfigurationProperty("touch.orientationAware", "1");
6559 addConfigurationProperty("touch.orientation", "ORIENTATION_90");
6560 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006561 prepareDisplay(ui::ROTATION_0);
Arpit Singha8c236b2023-04-25 13:56:05 +00006562 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006563 NotifyMotionArgs args;
6564
6565 // Orientation 90.
6566 processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
6567 processSync(mapper);
6568
6569 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6570 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6571 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6572
6573 processUp(mapper);
6574 processSync(mapper);
6575 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6576}
6577
6578TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation180_RotatesMotions) {
6579 addConfigurationProperty("touch.deviceType", "touchScreen");
6580 prepareButtons();
6581 prepareAxes(POSITION);
6582 addConfigurationProperty("touch.orientationAware", "1");
6583 addConfigurationProperty("touch.orientation", "ORIENTATION_180");
6584 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006585 prepareDisplay(ui::ROTATION_0);
Arpit Singha8c236b2023-04-25 13:56:05 +00006586 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006587 NotifyMotionArgs args;
6588
6589 // Orientation 180.
6590 processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
6591 processSync(mapper);
6592
6593 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6594 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6595 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6596
6597 processUp(mapper);
6598 processSync(mapper);
6599 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6600}
6601
6602TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation270_RotatesMotions) {
6603 addConfigurationProperty("touch.deviceType", "touchScreen");
6604 prepareButtons();
6605 prepareAxes(POSITION);
6606 addConfigurationProperty("touch.orientationAware", "1");
6607 addConfigurationProperty("touch.orientation", "ORIENTATION_270");
6608 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006609 prepareDisplay(ui::ROTATION_0);
Arpit Singha8c236b2023-04-25 13:56:05 +00006610 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006611 NotifyMotionArgs args;
6612
6613 // Orientation 270.
6614 processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
6615 processSync(mapper);
6616
6617 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6618 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6619 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6620
6621 processUp(mapper);
6622 processSync(mapper);
6623 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6624}
6625
6626TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationSpecified_RotatesMotionWithDisplay) {
6627 addConfigurationProperty("touch.deviceType", "touchScreen");
6628 prepareButtons();
6629 prepareAxes(POSITION);
6630 // Since InputReader works in the un-rotated coordinate space, only devices that are not
6631 // orientation-aware are affected by display rotation.
6632 addConfigurationProperty("touch.orientationAware", "0");
6633 addConfigurationProperty("touch.orientation", "ORIENTATION_90");
Arpit Singha8c236b2023-04-25 13:56:05 +00006634 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006635
6636 NotifyMotionArgs args;
6637
6638 // Orientation 90, Rotation 0.
6639 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006640 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006641 processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
6642 processSync(mapper);
6643
6644 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6645 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6646 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6647
6648 processUp(mapper);
6649 processSync(mapper);
6650 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6651
6652 // Orientation 90, Rotation 90.
6653 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006654 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanea31d4f2022-11-10 20:48:01 +00006655 processDown(mapper, toRawX(50), toRawY(75));
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006656 processSync(mapper);
6657
6658 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6659 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6660 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6661
6662 processUp(mapper);
6663 processSync(mapper);
6664 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6665
6666 // Orientation 90, Rotation 180.
6667 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006668 prepareDisplay(ui::ROTATION_180);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006669 processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
6670 processSync(mapper);
6671
6672 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6673 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6674 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6675
6676 processUp(mapper);
6677 processSync(mapper);
6678 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6679
6680 // Orientation 90, Rotation 270.
6681 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006682 prepareDisplay(ui::ROTATION_270);
Prabir Pradhanea31d4f2022-11-10 20:48:01 +00006683 processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006684 processSync(mapper);
6685
6686 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6687 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6688 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6689
6690 processUp(mapper);
6691 processSync(mapper);
6692 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6693}
6694
Prabir Pradhan675f25a2022-11-10 22:04:07 +00006695TEST_F(SingleTouchInputMapperTest, Process_IgnoresTouchesOutsidePhysicalFrame) {
6696 addConfigurationProperty("touch.deviceType", "touchScreen");
6697 prepareButtons();
6698 prepareAxes(POSITION);
6699 addConfigurationProperty("touch.orientationAware", "1");
6700 prepareDisplay(ui::ROTATION_0);
Arpit Singha8c236b2023-04-25 13:56:05 +00006701 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan675f25a2022-11-10 22:04:07 +00006702
6703 // Set a physical frame in the display viewport.
6704 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
6705 viewport->physicalLeft = 20;
6706 viewport->physicalTop = 600;
6707 viewport->physicalRight = 30;
6708 viewport->physicalBottom = 610;
6709 mFakePolicy->updateViewport(*viewport);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00006710 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhan675f25a2022-11-10 22:04:07 +00006711
6712 // Start the touch.
6713 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
6714 processSync(mapper);
6715
6716 // Expect all input starting outside the physical frame to be ignored.
6717 const std::array<Point, 6> outsidePoints = {
6718 {{0, 0}, {19, 605}, {31, 605}, {25, 599}, {25, 611}, {DISPLAY_WIDTH, DISPLAY_HEIGHT}}};
6719 for (const auto& p : outsidePoints) {
6720 processMove(mapper, toRawX(p.x), toRawY(p.y));
6721 processSync(mapper);
6722 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6723 }
6724
6725 // Move the touch into the physical frame.
6726 processMove(mapper, toRawX(25), toRawY(605));
6727 processSync(mapper);
6728 NotifyMotionArgs args;
6729 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6730 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
6731 EXPECT_NEAR(25, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6732 EXPECT_NEAR(605, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6733
6734 // Once the touch down is reported, continue reporting input, even if it is outside the frame.
6735 for (const auto& p : outsidePoints) {
6736 processMove(mapper, toRawX(p.x), toRawY(p.y));
6737 processSync(mapper);
6738 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6739 EXPECT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
6740 EXPECT_NEAR(p.x, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6741 EXPECT_NEAR(p.y, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6742 }
6743
6744 processUp(mapper);
6745 processSync(mapper);
6746 EXPECT_NO_FATAL_FAILURE(
6747 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
6748}
6749
Harry Cutts1db43992023-06-19 17:05:07 +00006750TEST_F(SingleTouchInputMapperTest, Process_DoesntCheckPhysicalFrameForTouchpads) {
6751 std::shared_ptr<FakePointerController> fakePointerController =
6752 std::make_shared<FakePointerController>();
6753 mFakePolicy->setPointerController(fakePointerController);
6754
6755 addConfigurationProperty("touch.deviceType", "pointer");
6756 prepareAxes(POSITION);
6757 prepareDisplay(ui::ROTATION_0);
6758 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
6759
6760 // Set a physical frame in the display viewport.
6761 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
6762 viewport->physicalLeft = 20;
6763 viewport->physicalTop = 600;
6764 viewport->physicalRight = 30;
6765 viewport->physicalBottom = 610;
6766 mFakePolicy->updateViewport(*viewport);
6767 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
6768
6769 // Start the touch.
6770 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
6771 processSync(mapper);
6772
6773 // Expect all input starting outside the physical frame to result in NotifyMotionArgs being
6774 // produced.
6775 const std::array<Point, 6> outsidePoints = {
6776 {{0, 0}, {19, 605}, {31, 605}, {25, 599}, {25, 611}, {DISPLAY_WIDTH, DISPLAY_HEIGHT}}};
6777 for (const auto& p : outsidePoints) {
6778 processMove(mapper, toRawX(p.x), toRawY(p.y));
6779 processSync(mapper);
6780 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6781 }
6782}
6783
Michael Wrightd02c5b62014-02-10 15:10:22 -08006784TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006785 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006786 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006787 prepareButtons();
6788 prepareAxes(POSITION | PRESSURE | TOOL | DISTANCE | TILT);
Arpit Singha8c236b2023-04-25 13:56:05 +00006789 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006790
6791 // These calculations are based on the input device calibration documentation.
6792 int32_t rawX = 100;
6793 int32_t rawY = 200;
6794 int32_t rawPressure = 10;
6795 int32_t rawToolMajor = 12;
6796 int32_t rawDistance = 2;
6797 int32_t rawTiltX = 30;
6798 int32_t rawTiltY = 110;
6799
6800 float x = toDisplayX(rawX);
6801 float y = toDisplayY(rawY);
6802 float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
6803 float size = float(rawToolMajor) / RAW_TOOL_MAX;
6804 float tool = float(rawToolMajor) * GEOMETRIC_SCALE;
6805 float distance = float(rawDistance);
6806
6807 float tiltCenter = (RAW_TILT_MAX + RAW_TILT_MIN) * 0.5f;
6808 float tiltScale = M_PI / 180;
6809 float tiltXAngle = (rawTiltX - tiltCenter) * tiltScale;
6810 float tiltYAngle = (rawTiltY - tiltCenter) * tiltScale;
6811 float orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
6812 float tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
6813
6814 processDown(mapper, rawX, rawY);
6815 processPressure(mapper, rawPressure);
6816 processToolMajor(mapper, rawToolMajor);
6817 processDistance(mapper, rawDistance);
6818 processTilt(mapper, rawTiltX, rawTiltY);
6819 processSync(mapper);
6820
6821 NotifyMotionArgs args;
6822 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6823 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
6824 x, y, pressure, size, tool, tool, tool, tool, orientation, distance));
6825 ASSERT_EQ(tilt, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TILT));
6826}
6827
Jason Gerecke489fda82012-09-07 17:19:40 -07006828TEST_F(SingleTouchInputMapperTest, Process_XYAxes_AffineCalibration) {
Jason Gerecke489fda82012-09-07 17:19:40 -07006829 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006830 prepareDisplay(ui::ROTATION_0);
Jason Gerecke489fda82012-09-07 17:19:40 -07006831 prepareLocationCalibration();
6832 prepareButtons();
6833 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00006834 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Jason Gerecke489fda82012-09-07 17:19:40 -07006835
6836 int32_t rawX = 100;
6837 int32_t rawY = 200;
6838
6839 float x = toDisplayX(toCookedX(rawX, rawY));
6840 float y = toDisplayY(toCookedY(rawX, rawY));
6841
6842 processDown(mapper, rawX, rawY);
6843 processSync(mapper);
6844
6845 NotifyMotionArgs args;
6846 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6847 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
6848 x, y, 1, 0, 0, 0, 0, 0, 0, 0));
6849}
6850
Michael Wrightd02c5b62014-02-10 15:10:22 -08006851TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006852 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006853 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006854 prepareButtons();
6855 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00006856 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006857
6858 NotifyMotionArgs motionArgs;
6859 NotifyKeyArgs keyArgs;
6860
6861 processDown(mapper, 100, 200);
6862 processSync(mapper);
6863 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6864 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6865 ASSERT_EQ(0, motionArgs.buttonState);
6866
6867 // press BTN_LEFT, release BTN_LEFT
6868 processKey(mapper, BTN_LEFT, 1);
6869 processSync(mapper);
6870 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6871 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6872 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
6873
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006874 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6875 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6876 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
6877
Michael Wrightd02c5b62014-02-10 15:10:22 -08006878 processKey(mapper, BTN_LEFT, 0);
6879 processSync(mapper);
6880 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006881 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006882 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006883
6884 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006885 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006886 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006887
6888 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
6889 processKey(mapper, BTN_RIGHT, 1);
6890 processKey(mapper, BTN_MIDDLE, 1);
6891 processSync(mapper);
6892 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6893 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6894 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
6895 motionArgs.buttonState);
6896
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006897 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6898 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6899 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
6900
6901 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6902 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6903 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
6904 motionArgs.buttonState);
6905
Michael Wrightd02c5b62014-02-10 15:10:22 -08006906 processKey(mapper, BTN_RIGHT, 0);
6907 processSync(mapper);
6908 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006909 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006910 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006911
6912 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006913 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006914 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006915
6916 processKey(mapper, BTN_MIDDLE, 0);
6917 processSync(mapper);
6918 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006919 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006920 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006921
6922 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006923 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006924 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006925
6926 // press BTN_BACK, release BTN_BACK
6927 processKey(mapper, BTN_BACK, 1);
6928 processSync(mapper);
6929 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6930 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6931 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006932
Michael Wrightd02c5b62014-02-10 15:10:22 -08006933 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006934 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006935 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
6936
6937 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6938 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6939 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006940
6941 processKey(mapper, BTN_BACK, 0);
6942 processSync(mapper);
6943 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006944 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006945 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006946
6947 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006948 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006949 ASSERT_EQ(0, motionArgs.buttonState);
6950
Michael Wrightd02c5b62014-02-10 15:10:22 -08006951 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6952 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6953 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
6954
6955 // press BTN_SIDE, release BTN_SIDE
6956 processKey(mapper, BTN_SIDE, 1);
6957 processSync(mapper);
6958 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6959 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6960 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006961
Michael Wrightd02c5b62014-02-10 15:10:22 -08006962 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006963 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006964 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
6965
6966 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6967 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6968 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006969
6970 processKey(mapper, BTN_SIDE, 0);
6971 processSync(mapper);
6972 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006973 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006974 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006975
6976 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006977 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006978 ASSERT_EQ(0, motionArgs.buttonState);
6979
Michael Wrightd02c5b62014-02-10 15:10:22 -08006980 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6981 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6982 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
6983
6984 // press BTN_FORWARD, release BTN_FORWARD
6985 processKey(mapper, BTN_FORWARD, 1);
6986 processSync(mapper);
6987 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6988 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6989 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006990
Michael Wrightd02c5b62014-02-10 15:10:22 -08006991 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006992 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006993 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
6994
6995 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6996 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6997 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006998
6999 processKey(mapper, BTN_FORWARD, 0);
7000 processSync(mapper);
7001 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007002 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007003 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007004
7005 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007006 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007007 ASSERT_EQ(0, motionArgs.buttonState);
7008
Michael Wrightd02c5b62014-02-10 15:10:22 -08007009 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7010 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
7011 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
7012
7013 // press BTN_EXTRA, release BTN_EXTRA
7014 processKey(mapper, BTN_EXTRA, 1);
7015 processSync(mapper);
7016 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7017 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
7018 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007019
Michael Wrightd02c5b62014-02-10 15:10:22 -08007020 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007021 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007022 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
7023
7024 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7025 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7026 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007027
7028 processKey(mapper, BTN_EXTRA, 0);
7029 processSync(mapper);
7030 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007031 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007032 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007033
7034 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007035 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007036 ASSERT_EQ(0, motionArgs.buttonState);
7037
Michael Wrightd02c5b62014-02-10 15:10:22 -08007038 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7039 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
7040 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
7041
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007042 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7043
Michael Wrightd02c5b62014-02-10 15:10:22 -08007044 // press BTN_STYLUS, release BTN_STYLUS
7045 processKey(mapper, BTN_STYLUS, 1);
7046 processSync(mapper);
7047 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7048 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007049 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
7050
7051 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7052 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7053 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007054
7055 processKey(mapper, BTN_STYLUS, 0);
7056 processSync(mapper);
7057 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007058 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007059 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007060
7061 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007062 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007063 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007064
7065 // press BTN_STYLUS2, release BTN_STYLUS2
7066 processKey(mapper, BTN_STYLUS2, 1);
7067 processSync(mapper);
7068 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7069 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007070 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
7071
7072 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7073 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7074 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007075
7076 processKey(mapper, BTN_STYLUS2, 0);
7077 processSync(mapper);
7078 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007079 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007080 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007081
7082 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08007083 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08007084 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007085
7086 // release touch
7087 processUp(mapper);
7088 processSync(mapper);
7089 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7090 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7091 ASSERT_EQ(0, motionArgs.buttonState);
7092}
7093
7094TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007095 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007096 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007097 prepareButtons();
7098 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00007099 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007100
7101 NotifyMotionArgs motionArgs;
7102
7103 // default tool type is finger
7104 processDown(mapper, 100, 200);
7105 processSync(mapper);
7106 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7107 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007108 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007109
7110 // eraser
7111 processKey(mapper, BTN_TOOL_RUBBER, 1);
7112 processSync(mapper);
7113 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7114 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007115 ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007116
7117 // stylus
7118 processKey(mapper, BTN_TOOL_RUBBER, 0);
7119 processKey(mapper, BTN_TOOL_PEN, 1);
7120 processSync(mapper);
7121 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7122 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007123 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007124
7125 // brush
7126 processKey(mapper, BTN_TOOL_PEN, 0);
7127 processKey(mapper, BTN_TOOL_BRUSH, 1);
7128 processSync(mapper);
7129 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7130 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007131 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007132
7133 // pencil
7134 processKey(mapper, BTN_TOOL_BRUSH, 0);
7135 processKey(mapper, BTN_TOOL_PENCIL, 1);
7136 processSync(mapper);
7137 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7138 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007139 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007140
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08007141 // air-brush
Michael Wrightd02c5b62014-02-10 15:10:22 -08007142 processKey(mapper, BTN_TOOL_PENCIL, 0);
7143 processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
7144 processSync(mapper);
7145 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7146 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007147 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007148
7149 // mouse
7150 processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
7151 processKey(mapper, BTN_TOOL_MOUSE, 1);
7152 processSync(mapper);
7153 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7154 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007155 ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007156
7157 // lens
7158 processKey(mapper, BTN_TOOL_MOUSE, 0);
7159 processKey(mapper, BTN_TOOL_LENS, 1);
7160 processSync(mapper);
7161 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7162 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007163 ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007164
7165 // double-tap
7166 processKey(mapper, BTN_TOOL_LENS, 0);
7167 processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
7168 processSync(mapper);
7169 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7170 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007171 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007172
7173 // triple-tap
7174 processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
7175 processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
7176 processSync(mapper);
7177 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7178 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007179 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007180
7181 // quad-tap
7182 processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
7183 processKey(mapper, BTN_TOOL_QUADTAP, 1);
7184 processSync(mapper);
7185 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7186 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007187 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007188
7189 // finger
7190 processKey(mapper, BTN_TOOL_QUADTAP, 0);
7191 processKey(mapper, BTN_TOOL_FINGER, 1);
7192 processSync(mapper);
7193 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7194 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007195 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007196
7197 // stylus trumps finger
7198 processKey(mapper, BTN_TOOL_PEN, 1);
7199 processSync(mapper);
7200 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7201 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007202 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007203
7204 // eraser trumps stylus
7205 processKey(mapper, BTN_TOOL_RUBBER, 1);
7206 processSync(mapper);
7207 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7208 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007209 ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007210
7211 // mouse trumps eraser
7212 processKey(mapper, BTN_TOOL_MOUSE, 1);
7213 processSync(mapper);
7214 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7215 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007216 ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007217
7218 // back to default tool type
7219 processKey(mapper, BTN_TOOL_MOUSE, 0);
7220 processKey(mapper, BTN_TOOL_RUBBER, 0);
7221 processKey(mapper, BTN_TOOL_PEN, 0);
7222 processKey(mapper, BTN_TOOL_FINGER, 0);
7223 processSync(mapper);
7224 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7225 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007226 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007227}
7228
7229TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007230 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007231 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007232 prepareButtons();
7233 prepareAxes(POSITION);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007234 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_FINGER, 0, AKEYCODE_UNKNOWN, 0);
Arpit Singha8c236b2023-04-25 13:56:05 +00007235 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007236
7237 NotifyMotionArgs motionArgs;
7238
7239 // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
7240 processKey(mapper, BTN_TOOL_FINGER, 1);
7241 processMove(mapper, 100, 200);
7242 processSync(mapper);
7243 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7244 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
7245 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7246 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
7247
7248 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7249 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
7250 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7251 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
7252
7253 // move a little
7254 processMove(mapper, 150, 250);
7255 processSync(mapper);
7256 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7257 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
7258 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7259 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7260
7261 // down when BTN_TOUCH is pressed, pressure defaults to 1
7262 processKey(mapper, BTN_TOUCH, 1);
7263 processSync(mapper);
7264 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7265 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
7266 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7267 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7268
7269 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7270 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7271 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7272 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
7273
7274 // up when BTN_TOUCH is released, hover restored
7275 processKey(mapper, BTN_TOUCH, 0);
7276 processSync(mapper);
7277 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7278 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7279 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7280 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
7281
7282 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7283 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
7284 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7285 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7286
7287 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7288 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
7289 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7290 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7291
7292 // exit hover when pointer goes away
7293 processKey(mapper, BTN_TOOL_FINGER, 0);
7294 processSync(mapper);
7295 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7296 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
7297 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7298 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7299}
7300
7301TEST_F(SingleTouchInputMapperTest, Process_WhenAbsPressureIsPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007302 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007303 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007304 prepareButtons();
7305 prepareAxes(POSITION | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +00007306 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007307
7308 NotifyMotionArgs motionArgs;
7309
7310 // initially hovering because pressure is 0
7311 processDown(mapper, 100, 200);
7312 processPressure(mapper, 0);
7313 processSync(mapper);
7314 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7315 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
7316 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7317 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
7318
7319 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7320 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
7321 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7322 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
7323
7324 // move a little
7325 processMove(mapper, 150, 250);
7326 processSync(mapper);
7327 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7328 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
7329 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7330 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7331
7332 // down when pressure is non-zero
7333 processPressure(mapper, RAW_PRESSURE_MAX);
7334 processSync(mapper);
7335 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7336 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
7337 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7338 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7339
7340 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7341 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7342 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7343 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
7344
7345 // up when pressure becomes 0, hover restored
7346 processPressure(mapper, 0);
7347 processSync(mapper);
7348 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7349 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7350 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7351 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
7352
7353 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7354 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
7355 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7356 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7357
7358 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7359 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
7360 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7361 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7362
7363 // exit hover when pointer goes away
7364 processUp(mapper);
7365 processSync(mapper);
7366 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7367 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
7368 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7369 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7370}
7371
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00007372TEST_F(SingleTouchInputMapperTest, Reset_CancelsOngoingGesture) {
7373 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007374 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00007375 prepareButtons();
7376 prepareAxes(POSITION | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +00007377 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00007378
7379 // Touch down.
7380 processDown(mapper, 100, 200);
7381 processPressure(mapper, 1);
7382 processSync(mapper);
7383 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7384 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
7385
7386 // Reset the mapper. This should cancel the ongoing gesture.
7387 resetMapper(mapper, ARBITRARY_TIME);
7388 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7389 WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
7390
7391 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7392}
7393
Prabir Pradhanafabcde2022-09-27 19:32:43 +00007394TEST_F(SingleTouchInputMapperTest, Reset_RecreatesTouchState) {
7395 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007396 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00007397 prepareButtons();
7398 prepareAxes(POSITION | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +00007399 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanafabcde2022-09-27 19:32:43 +00007400
7401 // Set the initial state for the touch pointer.
7402 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_X, 100);
7403 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_Y, 200);
7404 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MAX);
7405 mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1);
7406
7407 // Reset the mapper. When the mapper is reset, we expect it to attempt to recreate the touch
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00007408 // state by reading the current axis values. Since there was no ongoing gesture, calling reset
7409 // does not generate any events.
7410 resetMapper(mapper, ARBITRARY_TIME);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00007411
7412 // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
7413 // the recreated touch state to generate a down event.
7414 processSync(mapper);
7415 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7416 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
7417
7418 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7419}
7420
lilinnan687e58f2022-07-19 16:00:50 +08007421TEST_F(SingleTouchInputMapperTest,
7422 Process_WhenViewportDisplayIdChanged_TouchIsCanceledAndDeviceIsReset) {
7423 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007424 prepareDisplay(ui::ROTATION_0);
lilinnan687e58f2022-07-19 16:00:50 +08007425 prepareButtons();
7426 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00007427 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
lilinnan687e58f2022-07-19 16:00:50 +08007428 NotifyMotionArgs motionArgs;
7429
7430 // Down.
Prabir Pradhan3e5ec702022-07-29 16:26:24 +00007431 processDown(mapper, 100, 200);
lilinnan687e58f2022-07-19 16:00:50 +08007432 processSync(mapper);
7433
7434 // We should receive a down event
7435 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7436 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7437
7438 // Change display id
7439 clearViewports();
7440 prepareSecondaryDisplay(ViewportType::INTERNAL);
7441
7442 // We should receive a cancel event
7443 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7444 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
7445 // Then receive reset called
7446 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
7447}
7448
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00007449TEST_F(SingleTouchInputMapperTest,
7450 Process_WhenViewportActiveStatusChanged_TouchIsCanceledAndDeviceIsReset) {
7451 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007452 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00007453 prepareButtons();
7454 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00007455 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00007456 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
7457 NotifyMotionArgs motionArgs;
7458
7459 // Start a new gesture.
7460 processDown(mapper, 100, 200);
7461 processSync(mapper);
7462 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7463 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7464
7465 // Make the viewport inactive. This will put the device in disabled mode.
7466 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
7467 viewport->isActive = false;
7468 mFakePolicy->updateViewport(*viewport);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00007469 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00007470
7471 // We should receive a cancel event for the ongoing gesture.
7472 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7473 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
7474 // Then we should be notified that the device was reset.
7475 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
7476
7477 // No events are generated while the viewport is inactive.
7478 processMove(mapper, 101, 201);
7479 processSync(mapper);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00007480 processUp(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00007481 processSync(mapper);
7482 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7483
Prabir Pradhanafabcde2022-09-27 19:32:43 +00007484 // Start a new gesture while the viewport is still inactive.
7485 processDown(mapper, 300, 400);
7486 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_X, 300);
7487 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_Y, 400);
7488 mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1);
7489 processSync(mapper);
7490
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00007491 // Make the viewport active again. The device should resume processing events.
7492 viewport->isActive = true;
7493 mFakePolicy->updateViewport(*viewport);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00007494 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00007495
7496 // The device is reset because it changes back to direct mode, without generating any events.
7497 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
7498 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7499
Prabir Pradhanafabcde2022-09-27 19:32:43 +00007500 // In the next sync, the touch state that was recreated when the device was reset is reported.
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00007501 processSync(mapper);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00007502 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7503 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00007504
7505 // No more events.
7506 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7507 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
7508}
7509
Prabir Pradhan211ba622022-10-31 21:09:21 +00007510TEST_F(SingleTouchInputMapperTest, ButtonIsReleasedOnTouchUp) {
7511 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007512 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan211ba622022-10-31 21:09:21 +00007513 prepareButtons();
7514 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00007515 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan211ba622022-10-31 21:09:21 +00007516 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
7517
7518 // Press a stylus button.
7519 processKey(mapper, BTN_STYLUS, 1);
7520 processSync(mapper);
7521
7522 // Start a touch gesture and ensure the BUTTON_PRESS event is generated.
7523 processDown(mapper, 100, 200);
7524 processSync(mapper);
7525 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7526 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
7527 WithCoords(toDisplayX(100), toDisplayY(200)),
7528 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
7529 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7530 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
7531 WithCoords(toDisplayX(100), toDisplayY(200)),
7532 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
7533
7534 // Release the touch gesture. Ensure that the BUTTON_RELEASE event is generated even though
7535 // the button has not actually been released, since there will be no pointers through which the
7536 // button state can be reported. The event is generated at the location of the pointer before
7537 // it went up.
7538 processUp(mapper);
7539 processSync(mapper);
7540 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7541 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
7542 WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
7543 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7544 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
7545 WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
7546}
7547
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00007548TEST_F(SingleTouchInputMapperTest, StylusButtonMotionEventsDisabled) {
7549 addConfigurationProperty("touch.deviceType", "touchScreen");
7550 prepareDisplay(ui::ROTATION_0);
7551 prepareButtons();
7552 prepareAxes(POSITION);
7553
7554 mFakePolicy->setStylusButtonMotionEventsEnabled(false);
7555
Arpit Singha8c236b2023-04-25 13:56:05 +00007556 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00007557 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
7558
7559 // Press a stylus button.
7560 processKey(mapper, BTN_STYLUS, 1);
7561 processSync(mapper);
7562
7563 // Start a touch gesture and ensure that the stylus button is not reported.
7564 processDown(mapper, 100, 200);
7565 processSync(mapper);
7566 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7567 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithButtonState(0))));
7568
7569 // Release and press the stylus button again.
7570 processKey(mapper, BTN_STYLUS, 0);
7571 processSync(mapper);
7572 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7573 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
7574 processKey(mapper, BTN_STYLUS, 1);
7575 processSync(mapper);
7576 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7577 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
7578
7579 // Release the touch gesture.
7580 processUp(mapper);
7581 processSync(mapper);
7582 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7583 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
7584
7585 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7586}
7587
Ambrus Weisz7bc23bf2022-10-04 13:13:07 +00007588TEST_F(SingleTouchInputMapperTest, WhenDeviceTypeIsSetToTouchNavigation_setsCorrectType) {
7589 mFakePolicy->addDeviceTypeAssociation(DEVICE_LOCATION, "touchNavigation");
7590 prepareDisplay(ui::ROTATION_0);
7591 prepareButtons();
7592 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00007593 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Ambrus Weisz7bc23bf2022-10-04 13:13:07 +00007594 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
7595
7596 ASSERT_EQ(AINPUT_SOURCE_TOUCH_NAVIGATION, mapper.getSources());
7597}
7598
Seunghwan Choi356026c2023-02-01 14:37:25 +09007599TEST_F(SingleTouchInputMapperTest, Process_WhenConfigEnabled_ShouldShowDirectStylusPointer) {
7600 std::shared_ptr<FakePointerController> fakePointerController =
7601 std::make_shared<FakePointerController>();
7602 addConfigurationProperty("touch.deviceType", "touchScreen");
7603 prepareDisplay(ui::ROTATION_0);
7604 prepareButtons();
7605 prepareAxes(POSITION);
7606 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
7607 mFakePolicy->setPointerController(fakePointerController);
7608 mFakePolicy->setStylusPointerIconEnabled(true);
Arpit Singha8c236b2023-04-25 13:56:05 +00007609 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Seunghwan Choi356026c2023-02-01 14:37:25 +09007610
7611 processKey(mapper, BTN_TOOL_PEN, 1);
7612 processMove(mapper, 100, 200);
7613 processSync(mapper);
7614 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7615 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007616 WithToolType(ToolType::STYLUS),
Seunghwan Choi356026c2023-02-01 14:37:25 +09007617 WithPointerCoords(0, toDisplayX(100), toDisplayY(200)))));
7618 ASSERT_TRUE(fakePointerController->isPointerShown());
7619 ASSERT_NO_FATAL_FAILURE(
7620 fakePointerController->assertPosition(toDisplayX(100), toDisplayY(200)));
7621}
7622
7623TEST_F(SingleTouchInputMapperTest, Process_WhenConfigDisabled_ShouldNotShowDirectStylusPointer) {
7624 std::shared_ptr<FakePointerController> fakePointerController =
7625 std::make_shared<FakePointerController>();
7626 addConfigurationProperty("touch.deviceType", "touchScreen");
7627 prepareDisplay(ui::ROTATION_0);
7628 prepareButtons();
7629 prepareAxes(POSITION);
7630 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
7631 mFakePolicy->setPointerController(fakePointerController);
7632 mFakePolicy->setStylusPointerIconEnabled(false);
Arpit Singha8c236b2023-04-25 13:56:05 +00007633 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Seunghwan Choi356026c2023-02-01 14:37:25 +09007634
7635 processKey(mapper, BTN_TOOL_PEN, 1);
7636 processMove(mapper, 100, 200);
7637 processSync(mapper);
7638 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7639 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007640 WithToolType(ToolType::STYLUS),
Seunghwan Choi356026c2023-02-01 14:37:25 +09007641 WithPointerCoords(0, toDisplayX(100), toDisplayY(200)))));
7642 ASSERT_FALSE(fakePointerController->isPointerShown());
7643}
7644
Ambrus Weisz7b6e16b2022-12-16 17:54:57 +00007645TEST_F(SingleTouchInputMapperTest, WhenDeviceTypeIsChangedToTouchNavigation_updatesDeviceType) {
7646 // Initialize the device without setting device source to touch navigation.
7647 addConfigurationProperty("touch.deviceType", "touchScreen");
7648 prepareDisplay(ui::ROTATION_0);
7649 prepareButtons();
7650 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00007651 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Ambrus Weisz7b6e16b2022-12-16 17:54:57 +00007652
7653 // Ensure that the device is created as a touchscreen, not touch navigation.
7654 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
7655
7656 // Add device type association after the device was created.
7657 mFakePolicy->addDeviceTypeAssociation(DEVICE_LOCATION, "touchNavigation");
7658
7659 // Send update to the mapper.
7660 std::list<NotifyArgs> unused2 =
7661 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00007662 InputReaderConfiguration::Change::DEVICE_TYPE /*changes*/);
Ambrus Weisz7b6e16b2022-12-16 17:54:57 +00007663
7664 // Check whether device type update was successful.
7665 ASSERT_EQ(AINPUT_SOURCE_TOUCH_NAVIGATION, mDevice->getSources());
7666}
7667
Prabir Pradhane1e309a2022-11-29 02:54:27 +00007668TEST_F(SingleTouchInputMapperTest, HoverEventsOutsidePhysicalFrameAreIgnored) {
7669 // Initialize the device without setting device source to touch navigation.
7670 addConfigurationProperty("touch.deviceType", "touchScreen");
7671 prepareDisplay(ui::ROTATION_0);
7672 prepareButtons();
7673 prepareAxes(POSITION);
7674 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
7675
7676 // Set a physical frame in the display viewport.
7677 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
7678 viewport->physicalLeft = 0;
7679 viewport->physicalTop = 0;
7680 viewport->physicalRight = DISPLAY_WIDTH / 2;
7681 viewport->physicalBottom = DISPLAY_HEIGHT / 2;
7682 mFakePolicy->updateViewport(*viewport);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00007683 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhane1e309a2022-11-29 02:54:27 +00007684
Arpit Singha8c236b2023-04-25 13:56:05 +00007685 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhane1e309a2022-11-29 02:54:27 +00007686
7687 // Hovering inside the physical frame produces events.
7688 processKey(mapper, BTN_TOOL_PEN, 1);
7689 processMove(mapper, RAW_X_MIN + 1, RAW_Y_MIN + 1);
7690 processSync(mapper);
7691 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7692 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER)));
7693 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7694 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE)));
7695
7696 // Leaving the physical frame ends the hovering gesture.
7697 processMove(mapper, RAW_X_MAX - 1, RAW_Y_MAX - 1);
7698 processSync(mapper);
7699 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7700 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT)));
7701
7702 // Moving outside the physical frame does not produce events.
7703 processMove(mapper, RAW_X_MAX - 2, RAW_Y_MAX - 2);
7704 processSync(mapper);
7705 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7706
7707 // Re-entering the physical frame produces events.
7708 processMove(mapper, RAW_X_MIN, RAW_Y_MIN);
7709 processSync(mapper);
7710 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7711 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER)));
7712 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7713 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE)));
7714}
7715
Prabir Pradhan5632d622021-09-06 07:57:20 -07007716// --- TouchDisplayProjectionTest ---
7717
7718class TouchDisplayProjectionTest : public SingleTouchInputMapperTest {
7719public:
7720 // The values inside DisplayViewport are expected to be pre-rotated. This updates the current
7721 // DisplayViewport to pre-rotate the values. The viewport's physical display will be set to the
7722 // rotated equivalent of the given un-rotated physical display bounds.
Prabir Pradhana9df3162022-12-05 23:57:27 +00007723 void configurePhysicalDisplay(ui::Rotation orientation, Rect naturalPhysicalDisplay,
7724 int32_t naturalDisplayWidth = DISPLAY_WIDTH,
7725 int32_t naturalDisplayHeight = DISPLAY_HEIGHT) {
Prabir Pradhan5632d622021-09-06 07:57:20 -07007726 uint32_t inverseRotationFlags;
Prabir Pradhana9df3162022-12-05 23:57:27 +00007727 auto rotatedWidth = naturalDisplayWidth;
7728 auto rotatedHeight = naturalDisplayHeight;
Prabir Pradhan5632d622021-09-06 07:57:20 -07007729 switch (orientation) {
Michael Wrighta9cf4192022-12-01 23:46:39 +00007730 case ui::ROTATION_90:
Prabir Pradhan5632d622021-09-06 07:57:20 -07007731 inverseRotationFlags = ui::Transform::ROT_270;
Prabir Pradhana9df3162022-12-05 23:57:27 +00007732 std::swap(rotatedWidth, rotatedHeight);
Prabir Pradhan5632d622021-09-06 07:57:20 -07007733 break;
Michael Wrighta9cf4192022-12-01 23:46:39 +00007734 case ui::ROTATION_180:
Prabir Pradhan5632d622021-09-06 07:57:20 -07007735 inverseRotationFlags = ui::Transform::ROT_180;
7736 break;
Michael Wrighta9cf4192022-12-01 23:46:39 +00007737 case ui::ROTATION_270:
Prabir Pradhan5632d622021-09-06 07:57:20 -07007738 inverseRotationFlags = ui::Transform::ROT_90;
Prabir Pradhana9df3162022-12-05 23:57:27 +00007739 std::swap(rotatedWidth, rotatedHeight);
Prabir Pradhan5632d622021-09-06 07:57:20 -07007740 break;
Michael Wrighta9cf4192022-12-01 23:46:39 +00007741 case ui::ROTATION_0:
Prabir Pradhan5632d622021-09-06 07:57:20 -07007742 inverseRotationFlags = ui::Transform::ROT_0;
7743 break;
Prabir Pradhan5632d622021-09-06 07:57:20 -07007744 }
7745
Prabir Pradhana9df3162022-12-05 23:57:27 +00007746 const ui::Transform rotation(inverseRotationFlags, rotatedWidth, rotatedHeight);
Prabir Pradhan5632d622021-09-06 07:57:20 -07007747 const Rect rotatedPhysicalDisplay = rotation.transform(naturalPhysicalDisplay);
7748
7749 std::optional<DisplayViewport> internalViewport =
7750 *mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
7751 DisplayViewport& v = *internalViewport;
7752 v.displayId = DISPLAY_ID;
7753 v.orientation = orientation;
7754
7755 v.logicalLeft = 0;
7756 v.logicalTop = 0;
7757 v.logicalRight = 100;
7758 v.logicalBottom = 100;
7759
7760 v.physicalLeft = rotatedPhysicalDisplay.left;
7761 v.physicalTop = rotatedPhysicalDisplay.top;
7762 v.physicalRight = rotatedPhysicalDisplay.right;
7763 v.physicalBottom = rotatedPhysicalDisplay.bottom;
7764
Prabir Pradhana9df3162022-12-05 23:57:27 +00007765 v.deviceWidth = rotatedWidth;
7766 v.deviceHeight = rotatedHeight;
Prabir Pradhan5632d622021-09-06 07:57:20 -07007767
7768 v.isActive = true;
7769 v.uniqueId = UNIQUE_ID;
7770 v.type = ViewportType::INTERNAL;
7771 mFakePolicy->updateViewport(v);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00007772 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhan5632d622021-09-06 07:57:20 -07007773 }
7774
7775 void assertReceivedMove(const Point& point) {
7776 NotifyMotionArgs motionArgs;
7777 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7778 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07007779 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Prabir Pradhan5632d622021-09-06 07:57:20 -07007780 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], point.x, point.y,
7781 1, 0, 0, 0, 0, 0, 0, 0));
7782 }
7783};
7784
7785TEST_F(TouchDisplayProjectionTest, IgnoresTouchesOutsidePhysicalDisplay) {
7786 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007787 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan5632d622021-09-06 07:57:20 -07007788
7789 prepareButtons();
7790 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00007791 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan5632d622021-09-06 07:57:20 -07007792
7793 NotifyMotionArgs motionArgs;
7794
7795 // Configure the DisplayViewport such that the logical display maps to a subsection of
7796 // the display panel called the physical display. Here, the physical display is bounded by the
7797 // points (10, 20) and (70, 160) inside the display space, which is of the size 400 x 800.
7798 static const Rect kPhysicalDisplay{10, 20, 70, 160};
7799 static const std::array<Point, 6> kPointsOutsidePhysicalDisplay{
7800 {{-10, -10}, {0, 0}, {5, 100}, {50, 15}, {75, 100}, {50, 165}}};
7801
Michael Wrighta9cf4192022-12-01 23:46:39 +00007802 for (auto orientation : {ui::ROTATION_0, ui::ROTATION_90, ui::ROTATION_180, ui::ROTATION_270}) {
Prabir Pradhan5632d622021-09-06 07:57:20 -07007803 configurePhysicalDisplay(orientation, kPhysicalDisplay);
7804
7805 // Touches outside the physical display should be ignored, and should not generate any
7806 // events. Ensure touches at the following points that lie outside of the physical display
7807 // area do not generate any events.
7808 for (const auto& point : kPointsOutsidePhysicalDisplay) {
7809 processDown(mapper, toRawX(point.x), toRawY(point.y));
7810 processSync(mapper);
7811 processUp(mapper);
7812 processSync(mapper);
7813 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled())
7814 << "Unexpected event generated for touch outside physical display at point: "
7815 << point.x << ", " << point.y;
7816 }
7817 }
7818}
7819
7820TEST_F(TouchDisplayProjectionTest, EmitsTouchDownAfterEnteringPhysicalDisplay) {
7821 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007822 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan5632d622021-09-06 07:57:20 -07007823
7824 prepareButtons();
7825 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00007826 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan5632d622021-09-06 07:57:20 -07007827
7828 NotifyMotionArgs motionArgs;
7829
7830 // Configure the DisplayViewport such that the logical display maps to a subsection of
7831 // the display panel called the physical display. Here, the physical display is bounded by the
7832 // points (10, 20) and (70, 160) inside the display space, which is of the size 400 x 800.
7833 static const Rect kPhysicalDisplay{10, 20, 70, 160};
7834
Michael Wrighta9cf4192022-12-01 23:46:39 +00007835 for (auto orientation : {ui::ROTATION_0, ui::ROTATION_90, ui::ROTATION_180, ui::ROTATION_270}) {
Prabir Pradhan5632d622021-09-06 07:57:20 -07007836 configurePhysicalDisplay(orientation, kPhysicalDisplay);
7837
7838 // Touches that start outside the physical display should be ignored until it enters the
7839 // physical display bounds, at which point it should generate a down event. Start a touch at
7840 // the point (5, 100), which is outside the physical display bounds.
7841 static const Point kOutsidePoint{5, 100};
7842 processDown(mapper, toRawX(kOutsidePoint.x), toRawY(kOutsidePoint.y));
7843 processSync(mapper);
7844 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7845
7846 // Move the touch into the physical display area. This should generate a pointer down.
7847 processMove(mapper, toRawX(11), toRawY(21));
7848 processSync(mapper);
7849 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7850 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07007851 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Prabir Pradhan5632d622021-09-06 07:57:20 -07007852 ASSERT_NO_FATAL_FAILURE(
7853 assertPointerCoords(motionArgs.pointerCoords[0], 11, 21, 1, 0, 0, 0, 0, 0, 0, 0));
7854
7855 // Move the touch inside the physical display area. This should generate a pointer move.
7856 processMove(mapper, toRawX(69), toRawY(159));
7857 processSync(mapper);
7858 assertReceivedMove({69, 159});
7859
7860 // Move outside the physical display area. Since the pointer is already down, this should
7861 // now continue generating events.
7862 processMove(mapper, toRawX(kOutsidePoint.x), toRawY(kOutsidePoint.y));
7863 processSync(mapper);
7864 assertReceivedMove(kOutsidePoint);
7865
7866 // Release. This should generate a pointer up.
7867 processUp(mapper);
7868 processSync(mapper);
7869 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7870 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7871 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], kOutsidePoint.x,
7872 kOutsidePoint.y, 1, 0, 0, 0, 0, 0, 0, 0));
7873
7874 // Ensure no more events were generated.
7875 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7876 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7877 }
7878}
7879
Prabir Pradhana9df3162022-12-05 23:57:27 +00007880// --- TouchscreenPrecisionTests ---
7881
7882// This test suite is used to ensure that touchscreen devices are scaled and configured correctly
7883// in various orientations and with different display rotations. We configure the touchscreen to
7884// have a higher resolution than that of the display by an integer scale factor in each axis so that
7885// we can enforce that coordinates match precisely as expected.
7886class TouchscreenPrecisionTestsFixture : public TouchDisplayProjectionTest,
7887 public ::testing::WithParamInterface<ui::Rotation> {
7888public:
7889 void SetUp() override {
7890 SingleTouchInputMapperTest::SetUp();
7891
7892 // Prepare the raw axes to have twice the resolution of the display in the X axis and
7893 // four times the resolution of the display in the Y axis.
7894 prepareButtons();
7895 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, PRECISION_RAW_X_MIN, PRECISION_RAW_X_MAX,
Prabir Pradhan46211fb2022-12-17 00:30:39 +00007896 PRECISION_RAW_X_FLAT, PRECISION_RAW_X_FUZZ,
7897 PRECISION_RAW_X_RES);
Prabir Pradhana9df3162022-12-05 23:57:27 +00007898 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, PRECISION_RAW_Y_MIN, PRECISION_RAW_Y_MAX,
Prabir Pradhan46211fb2022-12-17 00:30:39 +00007899 PRECISION_RAW_Y_FLAT, PRECISION_RAW_Y_FUZZ,
7900 PRECISION_RAW_Y_RES);
Prabir Pradhana9df3162022-12-05 23:57:27 +00007901 }
7902
7903 static const int32_t PRECISION_RAW_X_MIN = TouchInputMapperTest::RAW_X_MIN;
7904 static const int32_t PRECISION_RAW_X_MAX = PRECISION_RAW_X_MIN + DISPLAY_WIDTH * 2 - 1;
7905 static const int32_t PRECISION_RAW_Y_MIN = TouchInputMapperTest::RAW_Y_MIN;
7906 static const int32_t PRECISION_RAW_Y_MAX = PRECISION_RAW_Y_MIN + DISPLAY_HEIGHT * 4 - 1;
7907
Prabir Pradhan46211fb2022-12-17 00:30:39 +00007908 static const int32_t PRECISION_RAW_X_RES = 50; // units per millimeter
7909 static const int32_t PRECISION_RAW_Y_RES = 100; // units per millimeter
7910
7911 static const int32_t PRECISION_RAW_X_FLAT = 16;
7912 static const int32_t PRECISION_RAW_Y_FLAT = 32;
7913
7914 static const int32_t PRECISION_RAW_X_FUZZ = 4;
7915 static const int32_t PRECISION_RAW_Y_FUZZ = 8;
7916
Prabir Pradhana9df3162022-12-05 23:57:27 +00007917 static const std::array<Point, 4> kRawCorners;
7918};
7919
7920const std::array<Point, 4> TouchscreenPrecisionTestsFixture::kRawCorners = {{
7921 {PRECISION_RAW_X_MIN, PRECISION_RAW_Y_MIN}, // left-top
7922 {PRECISION_RAW_X_MAX, PRECISION_RAW_Y_MIN}, // right-top
7923 {PRECISION_RAW_X_MAX, PRECISION_RAW_Y_MAX}, // right-bottom
7924 {PRECISION_RAW_X_MIN, PRECISION_RAW_Y_MAX}, // left-bottom
7925}};
7926
7927// Tests for how the touchscreen is oriented relative to the natural orientation of the display.
7928// For example, if a touchscreen is configured with an orientation of 90 degrees, it is a portrait
7929// touchscreen panel that is used on a device whose natural display orientation is in landscape.
7930TEST_P(TouchscreenPrecisionTestsFixture, OrientationPrecision) {
7931 enum class Orientation {
7932 ORIENTATION_0 = ui::toRotationInt(ui::ROTATION_0),
7933 ORIENTATION_90 = ui::toRotationInt(ui::ROTATION_90),
7934 ORIENTATION_180 = ui::toRotationInt(ui::ROTATION_180),
7935 ORIENTATION_270 = ui::toRotationInt(ui::ROTATION_270),
7936 ftl_last = ORIENTATION_270,
7937 };
7938 using Orientation::ORIENTATION_0, Orientation::ORIENTATION_90, Orientation::ORIENTATION_180,
7939 Orientation::ORIENTATION_270;
7940 static const std::map<Orientation, std::array<vec2, 4> /*mappedCorners*/> kMappedCorners = {
7941 {ORIENTATION_0, {{{0, 0}, {479.5, 0}, {479.5, 799.75}, {0, 799.75}}}},
7942 {ORIENTATION_90, {{{0, 479.5}, {0, 0}, {799.75, 0}, {799.75, 479.5}}}},
7943 {ORIENTATION_180, {{{479.5, 799.75}, {0, 799.75}, {0, 0}, {479.5, 0}}}},
7944 {ORIENTATION_270, {{{799.75, 0}, {799.75, 479.5}, {0, 479.5}, {0, 0}}}},
7945 };
7946
7947 const auto touchscreenOrientation = static_cast<Orientation>(ui::toRotationInt(GetParam()));
7948
7949 // Configure the touchscreen as being installed in the one of the four different orientations
7950 // relative to the display.
7951 addConfigurationProperty("touch.deviceType", "touchScreen");
7952 addConfigurationProperty("touch.orientation", ftl::enum_string(touchscreenOrientation).c_str());
7953 prepareDisplay(ui::ROTATION_0);
7954
Arpit Singha8c236b2023-04-25 13:56:05 +00007955 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhana9df3162022-12-05 23:57:27 +00007956
7957 // If the touchscreen is installed in a rotated orientation relative to the display (i.e. in
7958 // orientations of either 90 or 270) this means the display's natural resolution will be
7959 // flipped.
7960 const bool displayRotated =
7961 touchscreenOrientation == ORIENTATION_90 || touchscreenOrientation == ORIENTATION_270;
7962 const int32_t width = displayRotated ? DISPLAY_HEIGHT : DISPLAY_WIDTH;
7963 const int32_t height = displayRotated ? DISPLAY_WIDTH : DISPLAY_HEIGHT;
7964 const Rect physicalFrame{0, 0, width, height};
7965 configurePhysicalDisplay(ui::ROTATION_0, physicalFrame, width, height);
7966
7967 const auto& expectedPoints = kMappedCorners.at(touchscreenOrientation);
7968 const float expectedPrecisionX = displayRotated ? 4 : 2;
7969 const float expectedPrecisionY = displayRotated ? 2 : 4;
7970
7971 // Test all four corners.
7972 for (int i = 0; i < 4; i++) {
7973 const auto& raw = kRawCorners[i];
7974 processDown(mapper, raw.x, raw.y);
7975 processSync(mapper);
7976 const auto& expected = expectedPoints[i];
7977 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7978 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
7979 WithCoords(expected.x, expected.y),
7980 WithPrecision(expectedPrecisionX, expectedPrecisionY))))
7981 << "Failed to process raw point (" << raw.x << ", " << raw.y << ") "
7982 << "with touchscreen orientation "
7983 << ftl::enum_string(touchscreenOrientation).c_str() << ", expected point ("
7984 << expected.x << ", " << expected.y << ").";
7985 processUp(mapper);
7986 processSync(mapper);
7987 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7988 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
7989 WithCoords(expected.x, expected.y))));
7990 }
7991}
7992
Prabir Pradhan82687402022-12-06 01:32:53 +00007993TEST_P(TouchscreenPrecisionTestsFixture, RotationPrecisionWhenOrientationAware) {
7994 static const std::map<ui::Rotation /*rotation*/, std::array<vec2, 4> /*mappedCorners*/>
7995 kMappedCorners = {
7996 {ui::ROTATION_0, {{{0, 0}, {479.5, 0}, {479.5, 799.75}, {0, 799.75}}}},
7997 {ui::ROTATION_90, {{{0.5, 0}, {480, 0}, {480, 799.75}, {0.5, 799.75}}}},
7998 {ui::ROTATION_180, {{{0.5, 0.25}, {480, 0.25}, {480, 800}, {0.5, 800}}}},
7999 {ui::ROTATION_270, {{{0, 0.25}, {479.5, 0.25}, {479.5, 800}, {0, 800}}}},
8000 };
8001
8002 const ui::Rotation displayRotation = GetParam();
8003
8004 addConfigurationProperty("touch.deviceType", "touchScreen");
8005 prepareDisplay(displayRotation);
8006
Arpit Singha8c236b2023-04-25 13:56:05 +00008007 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan82687402022-12-06 01:32:53 +00008008
8009 const auto& expectedPoints = kMappedCorners.at(displayRotation);
8010
8011 // Test all four corners.
8012 for (int i = 0; i < 4; i++) {
8013 const auto& expected = expectedPoints[i];
8014 const auto& raw = kRawCorners[i];
8015 processDown(mapper, raw.x, raw.y);
8016 processSync(mapper);
8017 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8018 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
8019 WithCoords(expected.x, expected.y), WithPrecision(2, 4))))
8020 << "Failed to process raw point (" << raw.x << ", " << raw.y << ") "
8021 << "with display rotation " << ui::toCString(displayRotation)
8022 << ", expected point (" << expected.x << ", " << expected.y << ").";
8023 processUp(mapper);
8024 processSync(mapper);
8025 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8026 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
8027 WithCoords(expected.x, expected.y))));
8028 }
8029}
8030
Prabir Pradhan3e798762022-12-02 21:02:11 +00008031TEST_P(TouchscreenPrecisionTestsFixture, RotationPrecisionOrientationAwareInOri270) {
8032 static const std::map<ui::Rotation /*orientation*/, std::array<vec2, 4> /*mappedCorners*/>
8033 kMappedCorners = {
8034 {ui::ROTATION_0, {{{799.75, 0}, {799.75, 479.5}, {0, 479.5}, {0, 0}}}},
8035 {ui::ROTATION_90, {{{800, 0}, {800, 479.5}, {0.25, 479.5}, {0.25, 0}}}},
8036 {ui::ROTATION_180, {{{800, 0.5}, {800, 480}, {0.25, 480}, {0.25, 0.5}}}},
8037 {ui::ROTATION_270, {{{799.75, 0.5}, {799.75, 480}, {0, 480}, {0, 0.5}}}},
8038 };
8039
8040 const ui::Rotation displayRotation = GetParam();
8041
8042 addConfigurationProperty("touch.deviceType", "touchScreen");
8043 addConfigurationProperty("touch.orientation", "ORIENTATION_270");
8044
Arpit Singha8c236b2023-04-25 13:56:05 +00008045 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan3e798762022-12-02 21:02:11 +00008046
8047 // Ori 270, so width and height swapped
8048 const Rect physicalFrame{0, 0, DISPLAY_HEIGHT, DISPLAY_WIDTH};
8049 prepareDisplay(displayRotation);
8050 configurePhysicalDisplay(displayRotation, physicalFrame, DISPLAY_HEIGHT, DISPLAY_WIDTH);
8051
8052 const auto& expectedPoints = kMappedCorners.at(displayRotation);
8053
8054 // Test all four corners.
8055 for (int i = 0; i < 4; i++) {
8056 const auto& expected = expectedPoints[i];
8057 const auto& raw = kRawCorners[i];
8058 processDown(mapper, raw.x, raw.y);
8059 processSync(mapper);
8060 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8061 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
8062 WithCoords(expected.x, expected.y), WithPrecision(4, 2))))
8063 << "Failed to process raw point (" << raw.x << ", " << raw.y << ") "
8064 << "with display rotation " << ui::toCString(displayRotation)
8065 << ", expected point (" << expected.x << ", " << expected.y << ").";
8066 processUp(mapper);
8067 processSync(mapper);
8068 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8069 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
8070 WithCoords(expected.x, expected.y))));
8071 }
8072}
8073
Prabir Pradhan46211fb2022-12-17 00:30:39 +00008074TEST_P(TouchscreenPrecisionTestsFixture, MotionRangesAreOrientedInRotatedDisplay) {
8075 const ui::Rotation displayRotation = GetParam();
8076
8077 addConfigurationProperty("touch.deviceType", "touchScreen");
8078 prepareDisplay(displayRotation);
8079
8080 __attribute__((unused)) SingleTouchInputMapper& mapper =
Arpit Singha8c236b2023-04-25 13:56:05 +00008081 constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan46211fb2022-12-17 00:30:39 +00008082
8083 const InputDeviceInfo deviceInfo = mDevice->getDeviceInfo();
8084 // MotionRanges use display pixels as their units
8085 const auto* xRange = deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_X, AINPUT_SOURCE_TOUCHSCREEN);
8086 const auto* yRange = deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_Y, AINPUT_SOURCE_TOUCHSCREEN);
8087
8088 // The MotionRanges should be oriented in the rotated display's coordinate space
8089 const bool displayRotated =
8090 displayRotation == ui::ROTATION_90 || displayRotation == ui::ROTATION_270;
8091
8092 constexpr float MAX_X = 479.5;
8093 constexpr float MAX_Y = 799.75;
8094 EXPECT_EQ(xRange->min, 0.f);
8095 EXPECT_EQ(yRange->min, 0.f);
8096 EXPECT_EQ(xRange->max, displayRotated ? MAX_Y : MAX_X);
8097 EXPECT_EQ(yRange->max, displayRotated ? MAX_X : MAX_Y);
8098
8099 EXPECT_EQ(xRange->flat, 8.f);
8100 EXPECT_EQ(yRange->flat, 8.f);
8101
8102 EXPECT_EQ(xRange->fuzz, 2.f);
8103 EXPECT_EQ(yRange->fuzz, 2.f);
8104
8105 EXPECT_EQ(xRange->resolution, 25.f); // pixels per millimeter
8106 EXPECT_EQ(yRange->resolution, 25.f); // pixels per millimeter
8107}
8108
Prabir Pradhana9df3162022-12-05 23:57:27 +00008109// Run the precision tests for all rotations.
8110INSTANTIATE_TEST_SUITE_P(TouchscreenPrecisionTests, TouchscreenPrecisionTestsFixture,
8111 ::testing::Values(ui::ROTATION_0, ui::ROTATION_90, ui::ROTATION_180,
8112 ui::ROTATION_270),
8113 [](const testing::TestParamInfo<ui::Rotation>& testParamInfo) {
8114 return ftl::enum_string(testParamInfo.param);
8115 });
8116
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008117// --- ExternalStylusFusionTest ---
8118
8119class ExternalStylusFusionTest : public SingleTouchInputMapperTest {
8120public:
8121 SingleTouchInputMapper& initializeInputMapperWithExternalStylus() {
8122 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008123 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008124 prepareButtons();
8125 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00008126 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008127
8128 mStylusState.when = ARBITRARY_TIME;
8129 mStylusState.pressure = 0.f;
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008130 mStylusState.toolType = ToolType::STYLUS;
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008131 mReader->getContext()->setExternalStylusDevices({mExternalStylusDeviceInfo});
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00008132 configureDevice(InputReaderConfiguration::Change::EXTERNAL_STYLUS_PRESENCE);
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008133 processExternalStylusState(mapper);
8134 return mapper;
8135 }
8136
8137 std::list<NotifyArgs> processExternalStylusState(InputMapper& mapper) {
8138 std::list<NotifyArgs> generatedArgs = mapper.updateExternalStylusState(mStylusState);
8139 for (const NotifyArgs& args : generatedArgs) {
8140 mFakeListener->notify(args);
8141 }
8142 // Loop the reader to flush the input listener queue.
8143 mReader->loopOnce();
8144 return generatedArgs;
8145 }
8146
8147protected:
8148 StylusState mStylusState{};
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008149
8150 void testStartFusedStylusGesture(SingleTouchInputMapper& mapper) {
8151 auto toolTypeSource =
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00008152 AllOf(WithSource(STYLUS_FUSION_SOURCE), WithToolType(ToolType::STYLUS));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008153
8154 // The first pointer is withheld.
8155 processDown(mapper, 100, 200);
8156 processSync(mapper);
8157 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8158 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
8159 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
8160
8161 // The external stylus reports pressure. The withheld finger pointer is released as a
8162 // stylus.
8163 mStylusState.pressure = 1.f;
8164 processExternalStylusState(mapper);
8165 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8166 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
8167 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8168
8169 // Subsequent pointer events are not withheld.
8170 processMove(mapper, 101, 201);
8171 processSync(mapper);
8172 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8173 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
8174
8175 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8176 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8177 }
8178
8179 void testSuccessfulFusionGesture(SingleTouchInputMapper& mapper) {
8180 ASSERT_NO_FATAL_FAILURE(testStartFusedStylusGesture(mapper));
8181
8182 // Releasing the touch pointer ends the gesture.
8183 processUp(mapper);
8184 processSync(mapper);
8185 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00008186 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(STYLUS_FUSION_SOURCE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008187 WithToolType(ToolType::STYLUS))));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008188
8189 mStylusState.pressure = 0.f;
8190 processExternalStylusState(mapper);
8191 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8192 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8193 }
8194
8195 void testUnsuccessfulFusionGesture(SingleTouchInputMapper& mapper) {
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00008196 // When stylus fusion is not successful, events should be reported with the original source.
8197 // In this case, it is from a touchscreen.
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008198 auto toolTypeSource =
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00008199 AllOf(WithSource(AINPUT_SOURCE_TOUCHSCREEN), WithToolType(ToolType::FINGER));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008200
8201 // The first pointer is withheld when an external stylus is connected,
8202 // and a timeout is requested.
8203 processDown(mapper, 100, 200);
8204 processSync(mapper);
8205 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8206 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
8207 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
8208
8209 // If the timeout expires early, it is requested again.
8210 handleTimeout(mapper, ARBITRARY_TIME + 1);
8211 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
8212 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
8213
8214 // When the timeout expires, the withheld touch is released as a finger pointer.
8215 handleTimeout(mapper, ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT);
8216 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8217 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
8218
8219 // Subsequent pointer events are not withheld.
8220 processMove(mapper, 101, 201);
8221 processSync(mapper);
8222 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8223 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
8224 processUp(mapper);
8225 processSync(mapper);
8226 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8227 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP))));
8228
8229 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8230 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8231 }
8232
8233private:
8234 InputDeviceInfo mExternalStylusDeviceInfo{};
8235};
8236
8237TEST_F(ExternalStylusFusionTest, UsesBluetoothStylusSource) {
8238 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00008239 ASSERT_EQ(STYLUS_FUSION_SOURCE, mapper.getSources());
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008240}
8241
8242TEST_F(ExternalStylusFusionTest, UnsuccessfulFusion) {
8243 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
8244 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
8245}
8246
8247TEST_F(ExternalStylusFusionTest, SuccessfulFusion_TouchFirst) {
8248 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
8249 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
8250}
8251
8252// Test a successful stylus fusion gesture where the pressure is reported by the external
8253// before the touch is reported by the touchscreen.
8254TEST_F(ExternalStylusFusionTest, SuccessfulFusion_PressureFirst) {
8255 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00008256 auto toolTypeSource = AllOf(WithSource(STYLUS_FUSION_SOURCE), WithToolType(ToolType::STYLUS));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008257
8258 // The external stylus reports pressure first. It is ignored for now.
8259 mStylusState.pressure = 1.f;
8260 processExternalStylusState(mapper);
8261 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8262 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8263
8264 // When the touch goes down afterwards, it is reported as a stylus pointer.
8265 processDown(mapper, 100, 200);
8266 processSync(mapper);
8267 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8268 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
8269 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8270
8271 processMove(mapper, 101, 201);
8272 processSync(mapper);
8273 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8274 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
8275 processUp(mapper);
8276 processSync(mapper);
8277 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8278 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP))));
8279
8280 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8281 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8282}
8283
8284TEST_F(ExternalStylusFusionTest, FusionIsRepeatedForEachNewGesture) {
8285 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
8286
8287 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
8288 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
8289
8290 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
8291 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
8292 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
8293 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
8294}
8295
8296TEST_F(ExternalStylusFusionTest, FusedPointerReportsPressureChanges) {
8297 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00008298 auto toolTypeSource = AllOf(WithSource(STYLUS_FUSION_SOURCE), WithToolType(ToolType::STYLUS));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008299
8300 mStylusState.pressure = 0.8f;
8301 processExternalStylusState(mapper);
8302 processDown(mapper, 100, 200);
8303 processSync(mapper);
8304 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8305 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
8306 WithPressure(0.8f))));
8307 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8308
8309 // The external stylus reports a pressure change. We wait for some time for a touch event.
8310 mStylusState.pressure = 0.6f;
8311 processExternalStylusState(mapper);
8312 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8313 ASSERT_NO_FATAL_FAILURE(
8314 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
8315
8316 // If a touch is reported within the timeout, it reports the updated pressure.
8317 processMove(mapper, 101, 201);
8318 processSync(mapper);
8319 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8320 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
8321 WithPressure(0.6f))));
8322 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8323
8324 // There is another pressure change.
8325 mStylusState.pressure = 0.5f;
8326 processExternalStylusState(mapper);
8327 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8328 ASSERT_NO_FATAL_FAILURE(
8329 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
8330
8331 // If a touch is not reported within the timeout, a move event is generated to report
8332 // the new pressure.
8333 handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
8334 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8335 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
8336 WithPressure(0.5f))));
8337
8338 // If a zero pressure is reported before the touch goes up, the previous pressure value is
8339 // repeated indefinitely.
8340 mStylusState.pressure = 0.0f;
8341 processExternalStylusState(mapper);
8342 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8343 ASSERT_NO_FATAL_FAILURE(
8344 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
8345 processMove(mapper, 102, 202);
8346 processSync(mapper);
8347 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8348 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
8349 WithPressure(0.5f))));
8350 processMove(mapper, 103, 203);
8351 processSync(mapper);
8352 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8353 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
8354 WithPressure(0.5f))));
8355
8356 processUp(mapper);
8357 processSync(mapper);
8358 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00008359 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(STYLUS_FUSION_SOURCE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008360 WithToolType(ToolType::STYLUS))));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008361
8362 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8363 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8364}
8365
8366TEST_F(ExternalStylusFusionTest, FusedPointerReportsToolTypeChanges) {
8367 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00008368 auto source = WithSource(STYLUS_FUSION_SOURCE);
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008369
8370 mStylusState.pressure = 1.f;
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008371 mStylusState.toolType = ToolType::ERASER;
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008372 processExternalStylusState(mapper);
8373 processDown(mapper, 100, 200);
8374 processSync(mapper);
8375 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8376 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008377 WithToolType(ToolType::ERASER))));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008378 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8379
8380 // The external stylus reports a tool change. We wait for some time for a touch event.
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008381 mStylusState.toolType = ToolType::STYLUS;
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008382 processExternalStylusState(mapper);
8383 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8384 ASSERT_NO_FATAL_FAILURE(
8385 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
8386
8387 // If a touch is reported within the timeout, it reports the updated pressure.
8388 processMove(mapper, 101, 201);
8389 processSync(mapper);
8390 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8391 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008392 WithToolType(ToolType::STYLUS))));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008393 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8394
8395 // There is another tool type change.
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008396 mStylusState.toolType = ToolType::FINGER;
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008397 processExternalStylusState(mapper);
8398 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8399 ASSERT_NO_FATAL_FAILURE(
8400 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
8401
8402 // If a touch is not reported within the timeout, a move event is generated to report
8403 // the new tool type.
8404 handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
8405 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8406 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008407 WithToolType(ToolType::FINGER))));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008408
8409 processUp(mapper);
8410 processSync(mapper);
8411 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8412 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_UP),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008413 WithToolType(ToolType::FINGER))));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008414
8415 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8416 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8417}
8418
8419TEST_F(ExternalStylusFusionTest, FusedPointerReportsButtons) {
8420 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
Prabir Pradhanb08a0e82023-09-14 22:28:32 +00008421 auto toolTypeSource = AllOf(WithSource(STYLUS_FUSION_SOURCE), WithToolType(ToolType::STYLUS));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008422
8423 ASSERT_NO_FATAL_FAILURE(testStartFusedStylusGesture(mapper));
8424
8425 // The external stylus reports a button change. We wait for some time for a touch event.
8426 mStylusState.buttons = AMOTION_EVENT_BUTTON_STYLUS_PRIMARY;
8427 processExternalStylusState(mapper);
8428 ASSERT_NO_FATAL_FAILURE(
8429 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
8430
8431 // If a touch is reported within the timeout, it reports the updated button state.
8432 processMove(mapper, 101, 201);
8433 processSync(mapper);
8434 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8435 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
8436 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
8437 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8438 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
8439 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
8440 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8441
8442 // The button is now released.
8443 mStylusState.buttons = 0;
8444 processExternalStylusState(mapper);
8445 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8446 ASSERT_NO_FATAL_FAILURE(
8447 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
8448
8449 // If a touch is not reported within the timeout, a move event is generated to report
8450 // the new button state.
8451 handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008452 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8453 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
8454 WithButtonState(0))));
8455 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan124ea442022-10-28 20:27:44 +00008456 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
8457 WithButtonState(0))));
8458
8459 processUp(mapper);
8460 processSync(mapper);
8461 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00008462 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
8463
8464 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
8465 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8466}
8467
Michael Wrightd02c5b62014-02-10 15:10:22 -08008468// --- MultiTouchInputMapperTest ---
8469
8470class MultiTouchInputMapperTest : public TouchInputMapperTest {
8471protected:
8472 void prepareAxes(int axes);
8473
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008474 void processPosition(MultiTouchInputMapper& mapper, int32_t x, int32_t y);
8475 void processTouchMajor(MultiTouchInputMapper& mapper, int32_t touchMajor);
8476 void processTouchMinor(MultiTouchInputMapper& mapper, int32_t touchMinor);
8477 void processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor);
8478 void processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor);
8479 void processOrientation(MultiTouchInputMapper& mapper, int32_t orientation);
8480 void processPressure(MultiTouchInputMapper& mapper, int32_t pressure);
8481 void processDistance(MultiTouchInputMapper& mapper, int32_t distance);
8482 void processId(MultiTouchInputMapper& mapper, int32_t id);
8483 void processSlot(MultiTouchInputMapper& mapper, int32_t slot);
8484 void processToolType(MultiTouchInputMapper& mapper, int32_t toolType);
8485 void processKey(MultiTouchInputMapper& mapper, int32_t code, int32_t value);
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00008486 void processHidUsage(MultiTouchInputMapper& mapper, int32_t usageCode, int32_t value);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008487 void processMTSync(MultiTouchInputMapper& mapper);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00008488 void processSync(MultiTouchInputMapper& mapper, nsecs_t eventTime = ARBITRARY_TIME,
8489 nsecs_t readTime = READ_TIME);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008490};
8491
8492void MultiTouchInputMapperTest::prepareAxes(int axes) {
8493 if (axes & POSITION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008494 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
8495 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008496 }
8497 if (axes & TOUCH) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008498 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN,
8499 RAW_TOUCH_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008500 if (axes & MINOR) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008501 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN,
8502 RAW_TOUCH_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008503 }
8504 }
8505 if (axes & TOOL) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008506 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
8507 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008508 if (axes & MINOR) {
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08008509 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008510 RAW_TOOL_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008511 }
8512 }
8513 if (axes & ORIENTATION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008514 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_ORIENTATION, RAW_ORIENTATION_MIN,
8515 RAW_ORIENTATION_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008516 }
8517 if (axes & PRESSURE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008518 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_PRESSURE, RAW_PRESSURE_MIN,
8519 RAW_PRESSURE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008520 }
8521 if (axes & DISTANCE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008522 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_DISTANCE, RAW_DISTANCE_MIN,
8523 RAW_DISTANCE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008524 }
8525 if (axes & ID) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008526 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX, 0,
8527 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008528 }
8529 if (axes & SLOT) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008530 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX, 0, 0);
8531 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008532 }
8533 if (axes & TOOL_TYPE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008534 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOOL_TYPE, 0, MT_TOOL_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008535 }
8536}
8537
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008538void MultiTouchInputMapperTest::processPosition(MultiTouchInputMapper& mapper, int32_t x,
8539 int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008540 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_X, x);
8541 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008542}
8543
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008544void MultiTouchInputMapperTest::processTouchMajor(MultiTouchInputMapper& mapper,
8545 int32_t touchMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008546 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, touchMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008547}
8548
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008549void MultiTouchInputMapperTest::processTouchMinor(MultiTouchInputMapper& mapper,
8550 int32_t touchMinor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008551 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, touchMinor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008552}
8553
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008554void MultiTouchInputMapperTest::processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008555 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_WIDTH_MAJOR, toolMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008556}
8557
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008558void MultiTouchInputMapperTest::processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008559 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_WIDTH_MINOR, toolMinor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008560}
8561
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008562void MultiTouchInputMapperTest::processOrientation(MultiTouchInputMapper& mapper,
8563 int32_t orientation) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008564 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_ORIENTATION, orientation);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008565}
8566
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008567void MultiTouchInputMapperTest::processPressure(MultiTouchInputMapper& mapper, int32_t pressure) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008568 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_PRESSURE, pressure);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008569}
8570
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008571void MultiTouchInputMapperTest::processDistance(MultiTouchInputMapper& mapper, int32_t distance) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008572 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_DISTANCE, distance);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008573}
8574
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008575void MultiTouchInputMapperTest::processId(MultiTouchInputMapper& mapper, int32_t id) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008576 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TRACKING_ID, id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008577}
8578
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008579void MultiTouchInputMapperTest::processSlot(MultiTouchInputMapper& mapper, int32_t slot) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008580 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_SLOT, slot);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008581}
8582
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008583void MultiTouchInputMapperTest::processToolType(MultiTouchInputMapper& mapper, int32_t toolType) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008584 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOOL_TYPE, toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008585}
8586
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008587void MultiTouchInputMapperTest::processKey(MultiTouchInputMapper& mapper, int32_t code,
8588 int32_t value) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008589 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008590}
8591
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00008592void MultiTouchInputMapperTest::processHidUsage(MultiTouchInputMapper& mapper, int32_t usageCode,
8593 int32_t value) {
8594 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, usageCode);
8595 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UNKNOWN, value);
8596}
8597
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008598void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008599 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_MT_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008600}
8601
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00008602void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper& mapper, nsecs_t eventTime,
8603 nsecs_t readTime) {
8604 process(mapper, eventTime, readTime, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008605}
8606
Michael Wrightd02c5b62014-02-10 15:10:22 -08008607TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008608 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008609 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008610 prepareAxes(POSITION);
8611 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00008612 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008613
arthurhungdcef2dc2020-08-11 14:47:50 +08008614 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008615
8616 NotifyMotionArgs motionArgs;
8617
8618 // Two fingers down at once.
8619 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
8620 processPosition(mapper, x1, y1);
8621 processMTSync(mapper);
8622 processPosition(mapper, x2, y2);
8623 processMTSync(mapper);
8624 processSync(mapper);
8625
8626 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8627 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8628 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8629 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8630 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
8631 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8632 ASSERT_EQ(0, motionArgs.flags);
8633 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8634 ASSERT_EQ(0, motionArgs.buttonState);
8635 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008636 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008637 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008638 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008639 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8640 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8641 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8642 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8643 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8644
8645 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8646 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8647 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8648 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8649 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008650 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008651 ASSERT_EQ(0, motionArgs.flags);
8652 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8653 ASSERT_EQ(0, motionArgs.buttonState);
8654 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008655 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008656 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008657 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008658 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008659 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008660 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8661 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8662 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8663 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8664 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8665 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8666 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8667
8668 // Move.
8669 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
8670 processPosition(mapper, x1, y1);
8671 processMTSync(mapper);
8672 processPosition(mapper, x2, y2);
8673 processMTSync(mapper);
8674 processSync(mapper);
8675
8676 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8677 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8678 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8679 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8680 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
8681 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8682 ASSERT_EQ(0, motionArgs.flags);
8683 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8684 ASSERT_EQ(0, motionArgs.buttonState);
8685 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008686 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008687 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008688 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008689 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008690 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008691 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8692 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8693 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8694 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8695 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8696 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8697 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8698
8699 // First finger up.
8700 x2 += 15; y2 -= 20;
8701 processPosition(mapper, x2, y2);
8702 processMTSync(mapper);
8703 processSync(mapper);
8704
8705 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8706 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8707 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8708 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8709 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008710 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008711 ASSERT_EQ(0, motionArgs.flags);
8712 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8713 ASSERT_EQ(0, motionArgs.buttonState);
8714 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008715 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008716 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008717 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008718 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008719 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008720 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8721 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8722 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8723 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8724 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8725 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8726 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8727
8728 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8729 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8730 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8731 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8732 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
8733 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8734 ASSERT_EQ(0, motionArgs.flags);
8735 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8736 ASSERT_EQ(0, motionArgs.buttonState);
8737 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008738 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008739 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008740 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008741 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8742 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8743 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8744 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8745 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8746
8747 // Move.
8748 x2 += 20; y2 -= 25;
8749 processPosition(mapper, x2, y2);
8750 processMTSync(mapper);
8751 processSync(mapper);
8752
8753 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8754 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8755 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8756 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8757 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
8758 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8759 ASSERT_EQ(0, motionArgs.flags);
8760 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8761 ASSERT_EQ(0, motionArgs.buttonState);
8762 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008763 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008764 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008765 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008766 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8767 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8768 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8769 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8770 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8771
8772 // New finger down.
8773 int32_t x3 = 700, y3 = 300;
8774 processPosition(mapper, x2, y2);
8775 processMTSync(mapper);
8776 processPosition(mapper, x3, y3);
8777 processMTSync(mapper);
8778 processSync(mapper);
8779
8780 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8781 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8782 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8783 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8784 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008785 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008786 ASSERT_EQ(0, motionArgs.flags);
8787 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8788 ASSERT_EQ(0, motionArgs.buttonState);
8789 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008790 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008791 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008792 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008793 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008794 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008795 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8796 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8797 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8798 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8799 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8800 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8801 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8802
8803 // Second finger up.
8804 x3 += 30; y3 -= 20;
8805 processPosition(mapper, x3, y3);
8806 processMTSync(mapper);
8807 processSync(mapper);
8808
8809 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8810 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8811 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8812 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8813 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008814 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008815 ASSERT_EQ(0, motionArgs.flags);
8816 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8817 ASSERT_EQ(0, motionArgs.buttonState);
8818 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008819 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008820 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008821 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008822 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008823 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008824 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8825 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8826 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8827 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8828 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8829 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8830 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8831
8832 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8833 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8834 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8835 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8836 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
8837 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8838 ASSERT_EQ(0, motionArgs.flags);
8839 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8840 ASSERT_EQ(0, motionArgs.buttonState);
8841 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008842 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008843 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008844 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008845 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8846 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8847 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8848 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8849 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8850
8851 // Last finger up.
8852 processMTSync(mapper);
8853 processSync(mapper);
8854
8855 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8856 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8857 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8858 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8859 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
8860 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8861 ASSERT_EQ(0, motionArgs.flags);
8862 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8863 ASSERT_EQ(0, motionArgs.buttonState);
8864 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008865 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008866 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008867 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008868 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8869 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8870 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8871 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8872 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8873
8874 // Should not have sent any more keys or motions.
8875 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
8876 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8877}
8878
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08008879TEST_F(MultiTouchInputMapperTest, AxisResolution_IsPopulated) {
8880 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008881 prepareDisplay(ui::ROTATION_0);
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08008882
8883 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
8884 /*fuzz*/ 0, /*resolution*/ 10);
8885 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
8886 /*fuzz*/ 0, /*resolution*/ 11);
8887 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
8888 /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 12);
8889 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
8890 /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 13);
8891 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
8892 /*flat*/ 0, /*flat*/ 0, /*resolution*/ 14);
8893 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
8894 /*flat*/ 0, /*flat*/ 0, /*resolution*/ 15);
8895
Arpit Singha8c236b2023-04-25 13:56:05 +00008896 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08008897
8898 // X and Y axes
8899 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_X, 10 / X_PRECISION);
8900 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_Y, 11 / Y_PRECISION);
8901 // Touch major and minor
8902 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR, 12 * GEOMETRIC_SCALE);
8903 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR, 13 * GEOMETRIC_SCALE);
8904 // Tool major and minor
8905 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR, 14 * GEOMETRIC_SCALE);
8906 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR, 15 * GEOMETRIC_SCALE);
8907}
8908
8909TEST_F(MultiTouchInputMapperTest, TouchMajorAndMinorAxes_DoNotAppearIfNotSupported) {
8910 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008911 prepareDisplay(ui::ROTATION_0);
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08008912
8913 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
8914 /*fuzz*/ 0, /*resolution*/ 10);
8915 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
8916 /*fuzz*/ 0, /*resolution*/ 11);
8917
8918 // We do not add ABS_MT_TOUCH_MAJOR / MINOR or ABS_MT_WIDTH_MAJOR / MINOR axes
8919
Arpit Singha8c236b2023-04-25 13:56:05 +00008920 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08008921
8922 // Touch major and minor
8923 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR);
8924 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR);
8925 // Tool major and minor
8926 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR);
8927 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR);
8928}
8929
Michael Wrightd02c5b62014-02-10 15:10:22 -08008930TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008931 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008932 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008933 prepareAxes(POSITION | ID);
8934 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00008935 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008936
arthurhungdcef2dc2020-08-11 14:47:50 +08008937 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008938
8939 NotifyMotionArgs motionArgs;
8940
8941 // Two fingers down at once.
8942 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
8943 processPosition(mapper, x1, y1);
8944 processId(mapper, 1);
8945 processMTSync(mapper);
8946 processPosition(mapper, x2, y2);
8947 processId(mapper, 2);
8948 processMTSync(mapper);
8949 processSync(mapper);
8950
8951 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8952 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008953 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008954 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008955 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008956 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8957 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8958
8959 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008960 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008961 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008962 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008963 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008964 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008965 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008966 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8967 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8968 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8969 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8970
8971 // Move.
8972 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
8973 processPosition(mapper, x1, y1);
8974 processId(mapper, 1);
8975 processMTSync(mapper);
8976 processPosition(mapper, x2, y2);
8977 processId(mapper, 2);
8978 processMTSync(mapper);
8979 processSync(mapper);
8980
8981 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8982 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008983 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008984 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008985 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008986 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008987 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008988 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8989 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8990 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8991 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8992
8993 // First finger up.
8994 x2 += 15; y2 -= 20;
8995 processPosition(mapper, x2, y2);
8996 processId(mapper, 2);
8997 processMTSync(mapper);
8998 processSync(mapper);
8999
9000 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009001 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009002 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009003 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009004 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009005 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009006 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009007 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9008 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
9009 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
9010 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
9011
9012 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9013 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009014 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009015 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009016 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009017 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9018 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
9019
9020 // Move.
9021 x2 += 20; y2 -= 25;
9022 processPosition(mapper, x2, y2);
9023 processId(mapper, 2);
9024 processMTSync(mapper);
9025 processSync(mapper);
9026
9027 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9028 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009029 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009030 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009031 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009032 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9033 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
9034
9035 // New finger down.
9036 int32_t x3 = 700, y3 = 300;
9037 processPosition(mapper, x2, y2);
9038 processId(mapper, 2);
9039 processMTSync(mapper);
9040 processPosition(mapper, x3, y3);
9041 processId(mapper, 3);
9042 processMTSync(mapper);
9043 processSync(mapper);
9044
9045 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009046 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009047 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009048 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009049 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009050 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009051 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009052 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9053 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
9054 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
9055 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
9056
9057 // Second finger up.
9058 x3 += 30; y3 -= 20;
9059 processPosition(mapper, x3, y3);
9060 processId(mapper, 3);
9061 processMTSync(mapper);
9062 processSync(mapper);
9063
9064 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009065 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009066 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009067 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009068 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009069 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009070 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009071 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9072 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
9073 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
9074 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
9075
9076 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9077 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009078 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009079 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009080 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009081 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9082 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
9083
9084 // Last finger up.
9085 processMTSync(mapper);
9086 processSync(mapper);
9087
9088 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9089 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009090 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009091 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009092 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009093 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9094 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
9095
9096 // Should not have sent any more keys or motions.
9097 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
9098 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9099}
9100
9101TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithSlots) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08009102 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009103 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009104 prepareAxes(POSITION | ID | SLOT);
9105 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00009106 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08009107
arthurhungdcef2dc2020-08-11 14:47:50 +08009108 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009109
9110 NotifyMotionArgs motionArgs;
9111
9112 // Two fingers down at once.
9113 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
9114 processPosition(mapper, x1, y1);
9115 processId(mapper, 1);
9116 processSlot(mapper, 1);
9117 processPosition(mapper, x2, y2);
9118 processId(mapper, 2);
9119 processSync(mapper);
9120
9121 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9122 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009123 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009124 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009125 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009126 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9127 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
9128
9129 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009130 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009131 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009132 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009133 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009134 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009135 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009136 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9137 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
9138 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
9139 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
9140
9141 // Move.
9142 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
9143 processSlot(mapper, 0);
9144 processPosition(mapper, x1, y1);
9145 processSlot(mapper, 1);
9146 processPosition(mapper, x2, y2);
9147 processSync(mapper);
9148
9149 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9150 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009151 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009152 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009153 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009154 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009155 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009156 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9157 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
9158 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
9159 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
9160
9161 // First finger up.
9162 x2 += 15; y2 -= 20;
9163 processSlot(mapper, 0);
9164 processId(mapper, -1);
9165 processSlot(mapper, 1);
9166 processPosition(mapper, x2, y2);
9167 processSync(mapper);
9168
9169 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009170 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009171 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009172 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009173 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009174 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009175 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009176 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9177 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
9178 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
9179 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
9180
9181 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9182 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009183 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009184 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009185 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009186 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9187 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
9188
9189 // Move.
9190 x2 += 20; y2 -= 25;
9191 processPosition(mapper, x2, y2);
9192 processSync(mapper);
9193
9194 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9195 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009196 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009197 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009198 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009199 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9200 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
9201
9202 // New finger down.
9203 int32_t x3 = 700, y3 = 300;
9204 processPosition(mapper, x2, y2);
9205 processSlot(mapper, 0);
9206 processId(mapper, 3);
9207 processPosition(mapper, x3, y3);
9208 processSync(mapper);
9209
9210 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009211 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009212 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009213 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009214 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009215 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009216 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009217 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9218 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
9219 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
9220 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
9221
9222 // Second finger up.
9223 x3 += 30; y3 -= 20;
9224 processSlot(mapper, 1);
9225 processId(mapper, -1);
9226 processSlot(mapper, 0);
9227 processPosition(mapper, x3, y3);
9228 processSync(mapper);
9229
9230 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009231 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009232 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009233 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009234 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009235 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009236 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009237 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9238 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
9239 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
9240 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
9241
9242 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9243 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009244 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009245 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009246 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009247 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9248 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
9249
9250 // Last finger up.
9251 processId(mapper, -1);
9252 processSync(mapper);
9253
9254 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9255 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009256 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009257 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009258 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009259 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9260 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
9261
9262 // Should not have sent any more keys or motions.
9263 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
9264 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9265}
9266
9267TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08009268 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009269 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009270 prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR | DISTANCE);
Arpit Singha8c236b2023-04-25 13:56:05 +00009271 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08009272
9273 // These calculations are based on the input device calibration documentation.
9274 int32_t rawX = 100;
9275 int32_t rawY = 200;
9276 int32_t rawTouchMajor = 7;
9277 int32_t rawTouchMinor = 6;
9278 int32_t rawToolMajor = 9;
9279 int32_t rawToolMinor = 8;
9280 int32_t rawPressure = 11;
9281 int32_t rawDistance = 0;
9282 int32_t rawOrientation = 3;
9283 int32_t id = 5;
9284
9285 float x = toDisplayX(rawX);
9286 float y = toDisplayY(rawY);
9287 float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
9288 float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
9289 float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
9290 float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
9291 float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
9292 float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
9293 float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2;
9294 float distance = float(rawDistance);
9295
9296 processPosition(mapper, rawX, rawY);
9297 processTouchMajor(mapper, rawTouchMajor);
9298 processTouchMinor(mapper, rawTouchMinor);
9299 processToolMajor(mapper, rawToolMajor);
9300 processToolMinor(mapper, rawToolMinor);
9301 processPressure(mapper, rawPressure);
9302 processOrientation(mapper, rawOrientation);
9303 processDistance(mapper, rawDistance);
9304 processId(mapper, id);
9305 processMTSync(mapper);
9306 processSync(mapper);
9307
9308 NotifyMotionArgs args;
9309 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9310 ASSERT_EQ(0, args.pointerProperties[0].id);
9311 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
9312 x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor,
9313 orientation, distance));
9314}
9315
9316TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08009317 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009318 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009319 prepareAxes(POSITION | TOUCH | TOOL | MINOR);
9320 addConfigurationProperty("touch.size.calibration", "geometric");
Arpit Singha8c236b2023-04-25 13:56:05 +00009321 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08009322
9323 // These calculations are based on the input device calibration documentation.
9324 int32_t rawX = 100;
9325 int32_t rawY = 200;
9326 int32_t rawTouchMajor = 140;
9327 int32_t rawTouchMinor = 120;
9328 int32_t rawToolMajor = 180;
9329 int32_t rawToolMinor = 160;
9330
9331 float x = toDisplayX(rawX);
9332 float y = toDisplayY(rawY);
9333 float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
9334 float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
9335 float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
9336 float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
9337 float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
9338
9339 processPosition(mapper, rawX, rawY);
9340 processTouchMajor(mapper, rawTouchMajor);
9341 processTouchMinor(mapper, rawTouchMinor);
9342 processToolMajor(mapper, rawToolMajor);
9343 processToolMinor(mapper, rawToolMinor);
9344 processMTSync(mapper);
9345 processSync(mapper);
9346
9347 NotifyMotionArgs args;
9348 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9349 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
9350 x, y, 1.0f, size, touchMajor, touchMinor, toolMajor, toolMinor, 0, 0));
9351}
9352
9353TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_SummedLinearCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08009354 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009355 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009356 prepareAxes(POSITION | TOUCH | TOOL);
9357 addConfigurationProperty("touch.size.calibration", "diameter");
9358 addConfigurationProperty("touch.size.scale", "10");
9359 addConfigurationProperty("touch.size.bias", "160");
9360 addConfigurationProperty("touch.size.isSummed", "1");
Arpit Singha8c236b2023-04-25 13:56:05 +00009361 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08009362
9363 // These calculations are based on the input device calibration documentation.
9364 // Note: We only provide a single common touch/tool value because the device is assumed
9365 // not to emit separate values for each pointer (isSummed = 1).
9366 int32_t rawX = 100;
9367 int32_t rawY = 200;
9368 int32_t rawX2 = 150;
9369 int32_t rawY2 = 250;
9370 int32_t rawTouchMajor = 5;
9371 int32_t rawToolMajor = 8;
9372
9373 float x = toDisplayX(rawX);
9374 float y = toDisplayY(rawY);
9375 float x2 = toDisplayX(rawX2);
9376 float y2 = toDisplayY(rawY2);
9377 float size = float(rawTouchMajor) / 2 / RAW_TOUCH_MAX;
9378 float touch = float(rawTouchMajor) / 2 * 10.0f + 160.0f;
9379 float tool = float(rawToolMajor) / 2 * 10.0f + 160.0f;
9380
9381 processPosition(mapper, rawX, rawY);
9382 processTouchMajor(mapper, rawTouchMajor);
9383 processToolMajor(mapper, rawToolMajor);
9384 processMTSync(mapper);
9385 processPosition(mapper, rawX2, rawY2);
9386 processTouchMajor(mapper, rawTouchMajor);
9387 processToolMajor(mapper, rawToolMajor);
9388 processMTSync(mapper);
9389 processSync(mapper);
9390
9391 NotifyMotionArgs args;
9392 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9393 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
9394
9395 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009396 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07009397 ASSERT_EQ(size_t(2), args.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08009398 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
9399 x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
9400 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1],
9401 x2, y2, 1.0f, size, touch, touch, tool, tool, 0, 0));
9402}
9403
9404TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_AreaCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08009405 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009406 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009407 prepareAxes(POSITION | TOUCH | TOOL);
9408 addConfigurationProperty("touch.size.calibration", "area");
9409 addConfigurationProperty("touch.size.scale", "43");
9410 addConfigurationProperty("touch.size.bias", "3");
Arpit Singha8c236b2023-04-25 13:56:05 +00009411 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08009412
9413 // These calculations are based on the input device calibration documentation.
9414 int32_t rawX = 100;
9415 int32_t rawY = 200;
9416 int32_t rawTouchMajor = 5;
9417 int32_t rawToolMajor = 8;
9418
9419 float x = toDisplayX(rawX);
9420 float y = toDisplayY(rawY);
9421 float size = float(rawTouchMajor) / RAW_TOUCH_MAX;
9422 float touch = sqrtf(rawTouchMajor) * 43.0f + 3.0f;
9423 float tool = sqrtf(rawToolMajor) * 43.0f + 3.0f;
9424
9425 processPosition(mapper, rawX, rawY);
9426 processTouchMajor(mapper, rawTouchMajor);
9427 processToolMajor(mapper, rawToolMajor);
9428 processMTSync(mapper);
9429 processSync(mapper);
9430
9431 NotifyMotionArgs args;
9432 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9433 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
9434 x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
9435}
9436
9437TEST_F(MultiTouchInputMapperTest, Process_PressureAxis_AmplitudeCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08009438 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009439 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009440 prepareAxes(POSITION | PRESSURE);
9441 addConfigurationProperty("touch.pressure.calibration", "amplitude");
9442 addConfigurationProperty("touch.pressure.scale", "0.01");
Arpit Singha8c236b2023-04-25 13:56:05 +00009443 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08009444
Michael Wrightaa449c92017-12-13 21:21:43 +00009445 InputDeviceInfo info;
Harry Cuttsd02ea102023-03-17 18:21:30 +00009446 mapper.populateDeviceInfo(info);
Michael Wrightaa449c92017-12-13 21:21:43 +00009447 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
9448 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TOUCHSCREEN,
9449 0.0f, RAW_PRESSURE_MAX * 0.01, 0.0f, 0.0f));
9450
Michael Wrightd02c5b62014-02-10 15:10:22 -08009451 // These calculations are based on the input device calibration documentation.
9452 int32_t rawX = 100;
9453 int32_t rawY = 200;
9454 int32_t rawPressure = 60;
9455
9456 float x = toDisplayX(rawX);
9457 float y = toDisplayY(rawY);
9458 float pressure = float(rawPressure) * 0.01f;
9459
9460 processPosition(mapper, rawX, rawY);
9461 processPressure(mapper, rawPressure);
9462 processMTSync(mapper);
9463 processSync(mapper);
9464
9465 NotifyMotionArgs args;
9466 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9467 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
9468 x, y, pressure, 0, 0, 0, 0, 0, 0, 0));
9469}
9470
9471TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08009472 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009473 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009474 prepareAxes(POSITION | ID | SLOT);
Arpit Singha8c236b2023-04-25 13:56:05 +00009475 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08009476
9477 NotifyMotionArgs motionArgs;
9478 NotifyKeyArgs keyArgs;
9479
9480 processId(mapper, 1);
9481 processPosition(mapper, 100, 200);
9482 processSync(mapper);
9483 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9484 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9485 ASSERT_EQ(0, motionArgs.buttonState);
9486
9487 // press BTN_LEFT, release BTN_LEFT
9488 processKey(mapper, BTN_LEFT, 1);
9489 processSync(mapper);
9490 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9491 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9492 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
9493
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009494 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9495 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
9496 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
9497
Michael Wrightd02c5b62014-02-10 15:10:22 -08009498 processKey(mapper, BTN_LEFT, 0);
9499 processSync(mapper);
9500 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009501 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009502 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009503
9504 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009505 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009506 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009507
9508 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
9509 processKey(mapper, BTN_RIGHT, 1);
9510 processKey(mapper, BTN_MIDDLE, 1);
9511 processSync(mapper);
9512 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9513 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9514 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
9515 motionArgs.buttonState);
9516
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009517 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9518 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
9519 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
9520
9521 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9522 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
9523 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
9524 motionArgs.buttonState);
9525
Michael Wrightd02c5b62014-02-10 15:10:22 -08009526 processKey(mapper, BTN_RIGHT, 0);
9527 processSync(mapper);
9528 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009529 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009530 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009531
9532 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009533 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009534 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009535
9536 processKey(mapper, BTN_MIDDLE, 0);
9537 processSync(mapper);
9538 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009539 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009540 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009541
9542 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009543 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009544 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009545
9546 // press BTN_BACK, release BTN_BACK
9547 processKey(mapper, BTN_BACK, 1);
9548 processSync(mapper);
9549 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
9550 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
9551 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009552
Michael Wrightd02c5b62014-02-10 15:10:22 -08009553 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009554 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009555 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
9556
9557 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9558 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
9559 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009560
9561 processKey(mapper, BTN_BACK, 0);
9562 processSync(mapper);
9563 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009564 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009565 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009566
9567 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009568 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009569 ASSERT_EQ(0, motionArgs.buttonState);
9570
Michael Wrightd02c5b62014-02-10 15:10:22 -08009571 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
9572 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
9573 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
9574
9575 // press BTN_SIDE, release BTN_SIDE
9576 processKey(mapper, BTN_SIDE, 1);
9577 processSync(mapper);
9578 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
9579 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
9580 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009581
Michael Wrightd02c5b62014-02-10 15:10:22 -08009582 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009583 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009584 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
9585
9586 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9587 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
9588 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009589
9590 processKey(mapper, BTN_SIDE, 0);
9591 processSync(mapper);
9592 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009593 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009594 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009595
9596 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009597 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009598 ASSERT_EQ(0, motionArgs.buttonState);
9599
Michael Wrightd02c5b62014-02-10 15:10:22 -08009600 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
9601 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
9602 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
9603
9604 // press BTN_FORWARD, release BTN_FORWARD
9605 processKey(mapper, BTN_FORWARD, 1);
9606 processSync(mapper);
9607 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
9608 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
9609 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009610
Michael Wrightd02c5b62014-02-10 15:10:22 -08009611 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009612 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009613 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
9614
9615 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9616 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
9617 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009618
9619 processKey(mapper, BTN_FORWARD, 0);
9620 processSync(mapper);
9621 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009622 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009623 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009624
9625 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009626 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009627 ASSERT_EQ(0, motionArgs.buttonState);
9628
Michael Wrightd02c5b62014-02-10 15:10:22 -08009629 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
9630 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
9631 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
9632
9633 // press BTN_EXTRA, release BTN_EXTRA
9634 processKey(mapper, BTN_EXTRA, 1);
9635 processSync(mapper);
9636 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
9637 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
9638 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009639
Michael Wrightd02c5b62014-02-10 15:10:22 -08009640 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009641 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009642 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
9643
9644 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9645 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
9646 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009647
9648 processKey(mapper, BTN_EXTRA, 0);
9649 processSync(mapper);
9650 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009651 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009652 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009653
9654 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009655 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009656 ASSERT_EQ(0, motionArgs.buttonState);
9657
Michael Wrightd02c5b62014-02-10 15:10:22 -08009658 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
9659 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
9660 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
9661
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009662 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
9663
Michael Wrightd02c5b62014-02-10 15:10:22 -08009664 // press BTN_STYLUS, release BTN_STYLUS
9665 processKey(mapper, BTN_STYLUS, 1);
9666 processSync(mapper);
9667 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9668 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009669 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
9670
9671 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9672 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
9673 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009674
9675 processKey(mapper, BTN_STYLUS, 0);
9676 processSync(mapper);
9677 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009678 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009679 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009680
9681 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009682 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009683 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009684
9685 // press BTN_STYLUS2, release BTN_STYLUS2
9686 processKey(mapper, BTN_STYLUS2, 1);
9687 processSync(mapper);
9688 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9689 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009690 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
9691
9692 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9693 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
9694 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009695
9696 processKey(mapper, BTN_STYLUS2, 0);
9697 processSync(mapper);
9698 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009699 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009700 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009701
9702 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009703 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009704 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009705
9706 // release touch
9707 processId(mapper, -1);
9708 processSync(mapper);
9709 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9710 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9711 ASSERT_EQ(0, motionArgs.buttonState);
9712}
9713
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00009714TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleMappedStylusButtons) {
9715 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009716 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00009717 prepareAxes(POSITION | ID | SLOT);
Arpit Singha8c236b2023-04-25 13:56:05 +00009718 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00009719
9720 mFakeEventHub->addKey(EVENTHUB_ID, BTN_A, 0, AKEYCODE_STYLUS_BUTTON_PRIMARY, 0);
9721 mFakeEventHub->addKey(EVENTHUB_ID, 0, 0xabcd, AKEYCODE_STYLUS_BUTTON_SECONDARY, 0);
9722
9723 // Touch down.
9724 processId(mapper, 1);
9725 processPosition(mapper, 100, 200);
9726 processSync(mapper);
9727 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9728 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithButtonState(0))));
9729
9730 // Press and release button mapped to the primary stylus button.
9731 processKey(mapper, BTN_A, 1);
9732 processSync(mapper);
9733 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9734 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
9735 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
9736 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9737 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
9738 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
9739
9740 processKey(mapper, BTN_A, 0);
9741 processSync(mapper);
9742 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9743 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithButtonState(0))));
9744 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9745 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
9746
9747 // Press and release the HID usage mapped to the secondary stylus button.
9748 processHidUsage(mapper, 0xabcd, 1);
9749 processSync(mapper);
9750 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9751 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
9752 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY))));
9753 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9754 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
9755 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY))));
9756
9757 processHidUsage(mapper, 0xabcd, 0);
9758 processSync(mapper);
9759 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9760 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithButtonState(0))));
9761 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9762 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
9763
9764 // Release touch.
9765 processId(mapper, -1);
9766 processSync(mapper);
9767 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9768 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
9769}
9770
Michael Wrightd02c5b62014-02-10 15:10:22 -08009771TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08009772 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009773 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009774 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Arpit Singha8c236b2023-04-25 13:56:05 +00009775 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08009776
9777 NotifyMotionArgs motionArgs;
9778
9779 // default tool type is finger
9780 processId(mapper, 1);
9781 processPosition(mapper, 100, 200);
9782 processSync(mapper);
9783 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9784 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009785 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009786
9787 // eraser
9788 processKey(mapper, BTN_TOOL_RUBBER, 1);
9789 processSync(mapper);
9790 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9791 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009792 ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009793
9794 // stylus
9795 processKey(mapper, BTN_TOOL_RUBBER, 0);
9796 processKey(mapper, BTN_TOOL_PEN, 1);
9797 processSync(mapper);
9798 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9799 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009800 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009801
9802 // brush
9803 processKey(mapper, BTN_TOOL_PEN, 0);
9804 processKey(mapper, BTN_TOOL_BRUSH, 1);
9805 processSync(mapper);
9806 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9807 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009808 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009809
9810 // pencil
9811 processKey(mapper, BTN_TOOL_BRUSH, 0);
9812 processKey(mapper, BTN_TOOL_PENCIL, 1);
9813 processSync(mapper);
9814 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9815 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009816 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009817
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08009818 // air-brush
Michael Wrightd02c5b62014-02-10 15:10:22 -08009819 processKey(mapper, BTN_TOOL_PENCIL, 0);
9820 processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
9821 processSync(mapper);
9822 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9823 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009824 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009825
9826 // mouse
9827 processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
9828 processKey(mapper, BTN_TOOL_MOUSE, 1);
9829 processSync(mapper);
9830 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9831 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009832 ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009833
9834 // lens
9835 processKey(mapper, BTN_TOOL_MOUSE, 0);
9836 processKey(mapper, BTN_TOOL_LENS, 1);
9837 processSync(mapper);
9838 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9839 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009840 ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009841
9842 // double-tap
9843 processKey(mapper, BTN_TOOL_LENS, 0);
9844 processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
9845 processSync(mapper);
9846 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9847 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009848 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009849
9850 // triple-tap
9851 processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
9852 processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
9853 processSync(mapper);
9854 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9855 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009856 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009857
9858 // quad-tap
9859 processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
9860 processKey(mapper, BTN_TOOL_QUADTAP, 1);
9861 processSync(mapper);
9862 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9863 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009864 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009865
9866 // finger
9867 processKey(mapper, BTN_TOOL_QUADTAP, 0);
9868 processKey(mapper, BTN_TOOL_FINGER, 1);
9869 processSync(mapper);
9870 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9871 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009872 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009873
9874 // stylus trumps finger
9875 processKey(mapper, BTN_TOOL_PEN, 1);
9876 processSync(mapper);
9877 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9878 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009879 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009880
9881 // eraser trumps stylus
9882 processKey(mapper, BTN_TOOL_RUBBER, 1);
9883 processSync(mapper);
9884 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9885 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009886 ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009887
9888 // mouse trumps eraser
9889 processKey(mapper, BTN_TOOL_MOUSE, 1);
9890 processSync(mapper);
9891 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9892 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009893 ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009894
9895 // MT tool type trumps BTN tool types: MT_TOOL_FINGER
9896 processToolType(mapper, MT_TOOL_FINGER); // this is the first time we send MT_TOOL_TYPE
9897 processSync(mapper);
9898 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9899 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009900 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009901
9902 // MT tool type trumps BTN tool types: MT_TOOL_PEN
9903 processToolType(mapper, MT_TOOL_PEN);
9904 processSync(mapper);
9905 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9906 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009907 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009908
9909 // back to default tool type
9910 processToolType(mapper, -1); // use a deliberately undefined tool type, for testing
9911 processKey(mapper, BTN_TOOL_MOUSE, 0);
9912 processKey(mapper, BTN_TOOL_RUBBER, 0);
9913 processKey(mapper, BTN_TOOL_PEN, 0);
9914 processKey(mapper, BTN_TOOL_FINGER, 0);
9915 processSync(mapper);
9916 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9917 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009918 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009919}
9920
9921TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08009922 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009923 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009924 prepareAxes(POSITION | ID | SLOT);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009925 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Arpit Singha8c236b2023-04-25 13:56:05 +00009926 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08009927
9928 NotifyMotionArgs motionArgs;
9929
9930 // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
9931 processId(mapper, 1);
9932 processPosition(mapper, 100, 200);
9933 processSync(mapper);
9934 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9935 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
9936 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9937 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
9938
9939 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9940 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
9941 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9942 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
9943
9944 // move a little
9945 processPosition(mapper, 150, 250);
9946 processSync(mapper);
9947 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9948 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
9949 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9950 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9951
9952 // down when BTN_TOUCH is pressed, pressure defaults to 1
9953 processKey(mapper, BTN_TOUCH, 1);
9954 processSync(mapper);
9955 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9956 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
9957 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9958 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9959
9960 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9961 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9962 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9963 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
9964
9965 // up when BTN_TOUCH is released, hover restored
9966 processKey(mapper, BTN_TOUCH, 0);
9967 processSync(mapper);
9968 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9969 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9970 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9971 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
9972
9973 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9974 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
9975 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9976 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9977
9978 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9979 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
9980 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9981 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9982
9983 // exit hover when pointer goes away
9984 processId(mapper, -1);
9985 processSync(mapper);
9986 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9987 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
9988 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9989 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9990}
9991
9992TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTPressureIsPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08009993 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009994 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009995 prepareAxes(POSITION | ID | SLOT | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +00009996 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08009997
9998 NotifyMotionArgs motionArgs;
9999
10000 // initially hovering because pressure is 0
10001 processId(mapper, 1);
10002 processPosition(mapper, 100, 200);
10003 processPressure(mapper, 0);
10004 processSync(mapper);
10005 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10006 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
10007 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
10008 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
10009
10010 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10011 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
10012 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
10013 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
10014
10015 // move a little
10016 processPosition(mapper, 150, 250);
10017 processSync(mapper);
10018 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10019 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
10020 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
10021 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
10022
10023 // down when pressure becomes non-zero
10024 processPressure(mapper, RAW_PRESSURE_MAX);
10025 processSync(mapper);
10026 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10027 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
10028 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
10029 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
10030
10031 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10032 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10033 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
10034 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
10035
10036 // up when pressure becomes 0, hover restored
10037 processPressure(mapper, 0);
10038 processSync(mapper);
10039 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10040 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
10041 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
10042 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
10043
10044 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10045 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
10046 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
10047 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
10048
10049 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10050 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
10051 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
10052 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
10053
10054 // exit hover when pointer goes away
10055 processId(mapper, -1);
10056 processSync(mapper);
10057 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10058 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
10059 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
10060 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
10061}
10062
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -070010063/**
10064 * Set the input device port <--> display port associations, and check that the
10065 * events are routed to the display that matches the display port.
10066 * This can be checked by looking at the displayId of the resulting NotifyMotionArgs.
10067 */
10068TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayPort) {
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -070010069 const std::string usb2 = "USB2";
10070 const uint8_t hdmi1 = 0;
10071 const uint8_t hdmi2 = 1;
10072 const std::string secondaryUniqueId = "uniqueId2";
Michael Wrightfe3de7d2020-07-02 19:05:30 +010010073 constexpr ViewportType type = ViewportType::EXTERNAL;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -070010074
10075 addConfigurationProperty("touch.deviceType", "touchScreen");
10076 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +000010077 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -070010078
10079 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
10080 mFakePolicy->addInputPortAssociation(usb2, hdmi2);
10081
10082 // We are intentionally not adding the viewport for display 1 yet. Since the port association
10083 // for this input device is specified, and the matching viewport is not present,
10084 // the input device should be disabled (at the mapper level).
10085
10086 // Add viewport for display 2 on hdmi2
10087 prepareSecondaryDisplay(type, hdmi2);
10088 // Send a touch event
10089 processPosition(mapper, 100, 100);
10090 processSync(mapper);
10091 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10092
10093 // Add viewport for display 1 on hdmi1
Michael Wrighta9cf4192022-12-01 23:46:39 +000010094 prepareDisplay(ui::ROTATION_0, hdmi1);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -070010095 // Send a touch event again
10096 processPosition(mapper, 100, 100);
10097 processSync(mapper);
10098
10099 NotifyMotionArgs args;
10100 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10101 ASSERT_EQ(DISPLAY_ID, args.displayId);
10102}
Michael Wrightd02c5b62014-02-10 15:10:22 -080010103
Arthur Hung6d5b4b22022-01-21 07:21:10 +000010104TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayUniqueId) {
10105 addConfigurationProperty("touch.deviceType", "touchScreen");
10106 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +000010107 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Arthur Hung6d5b4b22022-01-21 07:21:10 +000010108
10109 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
10110
Michael Wrighta9cf4192022-12-01 23:46:39 +000010111 prepareDisplay(ui::ROTATION_0);
10112 prepareVirtualDisplay(ui::ROTATION_0);
Arthur Hung6d5b4b22022-01-21 07:21:10 +000010113
10114 // Send a touch event
10115 processPosition(mapper, 100, 100);
10116 processSync(mapper);
10117
10118 NotifyMotionArgs args;
10119 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10120 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
10121}
10122
Arthur Hungc7ad2d02018-12-18 17:41:29 +080010123TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
Garfield Tan888a6a42020-01-09 11:39:16 -080010124 // Setup for second display.
Michael Wright17db18e2020-06-26 20:51:44 +010010125 std::shared_ptr<FakePointerController> fakePointerController =
10126 std::make_shared<FakePointerController>();
Garfield Tan888a6a42020-01-09 11:39:16 -080010127 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
Arthur Hungc7ad2d02018-12-18 17:41:29 +080010128 fakePointerController->setPosition(100, 200);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +000010129 mFakePolicy->setPointerController(fakePointerController);
Arthur Hungc7ad2d02018-12-18 17:41:29 +080010130
Garfield Tan888a6a42020-01-09 11:39:16 -080010131 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
Michael Wrightfe3de7d2020-07-02 19:05:30 +010010132 prepareSecondaryDisplay(ViewportType::EXTERNAL);
Garfield Tan888a6a42020-01-09 11:39:16 -080010133
Michael Wrighta9cf4192022-12-01 23:46:39 +000010134 prepareDisplay(ui::ROTATION_0);
Arthur Hungc7ad2d02018-12-18 17:41:29 +080010135 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +000010136 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Arthur Hungc7ad2d02018-12-18 17:41:29 +080010137
Josep del Río2d8c79a2023-01-23 19:33:50 +000010138 // Check source is mouse that would obtain the PointerController.
10139 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Arthur Hungc7ad2d02018-12-18 17:41:29 +080010140
10141 NotifyMotionArgs motionArgs;
10142 processPosition(mapper, 100, 100);
10143 processSync(mapper);
10144
10145 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10146 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
10147 ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
10148}
10149
Siarhei Vishniakou6f778462020-12-09 23:39:07 +000010150/**
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +000010151 * Ensure that the readTime is set to the SYN_REPORT value when processing touch events.
10152 */
10153TEST_F(MultiTouchInputMapperTest, Process_SendsReadTime) {
10154 addConfigurationProperty("touch.deviceType", "touchScreen");
10155 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +000010156 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +000010157
Michael Wrighta9cf4192022-12-01 23:46:39 +000010158 prepareDisplay(ui::ROTATION_0);
Harry Cutts33476232023-01-30 19:57:29 +000010159 process(mapper, 10, /*readTime=*/11, EV_ABS, ABS_MT_TRACKING_ID, 1);
10160 process(mapper, 15, /*readTime=*/16, EV_ABS, ABS_MT_POSITION_X, 100);
10161 process(mapper, 20, /*readTime=*/21, EV_ABS, ABS_MT_POSITION_Y, 100);
10162 process(mapper, 25, /*readTime=*/26, EV_SYN, SYN_REPORT, 0);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +000010163
10164 NotifyMotionArgs args;
10165 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10166 ASSERT_EQ(26, args.readTime);
10167
Harry Cutts33476232023-01-30 19:57:29 +000010168 process(mapper, 30, /*readTime=*/31, EV_ABS, ABS_MT_POSITION_X, 110);
10169 process(mapper, 30, /*readTime=*/32, EV_ABS, ABS_MT_POSITION_Y, 220);
10170 process(mapper, 30, /*readTime=*/33, EV_SYN, SYN_REPORT, 0);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +000010171
10172 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10173 ASSERT_EQ(33, args.readTime);
10174}
10175
10176/**
Siarhei Vishniakou6f778462020-12-09 23:39:07 +000010177 * When the viewport is not active (isActive=false), the touch mapper should be disabled and the
10178 * events should not be delivered to the listener.
10179 */
10180TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreDropped) {
10181 addConfigurationProperty("touch.deviceType", "touchScreen");
Yuncheol Heo50c19b12022-11-02 20:33:08 -070010182 // Don't set touch.enableForInactiveViewport to verify the default behavior.
Michael Wrighta9cf4192022-12-01 23:46:39 +000010183 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +000010184 /*isActive=*/false, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +000010185 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Siarhei Vishniakou6f778462020-12-09 23:39:07 +000010186 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +000010187 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou6f778462020-12-09 23:39:07 +000010188
10189 NotifyMotionArgs motionArgs;
10190 processPosition(mapper, 100, 100);
10191 processSync(mapper);
10192
10193 mFakeListener->assertNotifyMotionWasNotCalled();
10194}
10195
Yuncheol Heo50c19b12022-11-02 20:33:08 -070010196/**
10197 * When the viewport is not active (isActive=false) and touch.enableForInactiveViewport is true,
10198 * the touch mapper can process the events and the events can be delivered to the listener.
10199 */
10200TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreProcessed) {
10201 addConfigurationProperty("touch.deviceType", "touchScreen");
10202 addConfigurationProperty("touch.enableForInactiveViewport", "1");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010203 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +000010204 /*isActive=*/false, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +000010205 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Yuncheol Heo50c19b12022-11-02 20:33:08 -070010206 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +000010207 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Yuncheol Heo50c19b12022-11-02 20:33:08 -070010208
10209 NotifyMotionArgs motionArgs;
10210 processPosition(mapper, 100, 100);
10211 processSync(mapper);
10212
10213 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10214 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10215}
10216
Josh Thielene986aed2023-06-01 14:17:30 +000010217/**
10218 * When the viewport is deactivated (isActive transitions from true to false),
10219 * and touch.enableForInactiveViewport is false, touches prior to the transition
10220 * should be cancelled.
10221 */
Garfield Tanc734e4f2021-01-15 20:01:39 -080010222TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_AbortTouches) {
10223 addConfigurationProperty("touch.deviceType", "touchScreen");
Yuncheol Heo50c19b12022-11-02 20:33:08 -070010224 addConfigurationProperty("touch.enableForInactiveViewport", "0");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010225 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +000010226 /*isActive=*/true, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Garfield Tanc734e4f2021-01-15 20:01:39 -080010227 std::optional<DisplayViewport> optionalDisplayViewport =
10228 mFakePolicy->getDisplayViewportByUniqueId(UNIQUE_ID);
10229 ASSERT_TRUE(optionalDisplayViewport.has_value());
10230 DisplayViewport displayViewport = *optionalDisplayViewport;
10231
Prabir Pradhan4bf6d452023-04-18 21:26:56 +000010232 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Garfield Tanc734e4f2021-01-15 20:01:39 -080010233 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +000010234 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Garfield Tanc734e4f2021-01-15 20:01:39 -080010235
10236 // Finger down
10237 int32_t x = 100, y = 100;
10238 processPosition(mapper, x, y);
10239 processSync(mapper);
10240
10241 NotifyMotionArgs motionArgs;
10242 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10243 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10244
10245 // Deactivate display viewport
10246 displayViewport.isActive = false;
10247 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
Prabir Pradhan4bf6d452023-04-18 21:26:56 +000010248 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Garfield Tanc734e4f2021-01-15 20:01:39 -080010249
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +000010250 // The ongoing touch should be canceled immediately
10251 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10252 EXPECT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
10253
10254 // Finger move is ignored
Garfield Tanc734e4f2021-01-15 20:01:39 -080010255 x += 10, y += 10;
10256 processPosition(mapper, x, y);
10257 processSync(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +000010258 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
Garfield Tanc734e4f2021-01-15 20:01:39 -080010259
10260 // Reactivate display viewport
10261 displayViewport.isActive = true;
10262 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
Prabir Pradhan4bf6d452023-04-18 21:26:56 +000010263 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Garfield Tanc734e4f2021-01-15 20:01:39 -080010264
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +000010265 // Finger move again starts new gesture
Garfield Tanc734e4f2021-01-15 20:01:39 -080010266 x += 10, y += 10;
10267 processPosition(mapper, x, y);
10268 processSync(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +000010269 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10270 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Garfield Tanc734e4f2021-01-15 20:01:39 -080010271}
10272
Josh Thielene986aed2023-06-01 14:17:30 +000010273/**
10274 * When the viewport is deactivated (isActive transitions from true to false),
10275 * and touch.enableForInactiveViewport is true, touches prior to the transition
10276 * should not be cancelled.
10277 */
10278TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_TouchesNotAborted) {
10279 addConfigurationProperty("touch.deviceType", "touchScreen");
10280 addConfigurationProperty("touch.enableForInactiveViewport", "1");
10281 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
10282 /*isActive=*/true, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
10283 std::optional<DisplayViewport> optionalDisplayViewport =
10284 mFakePolicy->getDisplayViewportByUniqueId(UNIQUE_ID);
10285 ASSERT_TRUE(optionalDisplayViewport.has_value());
10286 DisplayViewport displayViewport = *optionalDisplayViewport;
10287
10288 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
10289 prepareAxes(POSITION);
10290 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
10291
10292 // Finger down
10293 int32_t x = 100, y = 100;
10294 processPosition(mapper, x, y);
10295 processSync(mapper);
10296 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10297 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
10298
10299 // Deactivate display viewport
10300 displayViewport.isActive = false;
10301 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
10302 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
10303
10304 // The ongoing touch should not be canceled
10305 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10306
10307 // Finger move is not ignored
10308 x += 10, y += 10;
10309 processPosition(mapper, x, y);
10310 processSync(mapper);
10311 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10312 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
10313
10314 // Reactivate display viewport
10315 displayViewport.isActive = true;
10316 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
10317 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
10318
10319 // Finger move continues and does not start new gesture
10320 x += 10, y += 10;
10321 processPosition(mapper, x, y);
10322 processSync(mapper);
10323 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10324 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
10325}
10326
Arthur Hung7c645402019-01-25 17:45:42 +080010327TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) {
10328 // Setup the first touch screen device.
Arthur Hung7c645402019-01-25 17:45:42 +080010329 prepareAxes(POSITION | ID | SLOT);
10330 addConfigurationProperty("touch.deviceType", "touchScreen");
Arpit Singha8c236b2023-04-25 13:56:05 +000010331 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Arthur Hung7c645402019-01-25 17:45:42 +080010332
10333 // Create the second touch screen device, and enable multi fingers.
10334 const std::string USB2 = "USB2";
arthurhungdcef2dc2020-08-11 14:47:50 +080010335 const std::string DEVICE_NAME2 = "TOUCHSCREEN2";
Arthur Hung2c9a3342019-07-23 14:18:59 +080010336 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080010337 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
arthurhungdcef2dc2020-08-11 14:47:50 +080010338 std::shared_ptr<InputDevice> device2 =
10339 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -070010340 ftl::Flags<InputDeviceClass>(0));
arthurhungdcef2dc2020-08-11 14:47:50 +080010341
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080010342 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
Harry Cutts33476232023-01-30 19:57:29 +000010343 /*flat=*/0, /*fuzz=*/0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080010344 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
Harry Cutts33476232023-01-30 19:57:29 +000010345 /*flat=*/0, /*fuzz=*/0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080010346 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX,
Harry Cutts33476232023-01-30 19:57:29 +000010347 /*flat=*/0, /*fuzz=*/0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080010348 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX,
Harry Cutts33476232023-01-30 19:57:29 +000010349 /*flat=*/0, /*fuzz=*/0);
10350 mFakeEventHub->setAbsoluteAxisValue(SECOND_EVENTHUB_ID, ABS_MT_SLOT, /*value=*/0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080010351 mFakeEventHub->addConfigurationProperty(SECOND_EVENTHUB_ID, String8("touch.deviceType"),
10352 String8("touchScreen"));
Arthur Hung7c645402019-01-25 17:45:42 +080010353
10354 // Setup the second touch screen device.
Arpit Singha8c236b2023-04-25 13:56:05 +000010355 device2->addEmptyEventHubDevice(SECOND_EVENTHUB_ID);
10356 MultiTouchInputMapper& mapper2 = device2->constructAndAddMapper<
10357 MultiTouchInputMapper>(SECOND_EVENTHUB_ID, mFakePolicy->getReaderConfiguration());
Siarhei Vishniakou2935db72022-09-22 13:35:22 -070010358 std::list<NotifyArgs> unused =
10359 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +000010360 /*changes=*/{});
Siarhei Vishniakou2935db72022-09-22 13:35:22 -070010361 unused += device2->reset(ARBITRARY_TIME);
Arthur Hung7c645402019-01-25 17:45:42 +080010362
10363 // Setup PointerController.
Michael Wright17db18e2020-06-26 20:51:44 +010010364 std::shared_ptr<FakePointerController> fakePointerController =
10365 std::make_shared<FakePointerController>();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +000010366 mFakePolicy->setPointerController(fakePointerController);
Arthur Hung7c645402019-01-25 17:45:42 +080010367
10368 // Setup policy for associated displays and show touches.
10369 const uint8_t hdmi1 = 0;
10370 const uint8_t hdmi2 = 1;
10371 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
10372 mFakePolicy->addInputPortAssociation(USB2, hdmi2);
10373 mFakePolicy->setShowTouches(true);
10374
10375 // Create displays.
Michael Wrighta9cf4192022-12-01 23:46:39 +000010376 prepareDisplay(ui::ROTATION_0, hdmi1);
Michael Wrightfe3de7d2020-07-02 19:05:30 +010010377 prepareSecondaryDisplay(ViewportType::EXTERNAL, hdmi2);
Arthur Hung7c645402019-01-25 17:45:42 +080010378
10379 // Default device will reconfigure above, need additional reconfiguration for another device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -070010380 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +000010381 InputReaderConfiguration::Change::DISPLAY_INFO |
10382 InputReaderConfiguration::Change::SHOW_TOUCHES);
Arthur Hung7c645402019-01-25 17:45:42 +080010383
10384 // Two fingers down at default display.
10385 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
10386 processPosition(mapper, x1, y1);
10387 processId(mapper, 1);
10388 processSlot(mapper, 1);
10389 processPosition(mapper, x2, y2);
10390 processId(mapper, 2);
10391 processSync(mapper);
10392
10393 std::map<int32_t, std::vector<int32_t>>::const_iterator iter =
10394 fakePointerController->getSpots().find(DISPLAY_ID);
10395 ASSERT_TRUE(iter != fakePointerController->getSpots().end());
10396 ASSERT_EQ(size_t(2), iter->second.size());
10397
10398 // Two fingers down at second display.
10399 processPosition(mapper2, x1, y1);
10400 processId(mapper2, 1);
10401 processSlot(mapper2, 1);
10402 processPosition(mapper2, x2, y2);
10403 processId(mapper2, 2);
10404 processSync(mapper2);
10405
10406 iter = fakePointerController->getSpots().find(SECONDARY_DISPLAY_ID);
10407 ASSERT_TRUE(iter != fakePointerController->getSpots().end());
10408 ASSERT_EQ(size_t(2), iter->second.size());
Prabir Pradhan197e0862022-07-01 14:28:00 +000010409
10410 // Disable the show touches configuration and ensure the spots are cleared.
10411 mFakePolicy->setShowTouches(false);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -070010412 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +000010413 InputReaderConfiguration::Change::SHOW_TOUCHES);
Prabir Pradhan197e0862022-07-01 14:28:00 +000010414
10415 ASSERT_TRUE(fakePointerController->getSpots().empty());
Arthur Hung7c645402019-01-25 17:45:42 +080010416}
10417
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -060010418TEST_F(MultiTouchInputMapperTest, VideoFrames_ReceivedByListener) {
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -060010419 prepareAxes(POSITION);
10420 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010421 prepareDisplay(ui::ROTATION_0);
Arpit Singha8c236b2023-04-25 13:56:05 +000010422 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -060010423
10424 NotifyMotionArgs motionArgs;
10425 // Unrotated video frame
10426 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
10427 std::vector<TouchVideoFrame> frames{frame};
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080010428 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -060010429 processPosition(mapper, 100, 200);
10430 processSync(mapper);
10431 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10432 ASSERT_EQ(frames, motionArgs.videoFrames);
10433
10434 // Subsequent touch events should not have any videoframes
10435 // This is implemented separately in FakeEventHub,
10436 // but that should match the behaviour of TouchVideoDevice.
10437 processPosition(mapper, 200, 200);
10438 processSync(mapper);
10439 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10440 ASSERT_EQ(std::vector<TouchVideoFrame>(), motionArgs.videoFrames);
10441}
10442
Prabir Pradhanc14266f2021-05-12 15:56:24 -070010443TEST_F(MultiTouchInputMapperTest, VideoFrames_AreNotRotated) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -060010444 prepareAxes(POSITION);
10445 addConfigurationProperty("touch.deviceType", "touchScreen");
Arpit Singha8c236b2023-04-25 13:56:05 +000010446 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -060010447 // Unrotated video frame
10448 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
10449 NotifyMotionArgs motionArgs;
10450
10451 // Test all 4 orientations
Michael Wrighta9cf4192022-12-01 23:46:39 +000010452 for (ui::Rotation orientation : ftl::enum_range<ui::Rotation>()) {
Prabir Pradhanc14266f2021-05-12 15:56:24 -070010453 SCOPED_TRACE("Orientation " + StringPrintf("%i", orientation));
10454 clearViewports();
10455 prepareDisplay(orientation);
10456 std::vector<TouchVideoFrame> frames{frame};
10457 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
10458 processPosition(mapper, 100, 200);
10459 processSync(mapper);
10460 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10461 ASSERT_EQ(frames, motionArgs.videoFrames);
10462 }
10463}
10464
10465TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_AreRotated) {
10466 prepareAxes(POSITION);
10467 addConfigurationProperty("touch.deviceType", "touchScreen");
10468 // Since InputReader works in the un-rotated coordinate space, only devices that are not
10469 // orientation-aware are affected by display rotation.
10470 addConfigurationProperty("touch.orientationAware", "0");
Arpit Singha8c236b2023-04-25 13:56:05 +000010471 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhanc14266f2021-05-12 15:56:24 -070010472 // Unrotated video frame
10473 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
10474 NotifyMotionArgs motionArgs;
10475
10476 // Test all 4 orientations
Michael Wrighta9cf4192022-12-01 23:46:39 +000010477 for (ui::Rotation orientation : ftl::enum_range<ui::Rotation>()) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -060010478 SCOPED_TRACE("Orientation " + StringPrintf("%i", orientation));
10479 clearViewports();
10480 prepareDisplay(orientation);
10481 std::vector<TouchVideoFrame> frames{frame};
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080010482 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -060010483 processPosition(mapper, 100, 200);
10484 processSync(mapper);
10485 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Prabir Pradhanc14266f2021-05-12 15:56:24 -070010486 // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
10487 // compared to the display. This is so that when the window transform (which contains the
10488 // display rotation) is applied later by InputDispatcher, the coordinates end up in the
10489 // window's coordinate space.
10490 frames[0].rotate(getInverseRotation(orientation));
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -060010491 ASSERT_EQ(frames, motionArgs.videoFrames);
lilinnan687e58f2022-07-19 16:00:50 +080010492
10493 // Release finger.
10494 processSync(mapper);
10495 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -060010496 }
10497}
10498
Prabir Pradhanc14266f2021-05-12 15:56:24 -070010499TEST_F(MultiTouchInputMapperTest, VideoFrames_MultipleFramesAreNotRotated) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -060010500 prepareAxes(POSITION);
10501 addConfigurationProperty("touch.deviceType", "touchScreen");
Arpit Singha8c236b2023-04-25 13:56:05 +000010502 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -060010503 // Unrotated video frames. There's no rule that they must all have the same dimensions,
10504 // so mix these.
10505 TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
10506 TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
10507 TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
10508 std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
10509 NotifyMotionArgs motionArgs;
10510
Michael Wrighta9cf4192022-12-01 23:46:39 +000010511 prepareDisplay(ui::ROTATION_90);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080010512 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -060010513 processPosition(mapper, 100, 200);
10514 processSync(mapper);
10515 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Prabir Pradhanc14266f2021-05-12 15:56:24 -070010516 ASSERT_EQ(frames, motionArgs.videoFrames);
10517}
10518
10519TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_MultipleFramesAreRotated) {
10520 prepareAxes(POSITION);
10521 addConfigurationProperty("touch.deviceType", "touchScreen");
10522 // Since InputReader works in the un-rotated coordinate space, only devices that are not
10523 // orientation-aware are affected by display rotation.
10524 addConfigurationProperty("touch.orientationAware", "0");
Arpit Singha8c236b2023-04-25 13:56:05 +000010525 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhanc14266f2021-05-12 15:56:24 -070010526 // Unrotated video frames. There's no rule that they must all have the same dimensions,
10527 // so mix these.
10528 TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
10529 TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
10530 TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
10531 std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
10532 NotifyMotionArgs motionArgs;
10533
Michael Wrighta9cf4192022-12-01 23:46:39 +000010534 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc14266f2021-05-12 15:56:24 -070010535 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
10536 processPosition(mapper, 100, 200);
10537 processSync(mapper);
10538 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10539 std::for_each(frames.begin(), frames.end(), [](TouchVideoFrame& frame) {
10540 // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
10541 // compared to the display. This is so that when the window transform (which contains the
10542 // display rotation) is applied later by InputDispatcher, the coordinates end up in the
10543 // window's coordinate space.
Michael Wrighta9cf4192022-12-01 23:46:39 +000010544 frame.rotate(getInverseRotation(ui::ROTATION_90));
Prabir Pradhanc14266f2021-05-12 15:56:24 -070010545 });
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -060010546 ASSERT_EQ(frames, motionArgs.videoFrames);
10547}
10548
Arthur Hung9da14732019-09-02 16:16:58 +080010549/**
10550 * If we had defined port associations, but the viewport is not ready, the touch device would be
10551 * expected to be disabled, and it should be enabled after the viewport has found.
10552 */
10553TEST_F(MultiTouchInputMapperTest, Configure_EnabledForAssociatedDisplay) {
Arthur Hung9da14732019-09-02 16:16:58 +080010554 constexpr uint8_t hdmi2 = 1;
10555 const std::string secondaryUniqueId = "uniqueId2";
Michael Wrightfe3de7d2020-07-02 19:05:30 +010010556 constexpr ViewportType type = ViewportType::EXTERNAL;
Arthur Hung9da14732019-09-02 16:16:58 +080010557
10558 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi2);
10559
10560 addConfigurationProperty("touch.deviceType", "touchScreen");
10561 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +000010562 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Arthur Hung9da14732019-09-02 16:16:58 +080010563
10564 ASSERT_EQ(mDevice->isEnabled(), false);
10565
10566 // Add display on hdmi2, the device should be enabled and can receive touch event.
10567 prepareSecondaryDisplay(type, hdmi2);
10568 ASSERT_EQ(mDevice->isEnabled(), true);
10569
10570 // Send a touch event.
10571 processPosition(mapper, 100, 100);
10572 processSync(mapper);
10573
10574 NotifyMotionArgs args;
10575 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10576 ASSERT_EQ(SECONDARY_DISPLAY_ID, args.displayId);
10577}
10578
Arthur Hung421eb1c2020-01-16 00:09:42 +080010579TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleSingleTouch) {
Arthur Hung421eb1c2020-01-16 00:09:42 +080010580 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010581 prepareDisplay(ui::ROTATION_0);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010582 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010583 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Arthur Hung421eb1c2020-01-16 00:09:42 +080010584
10585 NotifyMotionArgs motionArgs;
10586
10587 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
10588 // finger down
10589 processId(mapper, 1);
10590 processPosition(mapper, x1, y1);
10591 processSync(mapper);
10592 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10593 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010594 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010595
10596 // finger move
10597 processId(mapper, 1);
10598 processPosition(mapper, x2, y2);
10599 processSync(mapper);
10600 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10601 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010602 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010603
10604 // finger up.
10605 processId(mapper, -1);
10606 processSync(mapper);
10607 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10608 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010609 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010610
10611 // new finger down
10612 processId(mapper, 1);
10613 processPosition(mapper, x3, y3);
10614 processSync(mapper);
10615 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10616 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010617 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010618}
10619
10620/**
arthurhungcc7f9802020-04-30 17:55:40 +080010621 * Test single touch should be canceled when received the MT_TOOL_PALM event, and the following
10622 * MOVE and UP events should be ignored.
Arthur Hung421eb1c2020-01-16 00:09:42 +080010623 */
arthurhungcc7f9802020-04-30 17:55:40 +080010624TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_SinglePointer) {
Arthur Hung421eb1c2020-01-16 00:09:42 +080010625 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010626 prepareDisplay(ui::ROTATION_0);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010627 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010628 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Arthur Hung421eb1c2020-01-16 00:09:42 +080010629
10630 NotifyMotionArgs motionArgs;
10631
10632 // default tool type is finger
10633 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
arthurhungcc7f9802020-04-30 17:55:40 +080010634 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010635 processPosition(mapper, x1, y1);
10636 processSync(mapper);
10637 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10638 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010639 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010640
10641 // Tool changed to MT_TOOL_PALM expect sending the cancel event.
10642 processToolType(mapper, MT_TOOL_PALM);
10643 processSync(mapper);
10644 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10645 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
10646
10647 // Ignore the following MOVE and UP events if had detect a palm event.
arthurhungcc7f9802020-04-30 17:55:40 +080010648 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010649 processPosition(mapper, x2, y2);
10650 processSync(mapper);
10651 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10652
10653 // finger up.
arthurhungcc7f9802020-04-30 17:55:40 +080010654 processId(mapper, INVALID_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010655 processSync(mapper);
10656 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10657
10658 // new finger down
arthurhungcc7f9802020-04-30 17:55:40 +080010659 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010660 processToolType(mapper, MT_TOOL_FINGER);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010661 processPosition(mapper, x3, y3);
10662 processSync(mapper);
10663 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10664 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010665 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010666}
10667
arthurhungbf89a482020-04-17 17:37:55 +080010668/**
arthurhungcc7f9802020-04-30 17:55:40 +080010669 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event from some finger,
10670 * and the rest active fingers could still be allowed to receive the events
arthurhungbf89a482020-04-17 17:37:55 +080010671 */
arthurhungcc7f9802020-04-30 17:55:40 +080010672TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_TwoPointers) {
arthurhungbf89a482020-04-17 17:37:55 +080010673 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010674 prepareDisplay(ui::ROTATION_0);
arthurhungbf89a482020-04-17 17:37:55 +080010675 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010676 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
arthurhungbf89a482020-04-17 17:37:55 +080010677
10678 NotifyMotionArgs motionArgs;
10679
10680 // default tool type is finger
arthurhungcc7f9802020-04-30 17:55:40 +080010681 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220;
10682 processId(mapper, FIRST_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +080010683 processPosition(mapper, x1, y1);
10684 processSync(mapper);
10685 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10686 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010687 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
arthurhungbf89a482020-04-17 17:37:55 +080010688
10689 // Second finger down.
arthurhungcc7f9802020-04-30 17:55:40 +080010690 processSlot(mapper, SECOND_SLOT);
10691 processId(mapper, SECOND_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +080010692 processPosition(mapper, x2, y2);
arthurhungcc7f9802020-04-30 17:55:40 +080010693 processSync(mapper);
10694 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010695 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010696 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
arthurhungcc7f9802020-04-30 17:55:40 +080010697
10698 // If the tool type of the first finger changes to MT_TOOL_PALM,
10699 // we expect to receive ACTION_POINTER_UP with cancel flag.
10700 processSlot(mapper, FIRST_SLOT);
10701 processId(mapper, FIRST_TRACKING_ID);
10702 processToolType(mapper, MT_TOOL_PALM);
10703 processSync(mapper);
10704 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010705 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +080010706 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
10707
10708 // The following MOVE events of second finger should be processed.
10709 processSlot(mapper, SECOND_SLOT);
10710 processId(mapper, SECOND_TRACKING_ID);
10711 processPosition(mapper, x2 + 1, y2 + 1);
10712 processSync(mapper);
10713 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10714 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010715 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
arthurhungcc7f9802020-04-30 17:55:40 +080010716
10717 // First finger up. It used to be in palm mode, and we already generated ACTION_POINTER_UP for
10718 // it. Second finger receive move.
10719 processSlot(mapper, FIRST_SLOT);
10720 processId(mapper, INVALID_TRACKING_ID);
10721 processSync(mapper);
10722 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10723 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010724 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
arthurhungcc7f9802020-04-30 17:55:40 +080010725
10726 // Second finger keeps moving.
10727 processSlot(mapper, SECOND_SLOT);
10728 processId(mapper, SECOND_TRACKING_ID);
10729 processPosition(mapper, x2 + 2, y2 + 2);
10730 processSync(mapper);
10731 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10732 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010733 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
arthurhungcc7f9802020-04-30 17:55:40 +080010734
10735 // Second finger up.
10736 processId(mapper, INVALID_TRACKING_ID);
10737 processSync(mapper);
10738 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10739 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
10740 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
10741}
10742
10743/**
10744 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event, if only 1 finger
10745 * is active, it should send CANCEL after receiving the MT_TOOL_PALM event.
10746 */
10747TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_ShouldCancelWhenAllTouchIsPalm) {
10748 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010749 prepareDisplay(ui::ROTATION_0);
arthurhungcc7f9802020-04-30 17:55:40 +080010750 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010751 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
arthurhungcc7f9802020-04-30 17:55:40 +080010752
10753 NotifyMotionArgs motionArgs;
10754
10755 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
10756 // First finger down.
10757 processId(mapper, FIRST_TRACKING_ID);
10758 processPosition(mapper, x1, y1);
10759 processSync(mapper);
10760 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10761 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010762 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
arthurhungcc7f9802020-04-30 17:55:40 +080010763
10764 // Second finger down.
10765 processSlot(mapper, SECOND_SLOT);
10766 processId(mapper, SECOND_TRACKING_ID);
10767 processPosition(mapper, x2, y2);
arthurhungbf89a482020-04-17 17:37:55 +080010768 processSync(mapper);
10769 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010770 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010771 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
arthurhungbf89a482020-04-17 17:37:55 +080010772
arthurhungcc7f9802020-04-30 17:55:40 +080010773 // If the tool type of the first finger changes to MT_TOOL_PALM,
10774 // we expect to receive ACTION_POINTER_UP with cancel flag.
10775 processSlot(mapper, FIRST_SLOT);
10776 processId(mapper, FIRST_TRACKING_ID);
10777 processToolType(mapper, MT_TOOL_PALM);
10778 processSync(mapper);
10779 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010780 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +080010781 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
10782
10783 // Second finger keeps moving.
10784 processSlot(mapper, SECOND_SLOT);
10785 processId(mapper, SECOND_TRACKING_ID);
10786 processPosition(mapper, x2 + 1, y2 + 1);
10787 processSync(mapper);
10788 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10789 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10790
10791 // second finger becomes palm, receive cancel due to only 1 finger is active.
10792 processId(mapper, SECOND_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +080010793 processToolType(mapper, MT_TOOL_PALM);
10794 processSync(mapper);
10795 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10796 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
10797
arthurhungcc7f9802020-04-30 17:55:40 +080010798 // third finger down.
10799 processSlot(mapper, THIRD_SLOT);
10800 processId(mapper, THIRD_TRACKING_ID);
10801 processToolType(mapper, MT_TOOL_FINGER);
arthurhungbf89a482020-04-17 17:37:55 +080010802 processPosition(mapper, x3, y3);
10803 processSync(mapper);
arthurhungbf89a482020-04-17 17:37:55 +080010804 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10805 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010806 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010807 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
arthurhungcc7f9802020-04-30 17:55:40 +080010808
10809 // third finger move
10810 processId(mapper, THIRD_TRACKING_ID);
10811 processPosition(mapper, x3 + 1, y3 + 1);
10812 processSync(mapper);
10813 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10814 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10815
10816 // first finger up, third finger receive move.
10817 processSlot(mapper, FIRST_SLOT);
10818 processId(mapper, INVALID_TRACKING_ID);
10819 processSync(mapper);
10820 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10821 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010822 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
arthurhungcc7f9802020-04-30 17:55:40 +080010823
10824 // second finger up, third finger receive move.
10825 processSlot(mapper, SECOND_SLOT);
10826 processId(mapper, INVALID_TRACKING_ID);
10827 processSync(mapper);
10828 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10829 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010830 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
arthurhungcc7f9802020-04-30 17:55:40 +080010831
10832 // third finger up.
10833 processSlot(mapper, THIRD_SLOT);
10834 processId(mapper, INVALID_TRACKING_ID);
10835 processSync(mapper);
10836 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10837 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
10838 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
10839}
10840
10841/**
10842 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event from some finger,
10843 * and the active finger could still be allowed to receive the events
10844 */
10845TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_KeepFirstPointer) {
10846 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010847 prepareDisplay(ui::ROTATION_0);
arthurhungcc7f9802020-04-30 17:55:40 +080010848 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010849 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
arthurhungcc7f9802020-04-30 17:55:40 +080010850
10851 NotifyMotionArgs motionArgs;
10852
10853 // default tool type is finger
10854 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220;
10855 processId(mapper, FIRST_TRACKING_ID);
10856 processPosition(mapper, x1, y1);
10857 processSync(mapper);
10858 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10859 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010860 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
arthurhungcc7f9802020-04-30 17:55:40 +080010861
10862 // Second finger down.
10863 processSlot(mapper, SECOND_SLOT);
10864 processId(mapper, SECOND_TRACKING_ID);
10865 processPosition(mapper, x2, y2);
10866 processSync(mapper);
10867 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010868 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010869 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
arthurhungcc7f9802020-04-30 17:55:40 +080010870
10871 // If the tool type of the second finger changes to MT_TOOL_PALM,
10872 // we expect to receive ACTION_POINTER_UP with cancel flag.
10873 processId(mapper, SECOND_TRACKING_ID);
10874 processToolType(mapper, MT_TOOL_PALM);
10875 processSync(mapper);
10876 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010877 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +080010878 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
10879
10880 // The following MOVE event should be processed.
10881 processSlot(mapper, FIRST_SLOT);
10882 processId(mapper, FIRST_TRACKING_ID);
10883 processPosition(mapper, x1 + 1, y1 + 1);
10884 processSync(mapper);
10885 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10886 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010887 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
arthurhungcc7f9802020-04-30 17:55:40 +080010888
10889 // second finger up.
10890 processSlot(mapper, SECOND_SLOT);
10891 processId(mapper, INVALID_TRACKING_ID);
10892 processSync(mapper);
10893 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10894 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10895
10896 // first finger keep moving
10897 processSlot(mapper, FIRST_SLOT);
10898 processId(mapper, FIRST_TRACKING_ID);
10899 processPosition(mapper, x1 + 2, y1 + 2);
10900 processSync(mapper);
10901 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10902 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10903
10904 // first finger up.
10905 processId(mapper, INVALID_TRACKING_ID);
10906 processSync(mapper);
10907 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10908 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
10909 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
arthurhungbf89a482020-04-17 17:37:55 +080010910}
10911
Arthur Hung9ad18942021-06-19 02:04:46 +000010912/**
10913 * Test multi-touch should sent ACTION_POINTER_UP/ACTION_UP when received the INVALID_TRACKING_ID,
10914 * to prevent the driver side may send unexpected data after set tracking id as INVALID_TRACKING_ID
10915 * cause slot be valid again.
10916 */
10917TEST_F(MultiTouchInputMapperTest, Process_MultiTouch_WithInvalidTrackingId) {
10918 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010919 prepareDisplay(ui::ROTATION_0);
Arthur Hung9ad18942021-06-19 02:04:46 +000010920 prepareAxes(POSITION | ID | SLOT | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010921 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Arthur Hung9ad18942021-06-19 02:04:46 +000010922
10923 NotifyMotionArgs motionArgs;
10924
10925 constexpr int32_t x1 = 100, y1 = 200, x2 = 0, y2 = 0;
10926 // First finger down.
10927 processId(mapper, FIRST_TRACKING_ID);
10928 processPosition(mapper, x1, y1);
10929 processPressure(mapper, RAW_PRESSURE_MAX);
10930 processSync(mapper);
10931 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10932 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010933 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
Arthur Hung9ad18942021-06-19 02:04:46 +000010934
10935 // First finger move.
10936 processId(mapper, FIRST_TRACKING_ID);
10937 processPosition(mapper, x1 + 1, y1 + 1);
10938 processPressure(mapper, RAW_PRESSURE_MAX);
10939 processSync(mapper);
10940 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10941 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010942 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
Arthur Hung9ad18942021-06-19 02:04:46 +000010943
10944 // Second finger down.
10945 processSlot(mapper, SECOND_SLOT);
10946 processId(mapper, SECOND_TRACKING_ID);
10947 processPosition(mapper, x2, y2);
10948 processPressure(mapper, RAW_PRESSURE_MAX);
10949 processSync(mapper);
10950 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010951 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010952 ASSERT_EQ(uint32_t(2), motionArgs.getPointerCount());
Arthur Hung9ad18942021-06-19 02:04:46 +000010953
10954 // second finger up with some unexpected data.
10955 processSlot(mapper, SECOND_SLOT);
10956 processId(mapper, INVALID_TRACKING_ID);
10957 processPosition(mapper, x2, y2);
10958 processSync(mapper);
10959 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010960 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010961 ASSERT_EQ(uint32_t(2), motionArgs.getPointerCount());
Arthur Hung9ad18942021-06-19 02:04:46 +000010962
10963 // first finger up with some unexpected data.
10964 processSlot(mapper, FIRST_SLOT);
10965 processId(mapper, INVALID_TRACKING_ID);
10966 processPosition(mapper, x2, y2);
10967 processPressure(mapper, RAW_PRESSURE_MAX);
10968 processSync(mapper);
10969 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10970 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010971 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
Arthur Hung9ad18942021-06-19 02:04:46 +000010972}
10973
Prabir Pradhanf8d9e442023-12-06 22:06:13 +000010974TEST_F(MultiTouchInputMapperTest, ResetClearsTouchState) {
Prabir Pradhanafabcde2022-09-27 19:32:43 +000010975 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010976 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanafabcde2022-09-27 19:32:43 +000010977 prepareAxes(POSITION | ID | SLOT | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010978 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhanafabcde2022-09-27 19:32:43 +000010979
10980 // First finger down.
10981 processId(mapper, FIRST_TRACKING_ID);
10982 processPosition(mapper, 100, 200);
10983 processPressure(mapper, RAW_PRESSURE_MAX);
10984 processSync(mapper);
10985 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10986 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
10987
10988 // Second finger down.
10989 processSlot(mapper, SECOND_SLOT);
10990 processId(mapper, SECOND_TRACKING_ID);
10991 processPosition(mapper, 300, 400);
10992 processPressure(mapper, RAW_PRESSURE_MAX);
10993 processSync(mapper);
10994 ASSERT_NO_FATAL_FAILURE(
10995 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(ACTION_POINTER_1_DOWN)));
10996
Prabir Pradhanf8d9e442023-12-06 22:06:13 +000010997 // Reset the mapper. When the mapper is reset, the touch state is also cleared.
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +000010998 resetMapper(mapper, ARBITRARY_TIME);
10999 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11000 WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
Prabir Pradhanafabcde2022-09-27 19:32:43 +000011001
Prabir Pradhanf8d9e442023-12-06 22:06:13 +000011002 // Move the second slot pointer, and ensure there are no events, because the touch state was
11003 // cleared and no slots should be in use.
Prabir Pradhanafabcde2022-09-27 19:32:43 +000011004 processPosition(mapper, 301, 302);
11005 processSync(mapper);
Prabir Pradhanf8d9e442023-12-06 22:06:13 +000011006 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
11007
11008 // Release both fingers.
11009 processId(mapper, INVALID_TRACKING_ID);
11010 processSlot(mapper, FIRST_SLOT);
11011 processId(mapper, INVALID_TRACKING_ID);
11012 processSync(mapper);
11013 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
11014
11015 // Start a new gesture, and ensure we get a DOWN event for it.
11016 processId(mapper, FIRST_TRACKING_ID);
11017 processPosition(mapper, 200, 300);
11018 processPressure(mapper, RAW_PRESSURE_MAX);
11019 processSync(mapper);
Prabir Pradhanafabcde2022-09-27 19:32:43 +000011020 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11021 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
Prabir Pradhanafabcde2022-09-27 19:32:43 +000011022
11023 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
11024}
11025
Prabir Pradhanf8d9e442023-12-06 22:06:13 +000011026TEST_F(MultiTouchInputMapperTest, ResetClearsTouchStateWithNoPointersDown) {
Prabir Pradhanafabcde2022-09-27 19:32:43 +000011027 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000011028 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanafabcde2022-09-27 19:32:43 +000011029 prepareAxes(POSITION | ID | SLOT | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +000011030 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhanafabcde2022-09-27 19:32:43 +000011031
11032 // First finger touches down and releases.
11033 processId(mapper, FIRST_TRACKING_ID);
11034 processPosition(mapper, 100, 200);
11035 processPressure(mapper, RAW_PRESSURE_MAX);
11036 processSync(mapper);
11037 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11038 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
11039 processId(mapper, INVALID_TRACKING_ID);
11040 processSync(mapper);
11041 ASSERT_NO_FATAL_FAILURE(
11042 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
11043
11044 // Reset the mapper. When the mapper is reset, we expect it to restore the latest
11045 // raw state where no pointers are down.
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +000011046 resetMapper(mapper, ARBITRARY_TIME);
Prabir Pradhanafabcde2022-09-27 19:32:43 +000011047 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
11048
11049 // Send an empty sync frame. Since there are no pointers, no events are generated.
11050 processSync(mapper);
11051 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
11052}
11053
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +000011054TEST_F(MultiTouchInputMapperTest, StylusSourceIsAddedDynamicallyFromToolType) {
Prabir Pradhanf9a41282022-10-25 17:15:50 +000011055 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000011056 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanf9a41282022-10-25 17:15:50 +000011057 prepareAxes(POSITION | ID | SLOT | PRESSURE | TOOL_TYPE);
Arpit Singha8c236b2023-04-25 13:56:05 +000011058 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +000011059 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
Prabir Pradhanf9a41282022-10-25 17:15:50 +000011060
11061 // Even if the device supports reporting the ABS_MT_TOOL_TYPE axis, which could give it the
11062 // ability to report MT_TOOL_PEN, we do not report the device as coming from a stylus source.
11063 // Due to limitations in the evdev protocol, we cannot say for certain that a device is capable
11064 // of reporting stylus events just because it supports ABS_MT_TOOL_TYPE.
11065 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
11066
11067 // However, if the device ever ends up reporting an event with MT_TOOL_PEN, it should be
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +000011068 // reported with the stylus source.
Prabir Pradhanf9a41282022-10-25 17:15:50 +000011069 processId(mapper, FIRST_TRACKING_ID);
11070 processToolType(mapper, MT_TOOL_PEN);
11071 processPosition(mapper, 100, 200);
11072 processPressure(mapper, RAW_PRESSURE_MAX);
11073 processSync(mapper);
11074 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11075 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
11076 WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011077 WithToolType(ToolType::STYLUS))));
Prabir Pradhanf9a41282022-10-25 17:15:50 +000011078
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +000011079 // Now that we know the device supports styluses, ensure that the device is re-configured with
11080 // the stylus source.
11081 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS, mapper.getSources());
11082 {
11083 const auto& devices = mReader->getInputDevices();
11084 auto deviceInfo =
11085 std::find_if(devices.begin(), devices.end(),
11086 [](const InputDeviceInfo& info) { return info.getId() == DEVICE_ID; });
11087 LOG_ALWAYS_FATAL_IF(deviceInfo == devices.end(), "Cannot find InputDevice");
11088 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS, deviceInfo->getSources());
11089 }
11090
11091 // Ensure the device was not reset to prevent interruptions of any ongoing gestures.
11092 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
11093
Prabir Pradhanf9a41282022-10-25 17:15:50 +000011094 processId(mapper, INVALID_TRACKING_ID);
11095 processSync(mapper);
11096 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11097 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
11098 WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011099 WithToolType(ToolType::STYLUS))));
Prabir Pradhanf9a41282022-10-25 17:15:50 +000011100}
11101
Seunghwan Choi356026c2023-02-01 14:37:25 +090011102TEST_F(MultiTouchInputMapperTest, Process_WhenConfigEnabled_ShouldShowDirectStylusPointer) {
11103 addConfigurationProperty("touch.deviceType", "touchScreen");
11104 prepareDisplay(ui::ROTATION_0);
11105 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE | PRESSURE);
11106 // Add BTN_TOOL_PEN to statically show stylus support, since using ABS_MT_TOOL_TYPE can only
11107 // indicate stylus presence dynamically.
11108 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
11109 std::shared_ptr<FakePointerController> fakePointerController =
11110 std::make_shared<FakePointerController>();
11111 mFakePolicy->setPointerController(fakePointerController);
11112 mFakePolicy->setStylusPointerIconEnabled(true);
Arpit Singha8c236b2023-04-25 13:56:05 +000011113 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Seunghwan Choi356026c2023-02-01 14:37:25 +090011114
11115 processId(mapper, FIRST_TRACKING_ID);
11116 processPressure(mapper, RAW_PRESSURE_MIN);
11117 processPosition(mapper, 100, 200);
11118 processToolType(mapper, MT_TOOL_PEN);
11119 processSync(mapper);
11120 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11121 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011122 WithToolType(ToolType::STYLUS),
Seunghwan Choi356026c2023-02-01 14:37:25 +090011123 WithPointerCoords(0, toDisplayX(100), toDisplayY(200)))));
11124 ASSERT_TRUE(fakePointerController->isPointerShown());
11125 ASSERT_NO_FATAL_FAILURE(
11126 fakePointerController->assertPosition(toDisplayX(100), toDisplayY(200)));
11127}
11128
11129TEST_F(MultiTouchInputMapperTest, Process_WhenConfigDisabled_ShouldNotShowDirectStylusPointer) {
11130 addConfigurationProperty("touch.deviceType", "touchScreen");
11131 prepareDisplay(ui::ROTATION_0);
11132 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE | PRESSURE);
11133 // Add BTN_TOOL_PEN to statically show stylus support, since using ABS_MT_TOOL_TYPE can only
11134 // indicate stylus presence dynamically.
11135 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
11136 std::shared_ptr<FakePointerController> fakePointerController =
11137 std::make_shared<FakePointerController>();
11138 mFakePolicy->setPointerController(fakePointerController);
11139 mFakePolicy->setStylusPointerIconEnabled(false);
Arpit Singha8c236b2023-04-25 13:56:05 +000011140 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Seunghwan Choi356026c2023-02-01 14:37:25 +090011141
11142 processId(mapper, FIRST_TRACKING_ID);
11143 processPressure(mapper, RAW_PRESSURE_MIN);
11144 processPosition(mapper, 100, 200);
11145 processToolType(mapper, MT_TOOL_PEN);
11146 processSync(mapper);
11147 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11148 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011149 WithToolType(ToolType::STYLUS),
Seunghwan Choi356026c2023-02-01 14:37:25 +090011150 WithPointerCoords(0, toDisplayX(100), toDisplayY(200)))));
11151 ASSERT_FALSE(fakePointerController->isPointerShown());
11152}
11153
Prabir Pradhanf8d9e442023-12-06 22:06:13 +000011154TEST_F(MultiTouchInputMapperTest, SimulateKernelBufferOverflow) {
11155 addConfigurationProperty("touch.deviceType", "touchScreen");
11156 prepareDisplay(ui::ROTATION_0);
11157 prepareAxes(POSITION | ID | SLOT | PRESSURE);
11158 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
11159
11160 // First finger down.
11161 processId(mapper, FIRST_TRACKING_ID);
11162 processPosition(mapper, 100, 200);
11163 processPressure(mapper, RAW_PRESSURE_MAX);
11164 processSync(mapper);
11165 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11166 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
11167
11168 // Assume the kernel buffer overflows, and we get a SYN_DROPPED event.
11169 // This will reset the mapper, and thus also reset the touch state.
11170 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_DROPPED, 0);
11171 resetMapper(mapper, ARBITRARY_TIME);
11172 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11173 WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
11174
11175 // Since the touch state was reset, it doesn't know which slots are active, so any movements
11176 // are ignored.
11177 processPosition(mapper, 101, 201);
11178 processSync(mapper);
11179
11180 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
11181
11182 // Second finger goes down. This is the first active finger, so we get a DOWN event.
11183 processSlot(mapper, SECOND_SLOT);
11184 processId(mapper, SECOND_TRACKING_ID);
11185 processPosition(mapper, 400, 500);
11186 processPressure(mapper, RAW_PRESSURE_MAX);
11187 processSync(mapper);
11188
11189 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11190 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
11191
11192 // First slot is still ignored, only the second one is active.
11193 processSlot(mapper, FIRST_SLOT);
11194 processPosition(mapper, 102, 202);
11195 processSlot(mapper, SECOND_SLOT);
11196 processPosition(mapper, 401, 501);
11197 processSync(mapper);
11198
11199 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11200 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
11201
11202 // Both slots up, so we get the UP event for the active pointer.
11203 processSlot(mapper, FIRST_SLOT);
11204 processId(mapper, INVALID_TRACKING_ID);
11205 processSlot(mapper, SECOND_SLOT);
11206 processId(mapper, INVALID_TRACKING_ID);
11207 processSync(mapper);
11208
11209 ASSERT_NO_FATAL_FAILURE(
11210 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
11211 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
11212}
11213
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080011214// --- MultiTouchInputMapperTest_ExternalDevice ---
11215
11216class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest {
11217protected:
Chris Yea52ade12020-08-27 16:49:20 -070011218 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080011219};
11220
11221/**
11222 * Expect fallback to internal viewport if device is external and external viewport is not present.
11223 */
11224TEST_F(MultiTouchInputMapperTest_ExternalDevice, Viewports_Fallback) {
11225 prepareAxes(POSITION);
11226 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000011227 prepareDisplay(ui::ROTATION_0);
Arpit Singha8c236b2023-04-25 13:56:05 +000011228 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080011229
11230 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
11231
11232 NotifyMotionArgs motionArgs;
11233
11234 // Expect the event to be sent to the internal viewport,
11235 // because an external viewport is not present.
11236 processPosition(mapper, 100, 100);
11237 processSync(mapper);
11238 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
11239 ASSERT_EQ(ADISPLAY_ID_DEFAULT, motionArgs.displayId);
11240
11241 // Expect the event to be sent to the external viewport if it is present.
Michael Wrightfe3de7d2020-07-02 19:05:30 +010011242 prepareSecondaryDisplay(ViewportType::EXTERNAL);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080011243 processPosition(mapper, 100, 100);
11244 processSync(mapper);
11245 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
11246 ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
11247}
Arthur Hung4197f6b2020-03-16 15:39:59 +080011248
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011249TEST_F(MultiTouchInputMapperTest, Process_TouchpadCapture) {
11250 // we need a pointer controller for mouse mode of touchpad (start pointer at 0,0)
11251 std::shared_ptr<FakePointerController> fakePointerController =
11252 std::make_shared<FakePointerController>();
11253 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
11254 fakePointerController->setPosition(0, 0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011255
11256 // prepare device and capture
Michael Wrighta9cf4192022-12-01 23:46:39 +000011257 prepareDisplay(ui::ROTATION_0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011258 prepareAxes(POSITION | ID | SLOT);
11259 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
11260 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
11261 mFakePolicy->setPointerCapture(true);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +000011262 mFakePolicy->setPointerController(fakePointerController);
Arpit Singha8c236b2023-04-25 13:56:05 +000011263 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011264
11265 // captured touchpad should be a touchpad source
11266 NotifyDeviceResetArgs resetArgs;
11267 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
11268 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
11269
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000011270 InputDeviceInfo deviceInfo = mDevice->getDeviceInfo();
Chris Yef74dc422020-09-02 22:41:50 -070011271
11272 const InputDeviceInfo::MotionRange* relRangeX =
11273 deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, AINPUT_SOURCE_TOUCHPAD);
11274 ASSERT_NE(relRangeX, nullptr);
11275 ASSERT_EQ(relRangeX->min, -(RAW_X_MAX - RAW_X_MIN));
11276 ASSERT_EQ(relRangeX->max, RAW_X_MAX - RAW_X_MIN);
11277 const InputDeviceInfo::MotionRange* relRangeY =
11278 deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, AINPUT_SOURCE_TOUCHPAD);
11279 ASSERT_NE(relRangeY, nullptr);
11280 ASSERT_EQ(relRangeY->min, -(RAW_Y_MAX - RAW_Y_MIN));
11281 ASSERT_EQ(relRangeY->max, RAW_Y_MAX - RAW_Y_MIN);
11282
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011283 // run captured pointer tests - note that this is unscaled, so input listener events should be
11284 // identical to what the hardware sends (accounting for any
11285 // calibration).
11286 // FINGER 0 DOWN
Chris Ye364fdb52020-08-05 15:07:56 -070011287 processSlot(mapper, 0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011288 processId(mapper, 1);
11289 processPosition(mapper, 100 + RAW_X_MIN, 100 + RAW_Y_MIN);
11290 processKey(mapper, BTN_TOUCH, 1);
11291 processSync(mapper);
11292
11293 // expect coord[0] to contain initial location of touch 0
11294 NotifyMotionArgs args;
11295 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11296 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011297 ASSERT_EQ(1U, args.getPointerCount());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011298 ASSERT_EQ(0, args.pointerProperties[0].id);
11299 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, args.source);
11300 ASSERT_NO_FATAL_FAILURE(
11301 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
11302
11303 // FINGER 1 DOWN
11304 processSlot(mapper, 1);
11305 processId(mapper, 2);
11306 processPosition(mapper, 560 + RAW_X_MIN, 154 + RAW_Y_MIN);
11307 processSync(mapper);
11308
11309 // expect coord[0] to contain previous location, coord[1] to contain new touch 1 location
11310 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080011311 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011312 ASSERT_EQ(2U, args.getPointerCount());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011313 ASSERT_EQ(0, args.pointerProperties[0].id);
11314 ASSERT_EQ(1, args.pointerProperties[1].id);
11315 ASSERT_NO_FATAL_FAILURE(
11316 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
11317 ASSERT_NO_FATAL_FAILURE(
11318 assertPointerCoords(args.pointerCoords[1], 560, 154, 1, 0, 0, 0, 0, 0, 0, 0));
11319
11320 // FINGER 1 MOVE
11321 processPosition(mapper, 540 + RAW_X_MIN, 690 + RAW_Y_MIN);
11322 processSync(mapper);
11323
11324 // expect coord[0] to contain previous location, coord[1] to contain new touch 1 location
11325 // from move
11326 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11327 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
11328 ASSERT_NO_FATAL_FAILURE(
11329 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
11330 ASSERT_NO_FATAL_FAILURE(
11331 assertPointerCoords(args.pointerCoords[1], 540, 690, 1, 0, 0, 0, 0, 0, 0, 0));
11332
11333 // FINGER 0 MOVE
11334 processSlot(mapper, 0);
11335 processPosition(mapper, 50 + RAW_X_MIN, 800 + RAW_Y_MIN);
11336 processSync(mapper);
11337
11338 // expect coord[0] to contain new touch 0 location, coord[1] to contain previous location
11339 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11340 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
11341 ASSERT_NO_FATAL_FAILURE(
11342 assertPointerCoords(args.pointerCoords[0], 50, 800, 1, 0, 0, 0, 0, 0, 0, 0));
11343 ASSERT_NO_FATAL_FAILURE(
11344 assertPointerCoords(args.pointerCoords[1], 540, 690, 1, 0, 0, 0, 0, 0, 0, 0));
11345
11346 // BUTTON DOWN
11347 processKey(mapper, BTN_LEFT, 1);
11348 processSync(mapper);
11349
11350 // touchinputmapper design sends a move before button press
11351 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11352 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
11353 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11354 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
11355
11356 // BUTTON UP
11357 processKey(mapper, BTN_LEFT, 0);
11358 processSync(mapper);
11359
11360 // touchinputmapper design sends a move after button release
11361 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11362 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
11363 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11364 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
11365
11366 // FINGER 0 UP
11367 processId(mapper, -1);
11368 processSync(mapper);
11369 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11370 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | 0x0000, args.action);
11371
11372 // FINGER 1 MOVE
11373 processSlot(mapper, 1);
11374 processPosition(mapper, 320 + RAW_X_MIN, 900 + RAW_Y_MIN);
11375 processSync(mapper);
11376
11377 // expect coord[0] to contain new location of touch 1, and properties[0].id to contain 1
11378 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11379 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011380 ASSERT_EQ(1U, args.getPointerCount());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011381 ASSERT_EQ(1, args.pointerProperties[0].id);
11382 ASSERT_NO_FATAL_FAILURE(
11383 assertPointerCoords(args.pointerCoords[0], 320, 900, 1, 0, 0, 0, 0, 0, 0, 0));
11384
11385 // FINGER 1 UP
11386 processId(mapper, -1);
11387 processKey(mapper, BTN_TOUCH, 0);
11388 processSync(mapper);
11389 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11390 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
11391
Josep del Río2d8c79a2023-01-23 19:33:50 +000011392 // non captured touchpad should be a mouse source
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011393 mFakePolicy->setPointerCapture(false);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +000011394 configureDevice(InputReaderConfiguration::Change::POINTER_CAPTURE);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011395 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Josep del Río2d8c79a2023-01-23 19:33:50 +000011396 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011397}
11398
11399TEST_F(MultiTouchInputMapperTest, Process_UnCapturedTouchpadPointer) {
11400 std::shared_ptr<FakePointerController> fakePointerController =
11401 std::make_shared<FakePointerController>();
11402 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
11403 fakePointerController->setPosition(0, 0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011404
11405 // prepare device and capture
Michael Wrighta9cf4192022-12-01 23:46:39 +000011406 prepareDisplay(ui::ROTATION_0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011407 prepareAxes(POSITION | ID | SLOT);
11408 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
11409 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +000011410 mFakePolicy->setPointerController(fakePointerController);
Arpit Singha8c236b2023-04-25 13:56:05 +000011411 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011412 // run uncaptured pointer tests - pushes out generic events
11413 // FINGER 0 DOWN
11414 processId(mapper, 3);
11415 processPosition(mapper, 100, 100);
11416 processKey(mapper, BTN_TOUCH, 1);
11417 processSync(mapper);
11418
11419 // start at (100,100), cursor should be at (0,0) * scale
11420 NotifyMotionArgs args;
11421 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11422 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
11423 ASSERT_NO_FATAL_FAILURE(
11424 assertPointerCoords(args.pointerCoords[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
11425
11426 // FINGER 0 MOVE
11427 processPosition(mapper, 200, 200);
11428 processSync(mapper);
11429
11430 // compute scaling to help with touch position checking
11431 float rawDiagonal = hypotf(RAW_X_MAX - RAW_X_MIN, RAW_Y_MAX - RAW_Y_MIN);
11432 float displayDiagonal = hypotf(DISPLAY_WIDTH, DISPLAY_HEIGHT);
11433 float scale =
11434 mFakePolicy->getPointerGestureMovementSpeedRatio() * displayDiagonal / rawDiagonal;
11435
11436 // translate from (100,100) -> (200,200), cursor should have changed to (100,100) * scale)
11437 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11438 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
11439 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 100 * scale, 100 * scale, 0,
11440 0, 0, 0, 0, 0, 0, 0));
LiZhihong758eb562022-11-03 15:28:29 +080011441
11442 // BUTTON DOWN
11443 processKey(mapper, BTN_LEFT, 1);
11444 processSync(mapper);
11445
11446 // touchinputmapper design sends a move before button press
11447 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11448 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
11449 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11450 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
11451
11452 // BUTTON UP
11453 processKey(mapper, BTN_LEFT, 0);
11454 processSync(mapper);
11455
11456 // touchinputmapper design sends a move after button release
11457 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11458 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
11459 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11460 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011461}
11462
11463TEST_F(MultiTouchInputMapperTest, WhenCapturedAndNotCaptured_GetSources) {
11464 std::shared_ptr<FakePointerController> fakePointerController =
11465 std::make_shared<FakePointerController>();
11466
Michael Wrighta9cf4192022-12-01 23:46:39 +000011467 prepareDisplay(ui::ROTATION_0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011468 prepareAxes(POSITION | ID | SLOT);
11469 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +000011470 mFakePolicy->setPointerController(fakePointerController);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011471 mFakePolicy->setPointerCapture(false);
Arpit Singha8c236b2023-04-25 13:56:05 +000011472 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011473
Josep del Río2d8c79a2023-01-23 19:33:50 +000011474 // uncaptured touchpad should be a pointer device
11475 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011476
Josep del Río2d8c79a2023-01-23 19:33:50 +000011477 // captured touchpad should be a touchpad device
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011478 mFakePolicy->setPointerCapture(true);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +000011479 configureDevice(InputReaderConfiguration::Change::POINTER_CAPTURE);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080011480 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
11481}
11482
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +000011483// --- BluetoothMultiTouchInputMapperTest ---
11484
11485class BluetoothMultiTouchInputMapperTest : public MultiTouchInputMapperTest {
11486protected:
11487 void SetUp() override {
11488 InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL, BUS_BLUETOOTH);
11489 }
11490};
11491
11492TEST_F(BluetoothMultiTouchInputMapperTest, TimestampSmoothening) {
11493 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000011494 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +000011495 prepareAxes(POSITION | ID | SLOT | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +000011496 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +000011497
11498 nsecs_t kernelEventTime = ARBITRARY_TIME;
11499 nsecs_t expectedEventTime = ARBITRARY_TIME;
11500 // Touch down.
11501 processId(mapper, FIRST_TRACKING_ID);
11502 processPosition(mapper, 100, 200);
11503 processPressure(mapper, RAW_PRESSURE_MAX);
11504 processSync(mapper, ARBITRARY_TIME);
11505 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11506 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithEventTime(ARBITRARY_TIME))));
11507
11508 // Process several events that come in quick succession, according to their timestamps.
11509 for (int i = 0; i < 3; i++) {
11510 constexpr static nsecs_t delta = ms2ns(1);
11511 static_assert(delta < MIN_BLUETOOTH_TIMESTAMP_DELTA);
11512 kernelEventTime += delta;
11513 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
11514
11515 processPosition(mapper, 101 + i, 201 + i);
11516 processSync(mapper, kernelEventTime);
11517 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11518 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
11519 WithEventTime(expectedEventTime))));
11520 }
11521
11522 // Release the touch.
11523 processId(mapper, INVALID_TRACKING_ID);
11524 processPressure(mapper, RAW_PRESSURE_MIN);
11525 processSync(mapper, ARBITRARY_TIME + ms2ns(50));
11526 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11527 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
11528 WithEventTime(ARBITRARY_TIME + ms2ns(50)))));
11529}
11530
11531// --- MultiTouchPointerModeTest ---
11532
HQ Liue6983c72022-04-19 22:14:56 +000011533class MultiTouchPointerModeTest : public MultiTouchInputMapperTest {
11534protected:
11535 float mPointerMovementScale;
11536 float mPointerXZoomScale;
11537 void preparePointerMode(int xAxisResolution, int yAxisResolution) {
11538 addConfigurationProperty("touch.deviceType", "pointer");
11539 std::shared_ptr<FakePointerController> fakePointerController =
11540 std::make_shared<FakePointerController>();
11541 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
11542 fakePointerController->setPosition(0, 0);
Michael Wrighta9cf4192022-12-01 23:46:39 +000011543 prepareDisplay(ui::ROTATION_0);
HQ Liue6983c72022-04-19 22:14:56 +000011544
11545 prepareAxes(POSITION);
11546 prepareAbsoluteAxisResolution(xAxisResolution, yAxisResolution);
11547 // In order to enable swipe and freeform gesture in pointer mode, pointer capture
11548 // needs to be disabled, and the pointer gesture needs to be enabled.
11549 mFakePolicy->setPointerCapture(false);
11550 mFakePolicy->setPointerGestureEnabled(true);
11551 mFakePolicy->setPointerController(fakePointerController);
11552
11553 float rawDiagonal = hypotf(RAW_X_MAX - RAW_X_MIN, RAW_Y_MAX - RAW_Y_MIN);
11554 float displayDiagonal = hypotf(DISPLAY_WIDTH, DISPLAY_HEIGHT);
11555 mPointerMovementScale =
11556 mFakePolicy->getPointerGestureMovementSpeedRatio() * displayDiagonal / rawDiagonal;
11557 mPointerXZoomScale =
11558 mFakePolicy->getPointerGestureZoomSpeedRatio() * displayDiagonal / rawDiagonal;
11559 }
11560
11561 void prepareAbsoluteAxisResolution(int xAxisResolution, int yAxisResolution) {
11562 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
11563 /*flat*/ 0,
11564 /*fuzz*/ 0, /*resolution*/ xAxisResolution);
11565 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
11566 /*flat*/ 0,
11567 /*fuzz*/ 0, /*resolution*/ yAxisResolution);
11568 }
11569};
11570
11571/**
11572 * Two fingers down on a pointer mode touch pad. The width
11573 * of the two finger is larger than 1/4 of the touch pack diagnal length. However, it
11574 * is smaller than the fixed min physical length 30mm. Two fingers' distance must
11575 * be greater than the both value to be freeform gesture, so that after two
11576 * fingers start to move downwards, the gesture should be swipe.
11577 */
11578TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthSwipe) {
11579 // The min freeform gesture width is 25units/mm x 30mm = 750
11580 // which is greater than fraction of the diagnal length of the touchpad (349).
11581 // Thus, MaxSwipWidth is 750.
Harry Cutts33476232023-01-30 19:57:29 +000011582 preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
Arpit Singha8c236b2023-04-25 13:56:05 +000011583 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
HQ Liue6983c72022-04-19 22:14:56 +000011584 NotifyMotionArgs motionArgs;
11585
11586 // Two fingers down at once.
11587 // The two fingers are 450 units apart, expects the current gesture to be PRESS
11588 // Pointer's initial position is used the [0,0] coordinate.
11589 int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125;
11590
11591 processId(mapper, FIRST_TRACKING_ID);
11592 processPosition(mapper, x1, y1);
11593 processMTSync(mapper);
11594 processId(mapper, SECOND_TRACKING_ID);
11595 processPosition(mapper, x2, y2);
11596 processMTSync(mapper);
11597 processSync(mapper);
11598
11599 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011600 ASSERT_EQ(1U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011601 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011602 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000011603 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000011604 ASSERT_NO_FATAL_FAILURE(
11605 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
11606
11607 // It should be recognized as a SWIPE gesture when two fingers start to move down,
11608 // that there should be 1 pointer.
11609 int32_t movingDistance = 200;
11610 y1 += movingDistance;
11611 y2 += movingDistance;
11612
11613 processId(mapper, FIRST_TRACKING_ID);
11614 processPosition(mapper, x1, y1);
11615 processMTSync(mapper);
11616 processId(mapper, SECOND_TRACKING_ID);
11617 processPosition(mapper, x2, y2);
11618 processMTSync(mapper);
11619 processSync(mapper);
11620
11621 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011622 ASSERT_EQ(1U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011623 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011624 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000011625 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000011626 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
11627 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
11628 0, 0, 0, 0));
11629}
11630
11631/**
11632 * Two fingers down on a pointer mode touch pad. The width of the two finger is larger
11633 * than the minimum freeform gesture width, 30mm. However, it is smaller than 1/4 of
11634 * the touch pack diagnal length. Two fingers' distance must be greater than the both
11635 * value to be freeform gesture, so that after two fingers start to move downwards,
11636 * the gesture should be swipe.
11637 */
11638TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthLowResolutionSwipe) {
11639 // The min freeform gesture width is 5units/mm x 30mm = 150
11640 // which is greater than fraction of the diagnal length of the touchpad (349).
11641 // Thus, MaxSwipWidth is the fraction of the diagnal length, 349.
Harry Cutts33476232023-01-30 19:57:29 +000011642 preparePointerMode(/*xResolution=*/5, /*yResolution=*/5);
Arpit Singha8c236b2023-04-25 13:56:05 +000011643 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
HQ Liue6983c72022-04-19 22:14:56 +000011644 NotifyMotionArgs motionArgs;
11645
11646 // Two fingers down at once.
11647 // The two fingers are 250 units apart, expects the current gesture to be PRESS
11648 // Pointer's initial position is used the [0,0] coordinate.
11649 int32_t x1 = 100, y1 = 125, x2 = 350, y2 = 125;
11650
11651 processId(mapper, FIRST_TRACKING_ID);
11652 processPosition(mapper, x1, y1);
11653 processMTSync(mapper);
11654 processId(mapper, SECOND_TRACKING_ID);
11655 processPosition(mapper, x2, y2);
11656 processMTSync(mapper);
11657 processSync(mapper);
11658
11659 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011660 ASSERT_EQ(1U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011661 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011662 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000011663 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000011664 ASSERT_NO_FATAL_FAILURE(
11665 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
11666
11667 // It should be recognized as a SWIPE gesture when two fingers start to move down,
11668 // and there should be 1 pointer.
11669 int32_t movingDistance = 200;
11670 y1 += movingDistance;
11671 y2 += movingDistance;
11672
11673 processId(mapper, FIRST_TRACKING_ID);
11674 processPosition(mapper, x1, y1);
11675 processMTSync(mapper);
11676 processId(mapper, SECOND_TRACKING_ID);
11677 processPosition(mapper, x2, y2);
11678 processMTSync(mapper);
11679 processSync(mapper);
11680
11681 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011682 ASSERT_EQ(1U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011683 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011684 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000011685 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000011686 // New coordinate is the scaled relative coordinate from the initial coordinate.
11687 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
11688 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
11689 0, 0, 0, 0));
11690}
11691
11692/**
11693 * Touch the touch pad with two fingers with a distance wider than the minimum freeform
11694 * gesture width and 1/4 of the diagnal length of the touchpad. Expect to receive
11695 * freeform gestures after two fingers start to move downwards.
11696 */
11697TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) {
Harry Cutts33476232023-01-30 19:57:29 +000011698 preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
Arpit Singha8c236b2023-04-25 13:56:05 +000011699 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
HQ Liue6983c72022-04-19 22:14:56 +000011700
11701 NotifyMotionArgs motionArgs;
11702
11703 // Two fingers down at once. Wider than the max swipe width.
11704 // The gesture is expected to be PRESS, then transformed to FREEFORM
11705 int32_t x1 = 100, y1 = 125, x2 = 900, y2 = 125;
11706
11707 processId(mapper, FIRST_TRACKING_ID);
11708 processPosition(mapper, x1, y1);
11709 processMTSync(mapper);
11710 processId(mapper, SECOND_TRACKING_ID);
11711 processPosition(mapper, x2, y2);
11712 processMTSync(mapper);
11713 processSync(mapper);
11714
11715 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011716 ASSERT_EQ(1U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011717 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011718 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000011719 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000011720 // One pointer for PRESS, and its coordinate is used as the origin for pointer coordinates.
11721 ASSERT_NO_FATAL_FAILURE(
11722 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
11723
11724 int32_t movingDistance = 200;
11725
11726 // Move two fingers down, expect a cancel event because gesture is changing to freeform,
11727 // then two down events for two pointers.
11728 y1 += movingDistance;
11729 y2 += movingDistance;
11730
11731 processId(mapper, FIRST_TRACKING_ID);
11732 processPosition(mapper, x1, y1);
11733 processMTSync(mapper);
11734 processId(mapper, SECOND_TRACKING_ID);
11735 processPosition(mapper, x2, y2);
11736 processMTSync(mapper);
11737 processSync(mapper);
11738
11739 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
11740 // The previous PRESS gesture is cancelled, because it is transformed to freeform
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011741 ASSERT_EQ(1U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011742 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
11743 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011744 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011745 ASSERT_EQ(1U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011746 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
11747 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011748 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000011749 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011750 ASSERT_EQ(2U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011751 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN, motionArgs.action & AMOTION_EVENT_ACTION_MASK);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011752 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000011753 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000011754 // Two pointers' scaled relative coordinates from their initial centroid.
11755 // Initial y coordinates are 0 as y1 and y2 have the same value.
11756 float cookedX1 = (x1 - x2) / 2 * mPointerXZoomScale;
11757 float cookedX2 = (x2 - x1) / 2 * mPointerXZoomScale;
11758 // When pointers move, the new coordinates equal to the initial coordinates plus
11759 // scaled moving distance.
11760 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
11761 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
11762 0, 0, 0, 0));
11763 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], cookedX2,
11764 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
11765 0, 0, 0, 0));
11766
11767 // Move two fingers down again, expect one MOVE motion event.
11768 y1 += movingDistance;
11769 y2 += movingDistance;
11770
11771 processId(mapper, FIRST_TRACKING_ID);
11772 processPosition(mapper, x1, y1);
11773 processMTSync(mapper);
11774 processId(mapper, SECOND_TRACKING_ID);
11775 processPosition(mapper, x2, y2);
11776 processMTSync(mapper);
11777 processSync(mapper);
11778
11779 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011780 ASSERT_EQ(2U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011781 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011782 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000011783 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000011784 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
11785 movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
11786 0, 0, 0, 0, 0));
11787 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], cookedX2,
11788 movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
11789 0, 0, 0, 0, 0));
11790}
11791
Harry Cutts39b7ca22022-10-05 15:55:48 +000011792TEST_F(MultiTouchPointerModeTest, TwoFingerSwipeOffsets) {
Harry Cutts33476232023-01-30 19:57:29 +000011793 preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
Arpit Singha8c236b2023-04-25 13:56:05 +000011794 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Harry Cutts39b7ca22022-10-05 15:55:48 +000011795 NotifyMotionArgs motionArgs;
11796
11797 // Place two fingers down.
11798 int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125;
11799
11800 processId(mapper, FIRST_TRACKING_ID);
11801 processPosition(mapper, x1, y1);
11802 processMTSync(mapper);
11803 processId(mapper, SECOND_TRACKING_ID);
11804 processPosition(mapper, x2, y2);
11805 processMTSync(mapper);
11806 processSync(mapper);
11807
11808 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011809 ASSERT_EQ(1U, motionArgs.getPointerCount());
Harry Cutts39b7ca22022-10-05 15:55:48 +000011810 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
11811 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
11812 ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET));
11813 ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET));
11814
11815 // Move the two fingers down and to the left.
11816 int32_t movingDistance = 200;
11817 x1 -= movingDistance;
11818 y1 += movingDistance;
11819 x2 -= movingDistance;
11820 y2 += movingDistance;
11821
11822 processId(mapper, FIRST_TRACKING_ID);
11823 processPosition(mapper, x1, y1);
11824 processMTSync(mapper);
11825 processId(mapper, SECOND_TRACKING_ID);
11826 processPosition(mapper, x2, y2);
11827 processMTSync(mapper);
11828 processSync(mapper);
11829
11830 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011831 ASSERT_EQ(1U, motionArgs.getPointerCount());
Harry Cutts39b7ca22022-10-05 15:55:48 +000011832 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
11833 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
11834 ASSERT_LT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET), 0);
11835 ASSERT_GT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET), 0);
11836}
11837
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011838TEST_F(MultiTouchPointerModeTest, WhenViewportActiveStatusChanged_PointerGestureIsReset) {
Harry Cutts33476232023-01-30 19:57:29 +000011839 preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011840 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
Arpit Singha8c236b2023-04-25 13:56:05 +000011841 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011842 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
11843
11844 // Start a stylus gesture.
11845 processKey(mapper, BTN_TOOL_PEN, 1);
11846 processId(mapper, FIRST_TRACKING_ID);
11847 processPosition(mapper, 100, 200);
11848 processSync(mapper);
11849 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11850 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
11851 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011852 WithToolType(ToolType::STYLUS))));
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011853 // TODO(b/257078296): Pointer mode generates extra event.
11854 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11855 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
11856 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011857 WithToolType(ToolType::STYLUS))));
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011858 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
11859
11860 // Make the viewport inactive. This will put the device in disabled mode, and the ongoing stylus
11861 // gesture should be disabled.
11862 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
11863 viewport->isActive = false;
11864 mFakePolicy->updateViewport(*viewport);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +000011865 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011866 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11867 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
11868 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011869 WithToolType(ToolType::STYLUS))));
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011870 // TODO(b/257078296): Pointer mode generates extra event.
11871 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11872 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
11873 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011874 WithToolType(ToolType::STYLUS))));
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011875 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
11876}
11877
Arthur Hung6d5b4b22022-01-21 07:21:10 +000011878// --- JoystickInputMapperTest ---
11879
11880class JoystickInputMapperTest : public InputMapperTest {
11881protected:
11882 static const int32_t RAW_X_MIN;
11883 static const int32_t RAW_X_MAX;
11884 static const int32_t RAW_Y_MIN;
11885 static const int32_t RAW_Y_MAX;
11886
11887 void SetUp() override {
11888 InputMapperTest::SetUp(InputDeviceClass::JOYSTICK | InputDeviceClass::EXTERNAL);
11889 }
11890 void prepareAxes() {
11891 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
11892 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
11893 }
11894
11895 void processAxis(JoystickInputMapper& mapper, int32_t axis, int32_t value) {
11896 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, axis, value);
11897 }
11898
11899 void processSync(JoystickInputMapper& mapper) {
11900 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
11901 }
11902
Michael Wrighta9cf4192022-12-01 23:46:39 +000011903 void prepareVirtualDisplay(ui::Rotation orientation) {
Arthur Hung6d5b4b22022-01-21 07:21:10 +000011904 setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH,
11905 VIRTUAL_DISPLAY_HEIGHT, orientation, VIRTUAL_DISPLAY_UNIQUE_ID,
11906 NO_PORT, ViewportType::VIRTUAL);
11907 }
11908};
11909
11910const int32_t JoystickInputMapperTest::RAW_X_MIN = -32767;
11911const int32_t JoystickInputMapperTest::RAW_X_MAX = 32767;
11912const int32_t JoystickInputMapperTest::RAW_Y_MIN = -32767;
11913const int32_t JoystickInputMapperTest::RAW_Y_MAX = 32767;
11914
11915TEST_F(JoystickInputMapperTest, Configure_AssignsDisplayUniqueId) {
11916 prepareAxes();
Arpit Singhae876352023-04-26 14:16:50 +000011917 JoystickInputMapper& mapper = constructAndAddMapper<JoystickInputMapper>();
Arthur Hung6d5b4b22022-01-21 07:21:10 +000011918
11919 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
11920
Michael Wrighta9cf4192022-12-01 23:46:39 +000011921 prepareVirtualDisplay(ui::ROTATION_0);
Arthur Hung6d5b4b22022-01-21 07:21:10 +000011922
11923 // Send an axis event
11924 processAxis(mapper, ABS_X, 100);
11925 processSync(mapper);
11926
11927 NotifyMotionArgs args;
11928 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11929 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
11930
11931 // Send another axis event
11932 processAxis(mapper, ABS_Y, 100);
11933 processSync(mapper);
11934
11935 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11936 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
11937}
11938
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011939// --- PeripheralControllerTest ---
Chris Yee2b1e5c2021-03-10 22:45:12 -080011940
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011941class PeripheralControllerTest : public testing::Test {
Chris Yee2b1e5c2021-03-10 22:45:12 -080011942protected:
11943 static const char* DEVICE_NAME;
11944 static const char* DEVICE_LOCATION;
11945 static const int32_t DEVICE_ID;
11946 static const int32_t DEVICE_GENERATION;
11947 static const int32_t DEVICE_CONTROLLER_NUMBER;
Dominik Laskowski2f01d772022-03-23 16:01:29 -070011948 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
Chris Yee2b1e5c2021-03-10 22:45:12 -080011949 static const int32_t EVENTHUB_ID;
11950
11951 std::shared_ptr<FakeEventHub> mFakeEventHub;
11952 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -070011953 std::unique_ptr<TestInputListener> mFakeListener;
Chris Yee2b1e5c2021-03-10 22:45:12 -080011954 std::unique_ptr<InstrumentedInputReader> mReader;
11955 std::shared_ptr<InputDevice> mDevice;
11956
Dominik Laskowski2f01d772022-03-23 16:01:29 -070011957 virtual void SetUp(ftl::Flags<InputDeviceClass> classes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -080011958 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070011959 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -070011960 mFakeListener = std::make_unique<TestInputListener>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080011961 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -070011962 *mFakeListener);
Chris Yee2b1e5c2021-03-10 22:45:12 -080011963 mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes);
11964 }
11965
11966 void SetUp() override { SetUp(DEVICE_CLASSES); }
11967
11968 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -070011969 mFakeListener.reset();
Chris Yee2b1e5c2021-03-10 22:45:12 -080011970 mFakePolicy.clear();
11971 }
11972
Chris Yee2b1e5c2021-03-10 22:45:12 -080011973 std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
11974 const std::string& location, int32_t eventHubId,
Dominik Laskowski2f01d772022-03-23 16:01:29 -070011975 ftl::Flags<InputDeviceClass> classes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -080011976 InputDeviceIdentifier identifier;
11977 identifier.name = name;
11978 identifier.location = location;
11979 std::shared_ptr<InputDevice> device =
11980 std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
11981 identifier);
11982 mReader->pushNextDevice(device);
11983 mFakeEventHub->addDevice(eventHubId, name, classes);
11984 mReader->loopOnce();
11985 return device;
11986 }
11987
11988 template <class T, typename... Args>
11989 T& addControllerAndConfigure(Args... args) {
11990 T& controller = mDevice->addController<T>(EVENTHUB_ID, args...);
11991
11992 return controller;
11993 }
11994};
11995
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011996const char* PeripheralControllerTest::DEVICE_NAME = "device";
11997const char* PeripheralControllerTest::DEVICE_LOCATION = "BLUETOOTH";
11998const int32_t PeripheralControllerTest::DEVICE_ID = END_RESERVED_ID + 1000;
11999const int32_t PeripheralControllerTest::DEVICE_GENERATION = 2;
12000const int32_t PeripheralControllerTest::DEVICE_CONTROLLER_NUMBER = 0;
Dominik Laskowski2f01d772022-03-23 16:01:29 -070012001const ftl::Flags<InputDeviceClass> PeripheralControllerTest::DEVICE_CLASSES =
12002 ftl::Flags<InputDeviceClass>(0); // not needed for current tests
Chris Ye1dd2e5c2021-04-04 23:12:41 -070012003const int32_t PeripheralControllerTest::EVENTHUB_ID = 1;
Chris Yee2b1e5c2021-03-10 22:45:12 -080012004
12005// --- BatteryControllerTest ---
Chris Ye1dd2e5c2021-04-04 23:12:41 -070012006class BatteryControllerTest : public PeripheralControllerTest {
Chris Yee2b1e5c2021-03-10 22:45:12 -080012007protected:
12008 void SetUp() override {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070012009 PeripheralControllerTest::SetUp(DEVICE_CLASSES | InputDeviceClass::BATTERY);
Chris Yee2b1e5c2021-03-10 22:45:12 -080012010 }
12011};
12012
12013TEST_F(BatteryControllerTest, GetBatteryCapacity) {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070012014 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080012015
Harry Cuttsa5b71292022-11-28 12:56:17 +000012016 ASSERT_TRUE(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY));
12017 ASSERT_EQ(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY).value_or(-1),
12018 FakeEventHub::BATTERY_CAPACITY);
Chris Yee2b1e5c2021-03-10 22:45:12 -080012019}
12020
12021TEST_F(BatteryControllerTest, GetBatteryStatus) {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070012022 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080012023
Harry Cuttsa5b71292022-11-28 12:56:17 +000012024 ASSERT_TRUE(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY));
12025 ASSERT_EQ(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY).value_or(-1),
12026 FakeEventHub::BATTERY_STATUS);
Chris Yee2b1e5c2021-03-10 22:45:12 -080012027}
12028
12029// --- LightControllerTest ---
Chris Ye1dd2e5c2021-04-04 23:12:41 -070012030class LightControllerTest : public PeripheralControllerTest {
Chris Yee2b1e5c2021-03-10 22:45:12 -080012031protected:
Chris Ye1dd2e5c2021-04-04 23:12:41 -070012032 void SetUp() override {
12033 PeripheralControllerTest::SetUp(DEVICE_CLASSES | InputDeviceClass::LIGHT);
12034 }
Chris Yee2b1e5c2021-03-10 22:45:12 -080012035};
12036
Chris Ye85758332021-05-16 23:05:17 -070012037TEST_F(LightControllerTest, MonoLight) {
12038 RawLightInfo infoMono = {.id = 1,
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000012039 .name = "mono_light",
Chris Ye85758332021-05-16 23:05:17 -070012040 .maxBrightness = 255,
12041 .flags = InputLightClass::BRIGHTNESS,
12042 .path = ""};
12043 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
Chris Yee2b1e5c2021-03-10 22:45:12 -080012044
Chris Ye1dd2e5c2021-04-04 23:12:41 -070012045 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080012046 InputDeviceInfo info;
12047 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000012048 std::vector<InputDeviceLightInfo> lights = info.getLights();
12049 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000012050 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
12051 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
12052
12053 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_BRIGHTNESS));
12054 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
12055}
12056
12057TEST_F(LightControllerTest, MonoKeyboardBacklight) {
12058 RawLightInfo infoMono = {.id = 1,
12059 .name = "mono_keyboard_backlight",
12060 .maxBrightness = 255,
12061 .flags = InputLightClass::BRIGHTNESS |
12062 InputLightClass::KEYBOARD_BACKLIGHT,
12063 .path = ""};
12064 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
12065
12066 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
12067 InputDeviceInfo info;
12068 controller.populateDeviceInfo(&info);
12069 std::vector<InputDeviceLightInfo> lights = info.getLights();
12070 ASSERT_EQ(1U, lights.size());
12071 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
12072 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
Chris Yee2b1e5c2021-03-10 22:45:12 -080012073
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000012074 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_BRIGHTNESS));
12075 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
Chris Yee2b1e5c2021-03-10 22:45:12 -080012076}
12077
Vaibhav Devmurari16c24192023-05-04 15:20:12 +000012078TEST_F(LightControllerTest, Ignore_MonoLight_WithPreferredBacklightLevels) {
12079 RawLightInfo infoMono = {.id = 1,
12080 .name = "mono_light",
12081 .maxBrightness = 255,
12082 .flags = InputLightClass::BRIGHTNESS,
12083 .path = ""};
12084 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
12085 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "keyboard.backlight.brightnessLevels",
12086 "0,100,200");
12087
12088 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
12089 std::list<NotifyArgs> unused =
12090 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
12091 /*changes=*/{});
12092
12093 InputDeviceInfo info;
12094 controller.populateDeviceInfo(&info);
12095 std::vector<InputDeviceLightInfo> lights = info.getLights();
12096 ASSERT_EQ(1U, lights.size());
12097 ASSERT_EQ(0U, lights[0].preferredBrightnessLevels.size());
12098}
12099
12100TEST_F(LightControllerTest, KeyboardBacklight_WithNoPreferredBacklightLevels) {
12101 RawLightInfo infoMono = {.id = 1,
12102 .name = "mono_keyboard_backlight",
12103 .maxBrightness = 255,
12104 .flags = InputLightClass::BRIGHTNESS |
12105 InputLightClass::KEYBOARD_BACKLIGHT,
12106 .path = ""};
12107 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
12108
12109 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
12110 std::list<NotifyArgs> unused =
12111 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
12112 /*changes=*/{});
12113
12114 InputDeviceInfo info;
12115 controller.populateDeviceInfo(&info);
12116 std::vector<InputDeviceLightInfo> lights = info.getLights();
12117 ASSERT_EQ(1U, lights.size());
12118 ASSERT_EQ(0U, lights[0].preferredBrightnessLevels.size());
12119}
12120
12121TEST_F(LightControllerTest, KeyboardBacklight_WithPreferredBacklightLevels) {
12122 RawLightInfo infoMono = {.id = 1,
12123 .name = "mono_keyboard_backlight",
12124 .maxBrightness = 255,
12125 .flags = InputLightClass::BRIGHTNESS |
12126 InputLightClass::KEYBOARD_BACKLIGHT,
12127 .path = ""};
12128 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
12129 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "keyboard.backlight.brightnessLevels",
12130 "0,100,200");
12131
12132 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
12133 std::list<NotifyArgs> unused =
12134 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
12135 /*changes=*/{});
12136
12137 InputDeviceInfo info;
12138 controller.populateDeviceInfo(&info);
12139 std::vector<InputDeviceLightInfo> lights = info.getLights();
12140 ASSERT_EQ(1U, lights.size());
12141 ASSERT_EQ(3U, lights[0].preferredBrightnessLevels.size());
12142 std::set<BrightnessLevel>::iterator it = lights[0].preferredBrightnessLevels.begin();
12143 ASSERT_EQ(BrightnessLevel(0), *it);
12144 std::advance(it, 1);
12145 ASSERT_EQ(BrightnessLevel(100), *it);
12146 std::advance(it, 1);
12147 ASSERT_EQ(BrightnessLevel(200), *it);
12148}
12149
12150TEST_F(LightControllerTest, KeyboardBacklight_WithWrongPreferredBacklightLevels) {
12151 RawLightInfo infoMono = {.id = 1,
12152 .name = "mono_keyboard_backlight",
12153 .maxBrightness = 255,
12154 .flags = InputLightClass::BRIGHTNESS |
12155 InputLightClass::KEYBOARD_BACKLIGHT,
12156 .path = ""};
12157 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
12158 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "keyboard.backlight.brightnessLevels",
12159 "0,100,200,300,400,500");
12160
12161 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
12162 std::list<NotifyArgs> unused =
12163 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
12164 /*changes=*/{});
12165
12166 InputDeviceInfo info;
12167 controller.populateDeviceInfo(&info);
12168 std::vector<InputDeviceLightInfo> lights = info.getLights();
12169 ASSERT_EQ(1U, lights.size());
12170 ASSERT_EQ(0U, lights[0].preferredBrightnessLevels.size());
12171}
12172
Chris Yee2b1e5c2021-03-10 22:45:12 -080012173TEST_F(LightControllerTest, RGBLight) {
12174 RawLightInfo infoRed = {.id = 1,
12175 .name = "red",
12176 .maxBrightness = 255,
12177 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED,
12178 .path = ""};
12179 RawLightInfo infoGreen = {.id = 2,
12180 .name = "green",
12181 .maxBrightness = 255,
12182 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN,
12183 .path = ""};
12184 RawLightInfo infoBlue = {.id = 3,
12185 .name = "blue",
12186 .maxBrightness = 255,
12187 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE,
12188 .path = ""};
12189 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
12190 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
12191 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
12192
Chris Ye1dd2e5c2021-04-04 23:12:41 -070012193 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080012194 InputDeviceInfo info;
12195 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000012196 std::vector<InputDeviceLightInfo> lights = info.getLights();
12197 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000012198 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
12199 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
12200 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
12201
12202 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
12203 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
12204}
12205
12206TEST_F(LightControllerTest, CorrectRGBKeyboardBacklight) {
12207 RawLightInfo infoRed = {.id = 1,
12208 .name = "red_keyboard_backlight",
12209 .maxBrightness = 255,
12210 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED |
12211 InputLightClass::KEYBOARD_BACKLIGHT,
12212 .path = ""};
12213 RawLightInfo infoGreen = {.id = 2,
12214 .name = "green_keyboard_backlight",
12215 .maxBrightness = 255,
12216 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN |
12217 InputLightClass::KEYBOARD_BACKLIGHT,
12218 .path = ""};
12219 RawLightInfo infoBlue = {.id = 3,
12220 .name = "blue_keyboard_backlight",
12221 .maxBrightness = 255,
12222 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE |
12223 InputLightClass::KEYBOARD_BACKLIGHT,
12224 .path = ""};
12225 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
12226 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
12227 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
12228
12229 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
12230 InputDeviceInfo info;
12231 controller.populateDeviceInfo(&info);
12232 std::vector<InputDeviceLightInfo> lights = info.getLights();
12233 ASSERT_EQ(1U, lights.size());
12234 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
12235 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
12236 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
12237
12238 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
12239 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
12240}
12241
12242TEST_F(LightControllerTest, IncorrectRGBKeyboardBacklight) {
12243 RawLightInfo infoRed = {.id = 1,
12244 .name = "red",
12245 .maxBrightness = 255,
12246 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED,
12247 .path = ""};
12248 RawLightInfo infoGreen = {.id = 2,
12249 .name = "green",
12250 .maxBrightness = 255,
12251 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN,
12252 .path = ""};
12253 RawLightInfo infoBlue = {.id = 3,
12254 .name = "blue",
12255 .maxBrightness = 255,
12256 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE,
12257 .path = ""};
12258 RawLightInfo infoGlobal = {.id = 3,
12259 .name = "global_keyboard_backlight",
12260 .maxBrightness = 255,
12261 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GLOBAL |
12262 InputLightClass::KEYBOARD_BACKLIGHT,
12263 .path = ""};
12264 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
12265 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
12266 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
12267 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoGlobal));
12268
12269 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
12270 InputDeviceInfo info;
12271 controller.populateDeviceInfo(&info);
12272 std::vector<InputDeviceLightInfo> lights = info.getLights();
12273 ASSERT_EQ(1U, lights.size());
12274 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
12275 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
12276 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080012277
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000012278 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
12279 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
Chris Yee2b1e5c2021-03-10 22:45:12 -080012280}
12281
12282TEST_F(LightControllerTest, MultiColorRGBLight) {
12283 RawLightInfo infoColor = {.id = 1,
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000012284 .name = "multi_color",
Chris Yee2b1e5c2021-03-10 22:45:12 -080012285 .maxBrightness = 255,
12286 .flags = InputLightClass::BRIGHTNESS |
12287 InputLightClass::MULTI_INTENSITY |
12288 InputLightClass::MULTI_INDEX,
12289 .path = ""};
12290
12291 mFakeEventHub->addRawLightInfo(infoColor.id, std::move(infoColor));
12292
Chris Ye1dd2e5c2021-04-04 23:12:41 -070012293 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080012294 InputDeviceInfo info;
12295 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000012296 std::vector<InputDeviceLightInfo> lights = info.getLights();
12297 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000012298 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
12299 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
12300 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
12301
12302 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
12303 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
12304}
12305
12306TEST_F(LightControllerTest, MultiColorRGBKeyboardBacklight) {
12307 RawLightInfo infoColor = {.id = 1,
12308 .name = "multi_color_keyboard_backlight",
12309 .maxBrightness = 255,
12310 .flags = InputLightClass::BRIGHTNESS |
12311 InputLightClass::MULTI_INTENSITY |
12312 InputLightClass::MULTI_INDEX |
12313 InputLightClass::KEYBOARD_BACKLIGHT,
12314 .path = ""};
12315
12316 mFakeEventHub->addRawLightInfo(infoColor.id, std::move(infoColor));
12317
12318 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
12319 InputDeviceInfo info;
12320 controller.populateDeviceInfo(&info);
12321 std::vector<InputDeviceLightInfo> lights = info.getLights();
12322 ASSERT_EQ(1U, lights.size());
12323 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
12324 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
12325 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080012326
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000012327 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
12328 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
Chris Yee2b1e5c2021-03-10 22:45:12 -080012329}
12330
12331TEST_F(LightControllerTest, PlayerIdLight) {
12332 RawLightInfo info1 = {.id = 1,
12333 .name = "player1",
12334 .maxBrightness = 255,
12335 .flags = InputLightClass::BRIGHTNESS,
12336 .path = ""};
12337 RawLightInfo info2 = {.id = 2,
12338 .name = "player2",
12339 .maxBrightness = 255,
12340 .flags = InputLightClass::BRIGHTNESS,
12341 .path = ""};
12342 RawLightInfo info3 = {.id = 3,
12343 .name = "player3",
12344 .maxBrightness = 255,
12345 .flags = InputLightClass::BRIGHTNESS,
12346 .path = ""};
12347 RawLightInfo info4 = {.id = 4,
12348 .name = "player4",
12349 .maxBrightness = 255,
12350 .flags = InputLightClass::BRIGHTNESS,
12351 .path = ""};
12352 mFakeEventHub->addRawLightInfo(info1.id, std::move(info1));
12353 mFakeEventHub->addRawLightInfo(info2.id, std::move(info2));
12354 mFakeEventHub->addRawLightInfo(info3.id, std::move(info3));
12355 mFakeEventHub->addRawLightInfo(info4.id, std::move(info4));
12356
Chris Ye1dd2e5c2021-04-04 23:12:41 -070012357 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080012358 InputDeviceInfo info;
12359 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000012360 std::vector<InputDeviceLightInfo> lights = info.getLights();
12361 ASSERT_EQ(1U, lights.size());
12362 ASSERT_EQ(InputDeviceLightType::PLAYER_ID, lights[0].type);
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000012363 ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
12364 ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080012365
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000012366 ASSERT_FALSE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
12367 ASSERT_TRUE(controller.setLightPlayerId(lights[0].id, LIGHT_PLAYER_ID));
12368 ASSERT_EQ(controller.getLightPlayerId(lights[0].id).value_or(-1), LIGHT_PLAYER_ID);
Chris Yee2b1e5c2021-03-10 22:45:12 -080012369}
12370
Michael Wrightd02c5b62014-02-10 15:10:22 -080012371} // namespace android