blob: bce0937890a93a6be823856ee1aa6b030c6b977e [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>
34#include <TestInputListener.h>
Prabir Pradhan739dca42022-09-09 20:12:01 +000035#include <TestInputListenerMatchers.h>
Prabir Pradhan2770d242019-09-02 18:07:11 -070036#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>
Michael Wrighta9cf4192022-12-01 23:46:39 +000040#include <ftl/enum.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080041#include <gtest/gtest.h>
chaviw3277faf2021-05-19 16:45:23 -050042#include <gui/constants.h>
Michael Wrighta9cf4192022-12-01 23:46:39 +000043#include <ui/Rotation.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080044
Siarhei Vishniakou21e96e62022-10-27 10:23:37 -070045#include <thread>
Harry Cuttsa5b71292022-11-28 12:56:17 +000046#include "FakeEventHub.h"
Harry Cutts6b5fbc52022-11-28 16:37:43 +000047#include "FakeInputReaderPolicy.h"
Harry Cuttsb57f1702022-11-28 15:34:22 +000048#include "FakePointerController.h"
Harry Cuttse6512e12022-11-28 18:44:01 +000049#include "InputMapperTest.h"
Harry Cutts144ff542022-11-28 17:41:06 +000050#include "InstrumentedInputReader.h"
Harry Cuttsa5b71292022-11-28 12:56:17 +000051#include "TestConstants.h"
Michael Wrightdde67b82020-10-27 16:09:22 +000052#include "input/DisplayViewport.h"
53#include "input/Input.h"
Michael Wright17db18e2020-06-26 20:51:44 +010054
Michael Wrightd02c5b62014-02-10 15:10:22 -080055namespace android {
56
Dominik Laskowski2f01d772022-03-23 16:01:29 -070057using namespace ftl::flag_operators;
Prabir Pradhan739dca42022-09-09 20:12:01 +000058using testing::AllOf;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -070059using std::chrono_literals::operator""ms;
60
Michael Wrightd02c5b62014-02-10 15:10:22 -080061// Arbitrary display properties.
arthurhungcc7f9802020-04-30 17:55:40 +080062static constexpr int32_t DISPLAY_ID = 0;
Prabir Pradhanc13ff082022-09-08 22:03:30 +000063static const std::string DISPLAY_UNIQUE_ID = "local:1";
arthurhungcc7f9802020-04-30 17:55:40 +080064static constexpr int32_t SECONDARY_DISPLAY_ID = DISPLAY_ID + 1;
Prabir Pradhanc13ff082022-09-08 22:03:30 +000065static const std::string SECONDARY_DISPLAY_UNIQUE_ID = "local:2";
arthurhungcc7f9802020-04-30 17:55:40 +080066static constexpr int32_t DISPLAY_WIDTH = 480;
67static constexpr int32_t DISPLAY_HEIGHT = 800;
68static constexpr int32_t VIRTUAL_DISPLAY_ID = 1;
69static constexpr int32_t VIRTUAL_DISPLAY_WIDTH = 400;
70static constexpr int32_t VIRTUAL_DISPLAY_HEIGHT = 500;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -070071static const char* VIRTUAL_DISPLAY_UNIQUE_ID = "virtual:1";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -070072static constexpr std::optional<uint8_t> NO_PORT = std::nullopt; // no physical port is specified
Michael Wrightd02c5b62014-02-10 15:10:22 -080073
arthurhungcc7f9802020-04-30 17:55:40 +080074static constexpr int32_t FIRST_SLOT = 0;
75static constexpr int32_t SECOND_SLOT = 1;
76static constexpr int32_t THIRD_SLOT = 2;
77static constexpr int32_t INVALID_TRACKING_ID = -1;
78static constexpr int32_t FIRST_TRACKING_ID = 0;
79static constexpr int32_t SECOND_TRACKING_ID = 1;
80static constexpr int32_t THIRD_TRACKING_ID = 2;
Chris Ye3fdbfef2021-01-06 18:45:18 -080081static constexpr int32_t LIGHT_BRIGHTNESS = 0x55000000;
82static constexpr int32_t LIGHT_COLOR = 0x7F448866;
83static constexpr int32_t LIGHT_PLAYER_ID = 2;
arthurhungcc7f9802020-04-30 17:55:40 +080084
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080085static constexpr int32_t ACTION_POINTER_0_DOWN =
86 AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
87static constexpr int32_t ACTION_POINTER_0_UP =
88 AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
89static constexpr int32_t ACTION_POINTER_1_DOWN =
90 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
91static constexpr int32_t ACTION_POINTER_1_UP =
92 AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
93
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +000094// Minimum timestamp separation between subsequent input events from a Bluetooth device.
95static constexpr nsecs_t MIN_BLUETOOTH_TIMESTAMP_DELTA = ms2ns(4);
96// Maximum smoothing time delta so that we don't generate events too far into the future.
97constexpr static nsecs_t MAX_BLUETOOTH_SMOOTHING_DELTA = ms2ns(32);
98
Michael Wrightd02c5b62014-02-10 15:10:22 -080099template<typename T>
100static inline T min(T a, T b) {
101 return a < b ? a : b;
102}
103
104static inline float avg(float x, float y) {
105 return (x + y) / 2;
106}
107
Chris Ye3fdbfef2021-01-06 18:45:18 -0800108// Mapping for light color name and the light color
109const std::unordered_map<std::string, LightColor> LIGHT_COLORS = {{"red", LightColor::RED},
110 {"green", LightColor::GREEN},
111 {"blue", LightColor::BLUE}};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800112
Michael Wrighta9cf4192022-12-01 23:46:39 +0000113static ui::Rotation getInverseRotation(ui::Rotation orientation) {
Prabir Pradhanc14266f2021-05-12 15:56:24 -0700114 switch (orientation) {
Michael Wrighta9cf4192022-12-01 23:46:39 +0000115 case ui::ROTATION_90:
116 return ui::ROTATION_270;
117 case ui::ROTATION_270:
118 return ui::ROTATION_90;
Prabir Pradhanc14266f2021-05-12 15:56:24 -0700119 default:
120 return orientation;
121 }
122}
123
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800124static void assertAxisResolution(MultiTouchInputMapper& mapper, int axis, float resolution) {
125 InputDeviceInfo info;
Harry Cuttsd02ea102023-03-17 18:21:30 +0000126 mapper.populateDeviceInfo(info);
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800127
128 const InputDeviceInfo::MotionRange* motionRange =
129 info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
130 ASSERT_NEAR(motionRange->resolution, resolution, EPSILON);
131}
132
133static void assertAxisNotPresent(MultiTouchInputMapper& mapper, int axis) {
134 InputDeviceInfo info;
Harry Cuttsd02ea102023-03-17 18:21:30 +0000135 mapper.populateDeviceInfo(info);
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800136
137 const InputDeviceInfo::MotionRange* motionRange =
138 info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
139 ASSERT_EQ(nullptr, motionRange);
140}
141
Siarhei Vishniakou21e96e62022-10-27 10:23:37 -0700142[[maybe_unused]] static void dumpReader(InputReader& reader) {
143 std::string dump;
144 reader.dump(dump);
145 std::istringstream iss(dump);
146 for (std::string line; std::getline(iss, line);) {
147 ALOGE("%s", line.c_str());
148 std::this_thread::sleep_for(std::chrono::milliseconds(1));
149 }
150}
151
Michael Wrightd02c5b62014-02-10 15:10:22 -0800152// --- FakeInputMapper ---
153
154class FakeInputMapper : public InputMapper {
155 uint32_t mSources;
156 int32_t mKeyboardType;
157 int32_t mMetaState;
158 KeyedVector<int32_t, int32_t> mKeyCodeStates;
159 KeyedVector<int32_t, int32_t> mScanCodeStates;
160 KeyedVector<int32_t, int32_t> mSwitchStates;
Philip Junker4af3b3d2021-12-14 10:36:55 +0100161 // fake mapping which would normally come from keyCharacterMap
162 std::unordered_map<int32_t, int32_t> mKeyCodeMapping;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800163 std::vector<int32_t> mSupportedKeyCodes;
Yeabkal Wubshite03e8b12023-06-27 16:23:12 -0700164 std::list<NotifyArgs> mProcessResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800165
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700166 std::mutex mLock;
167 std::condition_variable mStateChangedCondition;
168 bool mConfigureWasCalled GUARDED_BY(mLock);
169 bool mResetWasCalled GUARDED_BY(mLock);
170 bool mProcessWasCalled GUARDED_BY(mLock);
171 RawEvent mLastEvent GUARDED_BY(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800172
Arthur Hungc23540e2018-11-29 20:42:11 +0800173 std::optional<DisplayViewport> mViewport;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800174public:
Arpit Singh8e6fb252023-04-06 11:49:17 +0000175 FakeInputMapper(InputDeviceContext& deviceContext, const InputReaderConfiguration& readerConfig,
176 uint32_t sources)
177 : InputMapper(deviceContext, readerConfig),
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800178 mSources(sources),
179 mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
Michael Wrightd02c5b62014-02-10 15:10:22 -0800180 mMetaState(0),
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800181 mConfigureWasCalled(false),
182 mResetWasCalled(false),
183 mProcessWasCalled(false) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800184
Chris Yea52ade12020-08-27 16:49:20 -0700185 virtual ~FakeInputMapper() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800186
187 void setKeyboardType(int32_t keyboardType) {
188 mKeyboardType = keyboardType;
189 }
190
191 void setMetaState(int32_t metaState) {
192 mMetaState = metaState;
193 }
194
Yeabkal Wubshite03e8b12023-06-27 16:23:12 -0700195 // Sets the return value for the `process` call.
196 void setProcessResult(std::list<NotifyArgs> notifyArgs) {
197 mProcessResult.clear();
198 for (auto notifyArg : notifyArgs) {
199 mProcessResult.push_back(notifyArg);
200 }
201 }
202
Michael Wrightd02c5b62014-02-10 15:10:22 -0800203 void assertConfigureWasCalled() {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700204 std::unique_lock<std::mutex> lock(mLock);
205 base::ScopedLockAssertion assumeLocked(mLock);
206 const bool configureCalled =
207 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
208 return mConfigureWasCalled;
209 });
210 if (!configureCalled) {
211 FAIL() << "Expected configure() to have been called.";
212 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800213 mConfigureWasCalled = false;
214 }
215
216 void assertResetWasCalled() {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700217 std::unique_lock<std::mutex> lock(mLock);
218 base::ScopedLockAssertion assumeLocked(mLock);
219 const bool resetCalled =
220 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
221 return mResetWasCalled;
222 });
223 if (!resetCalled) {
224 FAIL() << "Expected reset() to have been called.";
225 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800226 mResetWasCalled = false;
227 }
228
Yi Kong9b14ac62018-07-17 13:48:38 -0700229 void assertProcessWasCalled(RawEvent* outLastEvent = nullptr) {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700230 std::unique_lock<std::mutex> lock(mLock);
231 base::ScopedLockAssertion assumeLocked(mLock);
232 const bool processCalled =
233 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
234 return mProcessWasCalled;
235 });
236 if (!processCalled) {
237 FAIL() << "Expected process() to have been called.";
238 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800239 if (outLastEvent) {
240 *outLastEvent = mLastEvent;
241 }
242 mProcessWasCalled = false;
243 }
244
245 void setKeyCodeState(int32_t keyCode, int32_t state) {
246 mKeyCodeStates.replaceValueFor(keyCode, state);
247 }
248
249 void setScanCodeState(int32_t scanCode, int32_t state) {
250 mScanCodeStates.replaceValueFor(scanCode, state);
251 }
252
253 void setSwitchState(int32_t switchCode, int32_t state) {
254 mSwitchStates.replaceValueFor(switchCode, state);
255 }
256
257 void addSupportedKeyCode(int32_t keyCode) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800258 mSupportedKeyCodes.push_back(keyCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800259 }
260
Philip Junker4af3b3d2021-12-14 10:36:55 +0100261 void addKeyCodeMapping(int32_t fromKeyCode, int32_t toKeyCode) {
262 mKeyCodeMapping.insert_or_assign(fromKeyCode, toKeyCode);
263 }
264
Michael Wrightd02c5b62014-02-10 15:10:22 -0800265private:
Philip Junker4af3b3d2021-12-14 10:36:55 +0100266 uint32_t getSources() const override { return mSources; }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800267
Harry Cuttsd02ea102023-03-17 18:21:30 +0000268 void populateDeviceInfo(InputDeviceInfo& deviceInfo) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800269 InputMapper::populateDeviceInfo(deviceInfo);
270
271 if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) {
Harry Cuttsd02ea102023-03-17 18:21:30 +0000272 deviceInfo.setKeyboardType(mKeyboardType);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800273 }
274 }
275
Arpit Singhed6c3de2023-04-05 19:24:37 +0000276 std::list<NotifyArgs> reconfigure(nsecs_t, const InputReaderConfiguration& config,
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000277 ConfigurationChanges changes) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700278 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800279 mConfigureWasCalled = true;
Arthur Hungc23540e2018-11-29 20:42:11 +0800280
281 // Find the associated viewport if exist.
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800282 const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000283 if (displayPort && changes.test(InputReaderConfiguration::Change::DISPLAY_INFO)) {
Arpit Singhed6c3de2023-04-05 19:24:37 +0000284 mViewport = config.getDisplayViewportByPort(*displayPort);
Arthur Hungc23540e2018-11-29 20:42:11 +0800285 }
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700286
287 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700288 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800289 }
290
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700291 std::list<NotifyArgs> reset(nsecs_t) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700292 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800293 mResetWasCalled = true;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700294 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700295 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800296 }
297
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700298 std::list<NotifyArgs> process(const RawEvent* rawEvent) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700299 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800300 mLastEvent = *rawEvent;
301 mProcessWasCalled = true;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700302 mStateChangedCondition.notify_all();
Yeabkal Wubshite03e8b12023-06-27 16:23:12 -0700303 return mProcessResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800304 }
305
Chris Yea52ade12020-08-27 16:49:20 -0700306 int32_t getKeyCodeState(uint32_t, int32_t keyCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800307 ssize_t index = mKeyCodeStates.indexOfKey(keyCode);
308 return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
309 }
310
Philip Junker4af3b3d2021-12-14 10:36:55 +0100311 int32_t getKeyCodeForKeyLocation(int32_t locationKeyCode) const override {
312 auto it = mKeyCodeMapping.find(locationKeyCode);
313 return it != mKeyCodeMapping.end() ? it->second : locationKeyCode;
314 }
315
Chris Yea52ade12020-08-27 16:49:20 -0700316 int32_t getScanCodeState(uint32_t, int32_t scanCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800317 ssize_t index = mScanCodeStates.indexOfKey(scanCode);
318 return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
319 }
320
Chris Yea52ade12020-08-27 16:49:20 -0700321 int32_t getSwitchState(uint32_t, int32_t switchCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800322 ssize_t index = mSwitchStates.indexOfKey(switchCode);
323 return index >= 0 ? mSwitchStates.valueAt(index) : AKEY_STATE_UNKNOWN;
324 }
325
Chris Yea52ade12020-08-27 16:49:20 -0700326 // Return true if the device has non-empty key layout.
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700327 bool markSupportedKeyCodes(uint32_t, const std::vector<int32_t>& keyCodes,
Chris Yea52ade12020-08-27 16:49:20 -0700328 uint8_t* outFlags) override {
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700329 for (size_t i = 0; i < keyCodes.size(); i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800330 for (size_t j = 0; j < mSupportedKeyCodes.size(); j++) {
331 if (keyCodes[i] == mSupportedKeyCodes[j]) {
332 outFlags[i] = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800333 }
334 }
335 }
Chris Yea52ade12020-08-27 16:49:20 -0700336 bool result = mSupportedKeyCodes.size() > 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800337 return result;
338 }
339
340 virtual int32_t getMetaState() {
341 return mMetaState;
342 }
343
344 virtual void fadePointer() {
345 }
Arthur Hungc23540e2018-11-29 20:42:11 +0800346
347 virtual std::optional<int32_t> getAssociatedDisplay() {
348 if (mViewport) {
349 return std::make_optional(mViewport->displayId);
350 }
351 return std::nullopt;
352 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800353};
354
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700355// --- InputReaderPolicyTest ---
356class InputReaderPolicyTest : public testing::Test {
Siarhei Vishniakoucd7ac1e2018-10-15 13:39:50 -0700357protected:
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700358 sp<FakeInputReaderPolicy> mFakePolicy;
359
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700360 void SetUp() override { mFakePolicy = sp<FakeInputReaderPolicy>::make(); }
Chris Yea52ade12020-08-27 16:49:20 -0700361 void TearDown() override { mFakePolicy.clear(); }
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700362};
363
364/**
365 * Check that empty set of viewports is an acceptable configuration.
366 * Also try to get internal viewport two different ways - by type and by uniqueId.
367 *
368 * There will be confusion if two viewports with empty uniqueId and identical type are present.
369 * Such configuration is not currently allowed.
370 */
371TEST_F(InputReaderPolicyTest, Viewports_GetCleared) {
Siarhei Vishniakoucd7ac1e2018-10-15 13:39:50 -0700372 static const std::string uniqueId = "local:0";
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700373
374 // We didn't add any viewports yet, so there shouldn't be any.
375 std::optional<DisplayViewport> internalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100376 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700377 ASSERT_FALSE(internalViewport);
378
379 // Add an internal viewport, then clear it
Michael Wrighta9cf4192022-12-01 23:46:39 +0000380 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +0000381 /*isActive=*/true, uniqueId, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700382
383 // Check matching by uniqueId
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700384 internalViewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700385 ASSERT_TRUE(internalViewport);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100386 ASSERT_EQ(ViewportType::INTERNAL, internalViewport->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700387
388 // Check matching by viewport type
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100389 internalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700390 ASSERT_TRUE(internalViewport);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700391 ASSERT_EQ(uniqueId, internalViewport->uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700392
393 mFakePolicy->clearViewports();
394 // Make sure nothing is found after clear
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700395 internalViewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700396 ASSERT_FALSE(internalViewport);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100397 internalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700398 ASSERT_FALSE(internalViewport);
399}
400
401TEST_F(InputReaderPolicyTest, Viewports_GetByType) {
402 const std::string internalUniqueId = "local:0";
403 const std::string externalUniqueId = "local:1";
404 const std::string virtualUniqueId1 = "virtual:2";
405 const std::string virtualUniqueId2 = "virtual:3";
406 constexpr int32_t virtualDisplayId1 = 2;
407 constexpr int32_t virtualDisplayId2 = 3;
408
409 // Add an internal viewport
Michael Wrighta9cf4192022-12-01 23:46:39 +0000410 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +0000411 /*isActive=*/true, internalUniqueId, NO_PORT,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000412 ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700413 // Add an external viewport
Michael Wrighta9cf4192022-12-01 23:46:39 +0000414 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +0000415 /*isActive=*/true, externalUniqueId, NO_PORT,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000416 ViewportType::EXTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700417 // Add an virtual viewport
418 mFakePolicy->addDisplayViewport(virtualDisplayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +0000419 ui::ROTATION_0, /*isActive=*/true, virtualUniqueId1, NO_PORT,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000420 ViewportType::VIRTUAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700421 // Add another virtual viewport
422 mFakePolicy->addDisplayViewport(virtualDisplayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +0000423 ui::ROTATION_0, /*isActive=*/true, virtualUniqueId2, NO_PORT,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000424 ViewportType::VIRTUAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700425
426 // Check matching by type for internal
427 std::optional<DisplayViewport> internalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100428 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700429 ASSERT_TRUE(internalViewport);
430 ASSERT_EQ(internalUniqueId, internalViewport->uniqueId);
431
432 // Check matching by type for external
433 std::optional<DisplayViewport> externalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100434 mFakePolicy->getDisplayViewportByType(ViewportType::EXTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700435 ASSERT_TRUE(externalViewport);
436 ASSERT_EQ(externalUniqueId, externalViewport->uniqueId);
437
438 // Check matching by uniqueId for virtual viewport #1
439 std::optional<DisplayViewport> virtualViewport1 =
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700440 mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId1);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700441 ASSERT_TRUE(virtualViewport1);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100442 ASSERT_EQ(ViewportType::VIRTUAL, virtualViewport1->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700443 ASSERT_EQ(virtualUniqueId1, virtualViewport1->uniqueId);
444 ASSERT_EQ(virtualDisplayId1, virtualViewport1->displayId);
445
446 // Check matching by uniqueId for virtual viewport #2
447 std::optional<DisplayViewport> virtualViewport2 =
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700448 mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId2);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700449 ASSERT_TRUE(virtualViewport2);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100450 ASSERT_EQ(ViewportType::VIRTUAL, virtualViewport2->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700451 ASSERT_EQ(virtualUniqueId2, virtualViewport2->uniqueId);
452 ASSERT_EQ(virtualDisplayId2, virtualViewport2->displayId);
453}
454
455
456/**
457 * We can have 2 viewports of the same kind. We can distinguish them by uniqueId, and confirm
458 * that lookup works by checking display id.
459 * Check that 2 viewports of each kind is possible, for all existing viewport types.
460 */
461TEST_F(InputReaderPolicyTest, Viewports_TwoOfSameType) {
462 const std::string uniqueId1 = "uniqueId1";
463 const std::string uniqueId2 = "uniqueId2";
464 constexpr int32_t displayId1 = 2;
465 constexpr int32_t displayId2 = 3;
466
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100467 std::vector<ViewportType> types = {ViewportType::INTERNAL, ViewportType::EXTERNAL,
468 ViewportType::VIRTUAL};
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700469 for (const ViewportType& type : types) {
470 mFakePolicy->clearViewports();
471 // Add a viewport
Michael Wrighta9cf4192022-12-01 23:46:39 +0000472 mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +0000473 /*isActive=*/true, uniqueId1, NO_PORT, type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700474 // Add another viewport
Michael Wrighta9cf4192022-12-01 23:46:39 +0000475 mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +0000476 /*isActive=*/true, uniqueId2, NO_PORT, type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700477
478 // Check that correct display viewport was returned by comparing the display IDs.
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700479 std::optional<DisplayViewport> viewport1 =
480 mFakePolicy->getDisplayViewportByUniqueId(uniqueId1);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700481 ASSERT_TRUE(viewport1);
482 ASSERT_EQ(displayId1, viewport1->displayId);
483 ASSERT_EQ(type, viewport1->type);
484
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700485 std::optional<DisplayViewport> viewport2 =
486 mFakePolicy->getDisplayViewportByUniqueId(uniqueId2);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700487 ASSERT_TRUE(viewport2);
488 ASSERT_EQ(displayId2, viewport2->displayId);
489 ASSERT_EQ(type, viewport2->type);
490
491 // When there are multiple viewports of the same kind, and uniqueId is not specified
492 // in the call to getDisplayViewport, then that situation is not supported.
493 // The viewports can be stored in any order, so we cannot rely on the order, since that
494 // is just implementation detail.
495 // However, we can check that it still returns *a* viewport, we just cannot assert
496 // which one specifically is returned.
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700497 std::optional<DisplayViewport> someViewport = mFakePolicy->getDisplayViewportByType(type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700498 ASSERT_TRUE(someViewport);
499 }
500}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800501
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700502/**
Michael Wrightdde67b82020-10-27 16:09:22 +0000503 * When we have multiple internal displays make sure we always return the default display when
504 * querying by type.
505 */
506TEST_F(InputReaderPolicyTest, Viewports_ByTypeReturnsDefaultForInternal) {
507 const std::string uniqueId1 = "uniqueId1";
508 const std::string uniqueId2 = "uniqueId2";
509 constexpr int32_t nonDefaultDisplayId = 2;
510 static_assert(nonDefaultDisplayId != ADISPLAY_ID_DEFAULT,
511 "Test display ID should not be ADISPLAY_ID_DEFAULT");
512
513 // Add the default display first and ensure it gets returned.
514 mFakePolicy->clearViewports();
515 mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +0000516 ui::ROTATION_0, /*isActive=*/true, uniqueId1, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000517 ViewportType::INTERNAL);
518 mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +0000519 ui::ROTATION_0, /*isActive=*/true, uniqueId2, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000520 ViewportType::INTERNAL);
521
522 std::optional<DisplayViewport> viewport =
523 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
524 ASSERT_TRUE(viewport);
525 ASSERT_EQ(ADISPLAY_ID_DEFAULT, viewport->displayId);
526 ASSERT_EQ(ViewportType::INTERNAL, viewport->type);
527
528 // Add the default display second to make sure order doesn't matter.
529 mFakePolicy->clearViewports();
530 mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +0000531 ui::ROTATION_0, /*isActive=*/true, uniqueId2, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000532 ViewportType::INTERNAL);
533 mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +0000534 ui::ROTATION_0, /*isActive=*/true, uniqueId1, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000535 ViewportType::INTERNAL);
536
537 viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
538 ASSERT_TRUE(viewport);
539 ASSERT_EQ(ADISPLAY_ID_DEFAULT, viewport->displayId);
540 ASSERT_EQ(ViewportType::INTERNAL, viewport->type);
541}
542
543/**
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700544 * Check getDisplayViewportByPort
545 */
546TEST_F(InputReaderPolicyTest, Viewports_GetByPort) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100547 constexpr ViewportType type = ViewportType::EXTERNAL;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700548 const std::string uniqueId1 = "uniqueId1";
549 const std::string uniqueId2 = "uniqueId2";
550 constexpr int32_t displayId1 = 1;
551 constexpr int32_t displayId2 = 2;
552 const uint8_t hdmi1 = 0;
553 const uint8_t hdmi2 = 1;
554 const uint8_t hdmi3 = 2;
555
556 mFakePolicy->clearViewports();
557 // Add a viewport that's associated with some display port that's not of interest.
Michael Wrighta9cf4192022-12-01 23:46:39 +0000558 mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +0000559 /*isActive=*/true, uniqueId1, hdmi3, type);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700560 // Add another viewport, connected to HDMI1 port
Michael Wrighta9cf4192022-12-01 23:46:39 +0000561 mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +0000562 /*isActive=*/true, uniqueId2, hdmi1, type);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700563
564 // Check that correct display viewport was returned by comparing the display ports.
565 std::optional<DisplayViewport> hdmi1Viewport = mFakePolicy->getDisplayViewportByPort(hdmi1);
566 ASSERT_TRUE(hdmi1Viewport);
567 ASSERT_EQ(displayId2, hdmi1Viewport->displayId);
568 ASSERT_EQ(uniqueId2, hdmi1Viewport->uniqueId);
569
570 // Check that we can still get the same viewport using the uniqueId
571 hdmi1Viewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId2);
572 ASSERT_TRUE(hdmi1Viewport);
573 ASSERT_EQ(displayId2, hdmi1Viewport->displayId);
574 ASSERT_EQ(uniqueId2, hdmi1Viewport->uniqueId);
575 ASSERT_EQ(type, hdmi1Viewport->type);
576
577 // Check that we cannot find a port with "HDMI2", because we never added one
578 std::optional<DisplayViewport> hdmi2Viewport = mFakePolicy->getDisplayViewportByPort(hdmi2);
579 ASSERT_FALSE(hdmi2Viewport);
580}
581
Michael Wrightd02c5b62014-02-10 15:10:22 -0800582// --- InputReaderTest ---
583
584class InputReaderTest : public testing::Test {
585protected:
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700586 std::unique_ptr<TestInputListener> mFakeListener;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800587 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -0700588 std::shared_ptr<FakeEventHub> mFakeEventHub;
Prabir Pradhan28efc192019-11-05 01:10:04 +0000589 std::unique_ptr<InstrumentedInputReader> mReader;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800590
Chris Yea52ade12020-08-27 16:49:20 -0700591 void SetUp() override {
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -0700592 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700593 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700594 mFakeListener = std::make_unique<TestInputListener>();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800595
Prabir Pradhan28efc192019-11-05 01:10:04 +0000596 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700597 *mFakeListener);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800598 }
599
Chris Yea52ade12020-08-27 16:49:20 -0700600 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700601 mFakeListener.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800602 mFakePolicy.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800603 }
604
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700605 void addDevice(int32_t eventHubId, const std::string& name,
606 ftl::Flags<InputDeviceClass> classes, const PropertyMap* configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800607 mFakeEventHub->addDevice(eventHubId, name, classes);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800608
609 if (configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800610 mFakeEventHub->addConfigurationMap(eventHubId, configuration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800611 }
612 mFakeEventHub->finishDeviceScan();
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000613 mReader->loopOnce();
614 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700615 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
Prabir Pradhane3da4bb2023-04-05 23:51:23 +0000616 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyInputDevicesChangedWasCalled());
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700617 ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800618 }
619
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800620 void disableDevice(int32_t deviceId) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700621 mFakePolicy->addDisabledDevice(deviceId);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000622 mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::ENABLED_STATE);
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700623 }
624
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800625 void enableDevice(int32_t deviceId) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700626 mFakePolicy->removeDisabledDevice(deviceId);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000627 mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::ENABLED_STATE);
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700628 }
629
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800630 FakeInputMapper& addDeviceWithFakeInputMapper(int32_t deviceId, int32_t eventHubId,
Chris Ye1b0c7342020-07-28 21:57:03 -0700631 const std::string& name,
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700632 ftl::Flags<InputDeviceClass> classes,
633 uint32_t sources,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800634 const PropertyMap* configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800635 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, name);
Arpit Singh8e6fb252023-04-06 11:49:17 +0000636 FakeInputMapper& mapper =
637 device->addMapper<FakeInputMapper>(eventHubId,
638 mFakePolicy->getReaderConfiguration(), sources);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800639 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800640 addDevice(eventHubId, name, classes, configuration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800641 return mapper;
642 }
643};
644
Chris Ye98d3f532020-10-01 21:48:59 -0700645TEST_F(InputReaderTest, PolicyGetInputDevices) {
646 ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr));
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700647 ASSERT_NO_FATAL_FAILURE(addDevice(2, "ignored", ftl::Flags<InputDeviceClass>(0),
Chris Ye98d3f532020-10-01 21:48:59 -0700648 nullptr)); // no classes so device will be ignored
Michael Wrightd02c5b62014-02-10 15:10:22 -0800649
650 // Should also have received a notification describing the new input devices.
Chris Ye98d3f532020-10-01 21:48:59 -0700651 const std::vector<InputDeviceInfo>& inputDevices = mFakePolicy->getInputDevices();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800652 ASSERT_EQ(1U, inputDevices.size());
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800653 ASSERT_EQ(END_RESERVED_ID + 1, inputDevices[0].getId());
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100654 ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800655 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
656 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
Siarhei Vishniakou1983a712021-06-04 19:27:09 +0000657 ASSERT_EQ(0U, inputDevices[0].getMotionRanges().size());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800658}
659
Vaibhav Devmurari5fc7d852023-03-17 18:43:33 +0000660TEST_F(InputReaderTest, InputDeviceRecreatedOnSysfsNodeChanged) {
661 ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr));
662 mFakeEventHub->setSysfsRootPath(1, "xyz");
663
664 // Should also have received a notification describing the new input device.
665 ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
666 InputDeviceInfo inputDevice = mFakePolicy->getInputDevices()[0];
667 ASSERT_EQ(0U, inputDevice.getLights().size());
668
669 RawLightInfo infoMonolight = {.id = 123,
670 .name = "mono_keyboard_backlight",
671 .maxBrightness = 255,
672 .flags = InputLightClass::BRIGHTNESS,
673 .path = ""};
674 mFakeEventHub->addRawLightInfo(/*rawId=*/123, std::move(infoMonolight));
675 mReader->sysfsNodeChanged("xyz");
676 mReader->loopOnce();
677
678 // Should also have received a notification describing the new recreated input device.
679 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
680 inputDevice = mFakePolicy->getInputDevices()[0];
681 ASSERT_EQ(1U, inputDevice.getLights().size());
682}
683
Chris Yee7310032020-09-22 15:36:28 -0700684TEST_F(InputReaderTest, GetMergedInputDevices) {
685 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
686 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
687 // Add two subdevices to device
688 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
689 // Must add at least one mapper or the device will be ignored!
Arpit Singh8e6fb252023-04-06 11:49:17 +0000690 device->addMapper<FakeInputMapper>(eventHubIds[0], mFakePolicy->getReaderConfiguration(),
691 AINPUT_SOURCE_KEYBOARD);
692 device->addMapper<FakeInputMapper>(eventHubIds[1], mFakePolicy->getReaderConfiguration(),
693 AINPUT_SOURCE_KEYBOARD);
Chris Yee7310032020-09-22 15:36:28 -0700694
695 // Push same device instance for next device to be added, so they'll have same identifier.
696 mReader->pushNextDevice(device);
697 mReader->pushNextDevice(device);
698 ASSERT_NO_FATAL_FAILURE(
699 addDevice(eventHubIds[0], "fake1", InputDeviceClass::KEYBOARD, nullptr));
700 ASSERT_NO_FATAL_FAILURE(
701 addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
702
703 // Two devices will be merged to one input device as they have same identifier
Siarhei Vishniakou1983a712021-06-04 19:27:09 +0000704 ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
Chris Yee7310032020-09-22 15:36:28 -0700705}
706
Chris Yee14523a2020-12-19 13:46:00 -0800707TEST_F(InputReaderTest, GetMergedInputDevicesEnabled) {
708 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
709 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
710 // Add two subdevices to device
711 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
712 // Must add at least one mapper or the device will be ignored!
Arpit Singh8e6fb252023-04-06 11:49:17 +0000713 device->addMapper<FakeInputMapper>(eventHubIds[0], mFakePolicy->getReaderConfiguration(),
714 AINPUT_SOURCE_KEYBOARD);
715 device->addMapper<FakeInputMapper>(eventHubIds[1], mFakePolicy->getReaderConfiguration(),
716 AINPUT_SOURCE_KEYBOARD);
Chris Yee14523a2020-12-19 13:46:00 -0800717
718 // Push same device instance for next device to be added, so they'll have same identifier.
719 mReader->pushNextDevice(device);
720 mReader->pushNextDevice(device);
721 // Sensor device is initially disabled
722 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1",
723 InputDeviceClass::KEYBOARD | InputDeviceClass::SENSOR,
724 nullptr));
725 // Device is disabled because the only sub device is a sensor device and disabled initially.
726 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
727 ASSERT_FALSE(device->isEnabled());
728 ASSERT_NO_FATAL_FAILURE(
729 addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
730 // The merged device is enabled if any sub device is enabled
731 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
732 ASSERT_TRUE(device->isEnabled());
733}
734
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700735TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800736 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700737 constexpr ftl::Flags<InputDeviceClass> deviceClass(InputDeviceClass::KEYBOARD);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800738 constexpr int32_t eventHubId = 1;
739 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700740 // Must add at least one mapper or the device will be ignored!
Arpit Singh8e6fb252023-04-06 11:49:17 +0000741 device->addMapper<FakeInputMapper>(eventHubId, mFakePolicy->getReaderConfiguration(),
742 AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800743 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800744 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700745
Yi Kong9b14ac62018-07-17 13:48:38 -0700746 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700747
748 NotifyDeviceResetArgs resetArgs;
749 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700750 ASSERT_EQ(deviceId, resetArgs.deviceId);
751
752 ASSERT_EQ(device->isEnabled(), true);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800753 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000754 mReader->loopOnce();
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700755
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700756 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700757 ASSERT_EQ(deviceId, resetArgs.deviceId);
758 ASSERT_EQ(device->isEnabled(), false);
759
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800760 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000761 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700762 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
763 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasNotCalled());
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700764 ASSERT_EQ(device->isEnabled(), false);
765
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800766 enableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000767 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700768 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700769 ASSERT_EQ(deviceId, resetArgs.deviceId);
770 ASSERT_EQ(device->isEnabled(), true);
771}
772
Michael Wrightd02c5b62014-02-10 15:10:22 -0800773TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800774 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700775 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800776 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800777 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800778 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800779 AINPUT_SOURCE_KEYBOARD, nullptr);
780 mapper.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800781
782 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(0,
783 AINPUT_SOURCE_ANY, AKEYCODE_A))
784 << "Should return unknown when the device id is >= 0 but unknown.";
785
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800786 ASSERT_EQ(AKEY_STATE_UNKNOWN,
787 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
788 << "Should return unknown when the device id is valid but the sources are not "
789 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800790
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800791 ASSERT_EQ(AKEY_STATE_DOWN,
792 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
793 AKEYCODE_A))
794 << "Should return value provided by mapper when device id is valid and the device "
795 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800796
797 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(-1,
798 AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
799 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
800
801 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(-1,
802 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
803 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
804}
805
Philip Junker4af3b3d2021-12-14 10:36:55 +0100806TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_ForwardsRequestsToMappers) {
807 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
808 constexpr int32_t eventHubId = 1;
809 FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "keyboard",
810 InputDeviceClass::KEYBOARD,
811 AINPUT_SOURCE_KEYBOARD, nullptr);
812 mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
813
814 ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(0, AKEYCODE_Y))
815 << "Should return unknown when the device with the specified id is not found.";
816
817 ASSERT_EQ(AKEYCODE_Z, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
818 << "Should return correct mapping when device id is valid and mapping exists.";
819
820 ASSERT_EQ(AKEYCODE_A, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_A))
821 << "Should return the location key code when device id is valid and there's no "
822 "mapping.";
823}
824
825TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_NoKeyboardMapper) {
826 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
827 constexpr int32_t eventHubId = 1;
828 FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "joystick",
829 InputDeviceClass::JOYSTICK,
830 AINPUT_SOURCE_GAMEPAD, nullptr);
831 mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
832
833 ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
834 << "Should return unknown when the device id is valid but there is no keyboard mapper";
835}
836
Michael Wrightd02c5b62014-02-10 15:10:22 -0800837TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800838 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700839 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800840 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800841 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800842 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800843 AINPUT_SOURCE_KEYBOARD, nullptr);
844 mapper.setScanCodeState(KEY_A, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800845
846 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(0,
847 AINPUT_SOURCE_ANY, KEY_A))
848 << "Should return unknown when the device id is >= 0 but unknown.";
849
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800850 ASSERT_EQ(AKEY_STATE_UNKNOWN,
851 mReader->getScanCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, KEY_A))
852 << "Should return unknown when the device id is valid but the sources are not "
853 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800854
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800855 ASSERT_EQ(AKEY_STATE_DOWN,
856 mReader->getScanCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
857 KEY_A))
858 << "Should return value provided by mapper when device id is valid and the device "
859 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800860
861 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(-1,
862 AINPUT_SOURCE_TRACKBALL, KEY_A))
863 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
864
865 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(-1,
866 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
867 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
868}
869
870TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800871 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700872 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800873 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800874 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800875 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800876 AINPUT_SOURCE_KEYBOARD, nullptr);
877 mapper.setSwitchState(SW_LID, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800878
879 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(0,
880 AINPUT_SOURCE_ANY, SW_LID))
881 << "Should return unknown when the device id is >= 0 but unknown.";
882
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800883 ASSERT_EQ(AKEY_STATE_UNKNOWN,
884 mReader->getSwitchState(deviceId, AINPUT_SOURCE_TRACKBALL, SW_LID))
885 << "Should return unknown when the device id is valid but the sources are not "
886 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800887
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800888 ASSERT_EQ(AKEY_STATE_DOWN,
889 mReader->getSwitchState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
890 SW_LID))
891 << "Should return value provided by mapper when device id is valid and the device "
892 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800893
894 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(-1,
895 AINPUT_SOURCE_TRACKBALL, SW_LID))
896 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
897
898 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(-1,
899 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
900 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
901}
902
903TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800904 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700905 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800906 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800907 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800908 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800909 AINPUT_SOURCE_KEYBOARD, nullptr);
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100910
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800911 mapper.addSupportedKeyCode(AKEYCODE_A);
912 mapper.addSupportedKeyCode(AKEYCODE_B);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800913
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700914 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800915 uint8_t flags[4] = { 0, 0, 0, 1 };
916
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700917 ASSERT_FALSE(mReader->hasKeys(0, AINPUT_SOURCE_ANY, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800918 << "Should return false when device id is >= 0 but unknown.";
919 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
920
921 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700922 ASSERT_FALSE(mReader->hasKeys(deviceId, AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800923 << "Should return false when device id is valid but the sources are not supported by "
924 "the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800925 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
926
927 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700928 ASSERT_TRUE(mReader->hasKeys(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800929 keyCodes, flags))
930 << "Should return value provided by mapper when device id is valid and the device "
931 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800932 ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
933
934 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700935 ASSERT_FALSE(mReader->hasKeys(-1, AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
936 << "Should return false when the device id is < 0 but the sources are not supported by "
937 "any device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800938 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
939
940 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700941 ASSERT_TRUE(
942 mReader->hasKeys(-1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
943 << "Should return value provided by mapper when device id is < 0 and one of the "
944 "devices supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800945 ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
946}
947
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000948TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800949 constexpr int32_t eventHubId = 1;
Chris Ye1b0c7342020-07-28 21:57:03 -0700950 addDevice(eventHubId, "ignored", InputDeviceClass::KEYBOARD, nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800951
952 NotifyConfigurationChangedArgs args;
953
954 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(&args));
955 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
956}
957
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000958TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800959 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700960 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000961 constexpr nsecs_t when = 0;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800962 constexpr int32_t eventHubId = 1;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000963 constexpr nsecs_t readTime = 2;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800964 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800965 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800966 AINPUT_SOURCE_KEYBOARD, nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800967
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000968 mFakeEventHub->enqueueEvent(when, readTime, eventHubId, EV_KEY, KEY_A, 1);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000969 mReader->loopOnce();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800970 ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
971
972 RawEvent event;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800973 ASSERT_NO_FATAL_FAILURE(mapper.assertProcessWasCalled(&event));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000974 ASSERT_EQ(when, event.when);
975 ASSERT_EQ(readTime, event.readTime);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800976 ASSERT_EQ(eventHubId, event.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800977 ASSERT_EQ(EV_KEY, event.type);
978 ASSERT_EQ(KEY_A, event.code);
979 ASSERT_EQ(1, event.value);
980}
981
Garfield Tan1c7bc862020-01-28 13:24:04 -0800982TEST_F(InputReaderTest, DeviceReset_RandomId) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800983 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700984 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800985 constexpr int32_t eventHubId = 1;
986 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
Prabir Pradhan42611e02018-11-27 14:04:02 -0800987 // Must add at least one mapper or the device will be ignored!
Arpit Singh8e6fb252023-04-06 11:49:17 +0000988 device->addMapper<FakeInputMapper>(eventHubId, mFakePolicy->getReaderConfiguration(),
989 AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800990 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800991 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Prabir Pradhan42611e02018-11-27 14:04:02 -0800992
993 NotifyDeviceResetArgs resetArgs;
994 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800995 int32_t prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -0800996
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800997 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000998 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700999 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -08001000 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001001 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08001002
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001003 enableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001004 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001005 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -08001006 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001007 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08001008
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001009 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001010 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001011 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -08001012 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001013 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -08001014}
1015
Garfield Tan1c7bc862020-01-28 13:24:04 -08001016TEST_F(InputReaderTest, DeviceReset_GenerateIdWithInputReaderSource) {
1017 constexpr int32_t deviceId = 1;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001018 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Garfield Tan1c7bc862020-01-28 13:24:04 -08001019 constexpr int32_t eventHubId = 1;
1020 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1021 // Must add at least one mapper or the device will be ignored!
Arpit Singh8e6fb252023-04-06 11:49:17 +00001022 device->addMapper<FakeInputMapper>(eventHubId, mFakePolicy->getReaderConfiguration(),
1023 AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001024 mReader->pushNextDevice(device);
Garfield Tan1c7bc862020-01-28 13:24:04 -08001025 ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr));
1026
1027 NotifyDeviceResetArgs resetArgs;
1028 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1029 ASSERT_EQ(IdGenerator::Source::INPUT_READER, IdGenerator::getSource(resetArgs.id));
1030}
1031
Arthur Hungc23540e2018-11-29 20:42:11 +08001032TEST_F(InputReaderTest, Device_CanDispatchToDisplay) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001033 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001034 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001035 constexpr int32_t eventHubId = 1;
Arthur Hungc23540e2018-11-29 20:42:11 +08001036 const char* DEVICE_LOCATION = "USB1";
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001037 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1038 FakeInputMapper& mapper =
Arpit Singh8e6fb252023-04-06 11:49:17 +00001039 device->addMapper<FakeInputMapper>(eventHubId, mFakePolicy->getReaderConfiguration(),
1040 AINPUT_SOURCE_TOUCHSCREEN);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001041 mReader->pushNextDevice(device);
Arthur Hungc23540e2018-11-29 20:42:11 +08001042
1043 const uint8_t hdmi1 = 1;
1044
1045 // Associated touch screen with second display.
1046 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
1047
1048 // Add default and second display.
Prabir Pradhan28efc192019-11-05 01:10:04 +00001049 mFakePolicy->clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00001050 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +00001051 /*isActive=*/true, "local:0", NO_PORT, ViewportType::INTERNAL);
Arthur Hungc23540e2018-11-29 20:42:11 +08001052 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +00001053 ui::ROTATION_0, /*isActive=*/true, "local:1", hdmi1,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001054 ViewportType::EXTERNAL);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00001055 mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::DISPLAY_INFO);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001056 mReader->loopOnce();
Prabir Pradhan28efc192019-11-05 01:10:04 +00001057
1058 // Add the device, and make sure all of the callbacks are triggered.
1059 // The device is added after the input port associations are processed since
1060 // we do not yet support dynamic device-to-display associations.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001061 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001062 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled());
Prabir Pradhan28efc192019-11-05 01:10:04 +00001063 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001064 ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
Arthur Hungc23540e2018-11-29 20:42:11 +08001065
Arthur Hung2c9a3342019-07-23 14:18:59 +08001066 // Device should only dispatch to the specified display.
Arthur Hungc23540e2018-11-29 20:42:11 +08001067 ASSERT_EQ(deviceId, device->getId());
1068 ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, DISPLAY_ID));
1069 ASSERT_TRUE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
Arthur Hung2c9a3342019-07-23 14:18:59 +08001070
1071 // Can't dispatch event from a disabled device.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001072 disableDevice(deviceId);
Prabir Pradhan28efc192019-11-05 01:10:04 +00001073 mReader->loopOnce();
Arthur Hung2c9a3342019-07-23 14:18:59 +08001074 ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
Arthur Hungc23540e2018-11-29 20:42:11 +08001075}
1076
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001077TEST_F(InputReaderTest, WhenEnabledChanges_AllSubdevicesAreUpdated) {
1078 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001079 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001080 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
1081 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1082 // Must add at least one mapper or the device will be ignored!
Arpit Singh8e6fb252023-04-06 11:49:17 +00001083 device->addMapper<FakeInputMapper>(eventHubIds[0], mFakePolicy->getReaderConfiguration(),
1084 AINPUT_SOURCE_KEYBOARD);
1085 device->addMapper<FakeInputMapper>(eventHubIds[1], mFakePolicy->getReaderConfiguration(),
1086 AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001087 mReader->pushNextDevice(device);
1088 mReader->pushNextDevice(device);
1089 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
1090 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
1091
1092 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
1093
1094 NotifyDeviceResetArgs resetArgs;
1095 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1096 ASSERT_EQ(deviceId, resetArgs.deviceId);
1097 ASSERT_TRUE(device->isEnabled());
1098 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1099 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1100
1101 disableDevice(deviceId);
1102 mReader->loopOnce();
1103
1104 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1105 ASSERT_EQ(deviceId, resetArgs.deviceId);
1106 ASSERT_FALSE(device->isEnabled());
1107 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1108 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1109
1110 enableDevice(deviceId);
1111 mReader->loopOnce();
1112
1113 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1114 ASSERT_EQ(deviceId, resetArgs.deviceId);
1115 ASSERT_TRUE(device->isEnabled());
1116 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1117 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1118}
1119
1120TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToSubdeviceMappers) {
1121 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001122 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001123 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
1124 // Add two subdevices to device
1125 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1126 FakeInputMapper& mapperDevice1 =
Arpit Singh8e6fb252023-04-06 11:49:17 +00001127 device->addMapper<FakeInputMapper>(eventHubIds[0],
1128 mFakePolicy->getReaderConfiguration(),
1129 AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001130 FakeInputMapper& mapperDevice2 =
Arpit Singh8e6fb252023-04-06 11:49:17 +00001131 device->addMapper<FakeInputMapper>(eventHubIds[1],
1132 mFakePolicy->getReaderConfiguration(),
1133 AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001134 mReader->pushNextDevice(device);
1135 mReader->pushNextDevice(device);
1136 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
1137 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
1138
1139 mapperDevice1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
1140 mapperDevice2.setKeyCodeState(AKEYCODE_B, AKEY_STATE_DOWN);
1141
1142 ASSERT_EQ(AKEY_STATE_DOWN,
1143 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_A));
1144 ASSERT_EQ(AKEY_STATE_DOWN,
1145 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_B));
1146 ASSERT_EQ(AKEY_STATE_UNKNOWN,
1147 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_C));
1148}
1149
Prabir Pradhan7e186182020-11-10 13:56:45 -08001150TEST_F(InputReaderTest, ChangingPointerCaptureNotifiesInputListener) {
1151 NotifyPointerCaptureChangedArgs args;
1152
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001153 auto request = mFakePolicy->setPointerCapture(true);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00001154 mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::POINTER_CAPTURE);
Prabir Pradhan7e186182020-11-10 13:56:45 -08001155 mReader->loopOnce();
1156 mFakeListener->assertNotifyCaptureWasCalled(&args);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001157 ASSERT_TRUE(args.request.enable) << "Pointer Capture should be enabled.";
1158 ASSERT_EQ(args.request, request) << "Pointer Capture sequence number should match.";
Prabir Pradhan7e186182020-11-10 13:56:45 -08001159
1160 mFakePolicy->setPointerCapture(false);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00001161 mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::POINTER_CAPTURE);
Prabir Pradhan7e186182020-11-10 13:56:45 -08001162 mReader->loopOnce();
1163 mFakeListener->assertNotifyCaptureWasCalled(&args);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001164 ASSERT_FALSE(args.request.enable) << "Pointer Capture should be disabled.";
Prabir Pradhan7e186182020-11-10 13:56:45 -08001165
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001166 // Verify that the Pointer Capture state is not updated when the configuration value
Prabir Pradhan7e186182020-11-10 13:56:45 -08001167 // does not change.
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00001168 mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::POINTER_CAPTURE);
Prabir Pradhan7e186182020-11-10 13:56:45 -08001169 mReader->loopOnce();
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001170 mFakeListener->assertNotifyCaptureWasNotCalled();
Prabir Pradhan7e186182020-11-10 13:56:45 -08001171}
1172
Chris Ye87143712020-11-10 05:05:58 +00001173class FakeVibratorInputMapper : public FakeInputMapper {
1174public:
Arpit Singh8e6fb252023-04-06 11:49:17 +00001175 FakeVibratorInputMapper(InputDeviceContext& deviceContext,
1176 const InputReaderConfiguration& readerConfig, uint32_t sources)
1177 : FakeInputMapper(deviceContext, readerConfig, sources) {}
Chris Ye87143712020-11-10 05:05:58 +00001178
1179 std::vector<int32_t> getVibratorIds() override { return getDeviceContext().getVibratorIds(); }
1180};
1181
1182TEST_F(InputReaderTest, VibratorGetVibratorIds) {
1183 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001184 ftl::Flags<InputDeviceClass> deviceClass =
1185 InputDeviceClass::KEYBOARD | InputDeviceClass::VIBRATOR;
Chris Ye87143712020-11-10 05:05:58 +00001186 constexpr int32_t eventHubId = 1;
1187 const char* DEVICE_LOCATION = "BLUETOOTH";
1188 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1189 FakeVibratorInputMapper& mapper =
Arpit Singh8e6fb252023-04-06 11:49:17 +00001190 device->addMapper<FakeVibratorInputMapper>(eventHubId,
1191 mFakePolicy->getReaderConfiguration(),
1192 AINPUT_SOURCE_KEYBOARD);
Chris Ye87143712020-11-10 05:05:58 +00001193 mReader->pushNextDevice(device);
1194
1195 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1196 ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
1197
1198 ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
1199 ASSERT_EQ(mReader->getVibratorIds(deviceId).size(), 2U);
1200}
1201
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001202// --- FakePeripheralController ---
Kim Low03ea0352020-11-06 12:45:07 -08001203
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001204class FakePeripheralController : public PeripheralControllerInterface {
Chris Yee2b1e5c2021-03-10 22:45:12 -08001205public:
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001206 FakePeripheralController(InputDeviceContext& deviceContext) : mDeviceContext(deviceContext) {}
Chris Yee2b1e5c2021-03-10 22:45:12 -08001207
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001208 ~FakePeripheralController() override {}
Chris Yee2b1e5c2021-03-10 22:45:12 -08001209
Andy Chenf9f1a022022-08-29 20:07:10 -04001210 int32_t getEventHubId() const { return getDeviceContext().getEventHubId(); }
1211
Chris Yee2b1e5c2021-03-10 22:45:12 -08001212 void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {}
1213
1214 void dump(std::string& dump) override {}
1215
1216 std::optional<int32_t> getBatteryCapacity(int32_t batteryId) override {
1217 return getDeviceContext().getBatteryCapacity(batteryId);
Kim Low03ea0352020-11-06 12:45:07 -08001218 }
1219
Chris Yee2b1e5c2021-03-10 22:45:12 -08001220 std::optional<int32_t> getBatteryStatus(int32_t batteryId) override {
1221 return getDeviceContext().getBatteryStatus(batteryId);
Kim Low03ea0352020-11-06 12:45:07 -08001222 }
Chris Ye3fdbfef2021-01-06 18:45:18 -08001223
1224 bool setLightColor(int32_t lightId, int32_t color) override {
1225 getDeviceContext().setLightBrightness(lightId, color >> 24);
1226 return true;
1227 }
1228
1229 std::optional<int32_t> getLightColor(int32_t lightId) override {
1230 std::optional<int32_t> result = getDeviceContext().getLightBrightness(lightId);
1231 if (!result.has_value()) {
1232 return std::nullopt;
1233 }
1234 return result.value() << 24;
1235 }
Chris Yee2b1e5c2021-03-10 22:45:12 -08001236
1237 bool setLightPlayerId(int32_t lightId, int32_t playerId) override { return true; }
1238
1239 std::optional<int32_t> getLightPlayerId(int32_t lightId) override { return std::nullopt; }
1240
1241private:
1242 InputDeviceContext& mDeviceContext;
1243 inline int32_t getDeviceId() { return mDeviceContext.getId(); }
1244 inline InputDeviceContext& getDeviceContext() { return mDeviceContext; }
Andy Chenf9f1a022022-08-29 20:07:10 -04001245 inline InputDeviceContext& getDeviceContext() const { return mDeviceContext; }
Chris Ye3fdbfef2021-01-06 18:45:18 -08001246};
1247
Chris Yee2b1e5c2021-03-10 22:45:12 -08001248TEST_F(InputReaderTest, BatteryGetCapacity) {
1249 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001250 ftl::Flags<InputDeviceClass> deviceClass =
1251 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
Chris Yee2b1e5c2021-03-10 22:45:12 -08001252 constexpr int32_t eventHubId = 1;
1253 const char* DEVICE_LOCATION = "BLUETOOTH";
1254 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001255 FakePeripheralController& controller =
1256 device->addController<FakePeripheralController>(eventHubId);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001257 mReader->pushNextDevice(device);
1258
1259 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1260
Harry Cuttsa5b71292022-11-28 12:56:17 +00001261 ASSERT_EQ(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY),
1262 FakeEventHub::BATTERY_CAPACITY);
1263 ASSERT_EQ(mReader->getBatteryCapacity(deviceId), FakeEventHub::BATTERY_CAPACITY);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001264}
1265
1266TEST_F(InputReaderTest, BatteryGetStatus) {
1267 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001268 ftl::Flags<InputDeviceClass> deviceClass =
1269 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
Chris Yee2b1e5c2021-03-10 22:45:12 -08001270 constexpr int32_t eventHubId = 1;
1271 const char* DEVICE_LOCATION = "BLUETOOTH";
1272 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001273 FakePeripheralController& controller =
1274 device->addController<FakePeripheralController>(eventHubId);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001275 mReader->pushNextDevice(device);
1276
1277 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1278
Harry Cuttsa5b71292022-11-28 12:56:17 +00001279 ASSERT_EQ(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY),
1280 FakeEventHub::BATTERY_STATUS);
1281 ASSERT_EQ(mReader->getBatteryStatus(deviceId), FakeEventHub::BATTERY_STATUS);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001282}
1283
Prabir Pradhane287ecd2022-09-07 21:18:05 +00001284TEST_F(InputReaderTest, BatteryGetDevicePath) {
1285 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1286 ftl::Flags<InputDeviceClass> deviceClass =
1287 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
1288 constexpr int32_t eventHubId = 1;
1289 const char* DEVICE_LOCATION = "BLUETOOTH";
1290 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1291 device->addController<FakePeripheralController>(eventHubId);
1292 mReader->pushNextDevice(device);
1293
1294 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1295
Harry Cuttsa5b71292022-11-28 12:56:17 +00001296 ASSERT_EQ(mReader->getBatteryDevicePath(deviceId), FakeEventHub::BATTERY_DEVPATH);
Prabir Pradhane287ecd2022-09-07 21:18:05 +00001297}
1298
Chris Ye3fdbfef2021-01-06 18:45:18 -08001299TEST_F(InputReaderTest, LightGetColor) {
1300 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001301 ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD | InputDeviceClass::LIGHT;
Chris Ye3fdbfef2021-01-06 18:45:18 -08001302 constexpr int32_t eventHubId = 1;
1303 const char* DEVICE_LOCATION = "BLUETOOTH";
1304 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001305 FakePeripheralController& controller =
1306 device->addController<FakePeripheralController>(eventHubId);
Chris Ye3fdbfef2021-01-06 18:45:18 -08001307 mReader->pushNextDevice(device);
1308 RawLightInfo info = {.id = 1,
1309 .name = "Mono",
1310 .maxBrightness = 255,
1311 .flags = InputLightClass::BRIGHTNESS,
1312 .path = ""};
Harry Cutts33476232023-01-30 19:57:29 +00001313 mFakeEventHub->addRawLightInfo(/*rawId=*/1, std::move(info));
1314 mFakeEventHub->fakeLightBrightness(/*rawId=*/1, 0x55);
Chris Ye3fdbfef2021-01-06 18:45:18 -08001315
1316 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Chris Ye3fdbfef2021-01-06 18:45:18 -08001317
Harry Cutts33476232023-01-30 19:57:29 +00001318 ASSERT_TRUE(controller.setLightColor(/*lightId=*/1, LIGHT_BRIGHTNESS));
1319 ASSERT_EQ(controller.getLightColor(/*lightId=*/1), LIGHT_BRIGHTNESS);
1320 ASSERT_TRUE(mReader->setLightColor(deviceId, /*lightId=*/1, LIGHT_BRIGHTNESS));
1321 ASSERT_EQ(mReader->getLightColor(deviceId, /*lightId=*/1), LIGHT_BRIGHTNESS);
Chris Ye3fdbfef2021-01-06 18:45:18 -08001322}
1323
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001324// --- InputReaderIntegrationTest ---
1325
1326// These tests create and interact with the InputReader only through its interface.
1327// The InputReader is started during SetUp(), which starts its processing in its own
1328// thread. The tests use linux uinput to emulate input devices.
1329// NOTE: Interacting with the physical device while these tests are running may cause
1330// the tests to fail.
1331class InputReaderIntegrationTest : public testing::Test {
1332protected:
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001333 std::unique_ptr<TestInputListener> mTestListener;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001334 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001335 std::unique_ptr<InputReaderInterface> mReader;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001336
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00001337 std::shared_ptr<FakePointerController> mFakePointerController;
1338
Chris Yea52ade12020-08-27 16:49:20 -07001339 void SetUp() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001340#if !defined(__ANDROID__)
1341 GTEST_SKIP();
1342#endif
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07001343 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00001344 mFakePointerController = std::make_shared<FakePointerController>();
1345 mFakePolicy->setPointerController(mFakePointerController);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001346
Arpit Singh440bf652023-08-09 09:23:43 +00001347 setupInputReader();
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001348 }
1349
Chris Yea52ade12020-08-27 16:49:20 -07001350 void TearDown() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001351#if !defined(__ANDROID__)
1352 return;
1353#endif
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001354 ASSERT_EQ(mReader->stop(), OK);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001355 mReader.reset();
1356 mTestListener.reset();
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001357 mFakePolicy.clear();
1358 }
Prabir Pradhanda20b172022-09-26 17:01:18 +00001359
1360 std::optional<InputDeviceInfo> findDeviceByName(const std::string& name) {
1361 const std::vector<InputDeviceInfo> inputDevices = mFakePolicy->getInputDevices();
1362 const auto& it = std::find_if(inputDevices.begin(), inputDevices.end(),
1363 [&name](const InputDeviceInfo& info) {
1364 return info.getIdentifier().name == name;
1365 });
1366 return it != inputDevices.end() ? std::make_optional(*it) : std::nullopt;
1367 }
Arpit Singh440bf652023-08-09 09:23:43 +00001368
1369 void setupInputReader() {
1370 mTestListener = std::make_unique<TestInputListener>(/*eventHappenedTimeout=*/2000ms,
1371 /*eventDidNotHappenTimeout=*/30ms);
1372
1373 mReader = std::make_unique<InputReader>(std::make_shared<EventHub>(), mFakePolicy,
1374 *mTestListener);
1375 ASSERT_EQ(mReader->start(), OK);
1376
1377 // Since this test is run on a real device, all the input devices connected
1378 // to the test device will show up in mReader. We wait for those input devices to
1379 // show up before beginning the tests.
1380 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1381 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyInputDevicesChangedWasCalled());
1382 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1383 }
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001384};
1385
1386TEST_F(InputReaderIntegrationTest, TestInvalidDevice) {
1387 // An invalid input device that is only used for this test.
1388 class InvalidUinputDevice : public UinputDevice {
1389 public:
Harry Cutts33476232023-01-30 19:57:29 +00001390 InvalidUinputDevice() : UinputDevice("Invalid Device", /*productId=*/99) {}
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001391
1392 private:
1393 void configureDevice(int fd, uinput_user_dev* device) override {}
1394 };
1395
1396 const size_t numDevices = mFakePolicy->getInputDevices().size();
1397
1398 // UinputDevice does not set any event or key bits, so InputReader should not
1399 // consider it as a valid device.
1400 std::unique_ptr<UinputDevice> invalidDevice = createUinputDevice<InvalidUinputDevice>();
1401 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
1402 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
1403 ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
1404
1405 invalidDevice.reset();
1406 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
1407 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
1408 ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
1409}
1410
1411TEST_F(InputReaderIntegrationTest, AddNewDevice) {
1412 const size_t initialNumDevices = mFakePolicy->getInputDevices().size();
1413
1414 std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
1415 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1416 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1417 ASSERT_EQ(initialNumDevices + 1, mFakePolicy->getInputDevices().size());
1418
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001419 const auto device = findDeviceByName(keyboard->getName());
1420 ASSERT_TRUE(device.has_value());
1421 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, device->getKeyboardType());
1422 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources());
1423 ASSERT_EQ(0U, device->getMotionRanges().size());
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001424
1425 keyboard.reset();
1426 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1427 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1428 ASSERT_EQ(initialNumDevices, mFakePolicy->getInputDevices().size());
1429}
1430
1431TEST_F(InputReaderIntegrationTest, SendsEventsToInputListener) {
1432 std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
1433 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1434
1435 NotifyConfigurationChangedArgs configChangedArgs;
1436 ASSERT_NO_FATAL_FAILURE(
1437 mTestListener->assertNotifyConfigurationChangedWasCalled(&configChangedArgs));
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001438 int32_t prevId = configChangedArgs.id;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001439 nsecs_t prevTimestamp = configChangedArgs.eventTime;
1440
1441 NotifyKeyArgs keyArgs;
1442 keyboard->pressAndReleaseHomeKey();
1443 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
1444 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
Garfield Tan1c7bc862020-01-28 13:24:04 -08001445 ASSERT_NE(prevId, keyArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001446 prevId = keyArgs.id;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001447 ASSERT_LE(prevTimestamp, keyArgs.eventTime);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001448 ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001449 prevTimestamp = keyArgs.eventTime;
1450
1451 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
1452 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
Garfield Tan1c7bc862020-01-28 13:24:04 -08001453 ASSERT_NE(prevId, keyArgs.id);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001454 ASSERT_LE(prevTimestamp, keyArgs.eventTime);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001455 ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001456}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001457
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001458TEST_F(InputReaderIntegrationTest, ExternalStylusesButtons) {
1459 std::unique_ptr<UinputExternalStylus> stylus = createUinputDevice<UinputExternalStylus>();
1460 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1461
1462 const auto device = findDeviceByName(stylus->getName());
1463 ASSERT_TRUE(device.has_value());
1464
Prabir Pradhana3621852022-10-14 18:57:23 +00001465 // An external stylus with buttons should also be recognized as a keyboard.
1466 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_STYLUS, device->getSources())
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001467 << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
1468 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, device->getKeyboardType());
1469
1470 const auto DOWN =
1471 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD));
1472 const auto UP = AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD));
1473
1474 stylus->pressAndReleaseKey(BTN_STYLUS);
1475 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1476 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1477 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1478 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1479
1480 stylus->pressAndReleaseKey(BTN_STYLUS2);
1481 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1482 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_SECONDARY))));
1483 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1484 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_SECONDARY))));
1485
1486 stylus->pressAndReleaseKey(BTN_STYLUS3);
1487 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1488 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
1489 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1490 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
1491}
1492
Prabir Pradhan3c28b942023-08-18 20:02:01 +00001493TEST_F(InputReaderIntegrationTest, KeyboardWithStylusButtons) {
1494 std::unique_ptr<UinputKeyboard> keyboard =
1495 createUinputDevice<UinputKeyboard>("KeyboardWithStylusButtons", /*productId=*/99,
1496 std::initializer_list<int>{KEY_Q, KEY_W, KEY_E,
1497 KEY_R, KEY_T, KEY_Y,
1498 BTN_STYLUS, BTN_STYLUS2,
1499 BTN_STYLUS3});
1500 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1501
1502 const auto device = findDeviceByName(keyboard->getName());
1503 ASSERT_TRUE(device.has_value());
1504
1505 // An alphabetical keyboard that reports stylus buttons should not be recognized as a stylus.
1506 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources())
1507 << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
1508 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, device->getKeyboardType());
1509}
1510
Prabir Pradhan37a819b2023-08-22 23:20:16 +00001511TEST_F(InputReaderIntegrationTest, HidUsageKeyboardIsNotAStylus) {
1512 // Create a Uinput keyboard that simulates a keyboard that can report HID usage codes. The
1513 // hid-input driver reports HID usage codes using the value for EV_MSC MSC_SCAN event.
1514 std::unique_ptr<UinputKeyboardWithHidUsage> keyboard =
1515 createUinputDevice<UinputKeyboardWithHidUsage>(
1516 std::initializer_list<int>{KEY_VOLUMEUP, KEY_VOLUMEDOWN});
1517 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1518
1519 const auto device = findDeviceByName(keyboard->getName());
1520 ASSERT_TRUE(device.has_value());
1521
1522 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources())
1523 << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
1524
1525 // If a device supports reporting HID usage codes, it shouldn't automatically support
1526 // stylus keys.
1527 const std::vector<int> keycodes{AKEYCODE_STYLUS_BUTTON_PRIMARY};
1528 uint8_t outFlags[] = {0};
1529 ASSERT_TRUE(mReader->hasKeys(device->getId(), AINPUT_SOURCE_KEYBOARD, keycodes, outFlags));
1530 ASSERT_EQ(0, outFlags[0]) << "Keyboard should not have stylus button";
1531}
1532
Siarhei Vishniakoua0d2b802020-05-13 14:00:31 -07001533/**
1534 * The Steam controller sends BTN_GEAR_DOWN and BTN_GEAR_UP for the two "paddle" buttons
1535 * on the back. In this test, we make sure that BTN_GEAR_DOWN / BTN_WHEEL and BTN_GEAR_UP
1536 * are passed to the listener.
1537 */
1538static_assert(BTN_GEAR_DOWN == BTN_WHEEL);
1539TEST_F(InputReaderIntegrationTest, SendsGearDownAndUpToInputListener) {
1540 std::unique_ptr<UinputSteamController> controller = createUinputDevice<UinputSteamController>();
1541 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1542 NotifyKeyArgs keyArgs;
1543
1544 controller->pressAndReleaseKey(BTN_GEAR_DOWN);
1545 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
1546 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
1547 ASSERT_EQ(BTN_GEAR_DOWN, keyArgs.scanCode);
1548
1549 controller->pressAndReleaseKey(BTN_GEAR_UP);
1550 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
1551 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
1552 ASSERT_EQ(BTN_GEAR_UP, keyArgs.scanCode);
1553}
1554
Prabir Pradhan484d55a2022-10-14 23:17:16 +00001555// --- TouchIntegrationTest ---
1556
Arpit Singh440bf652023-08-09 09:23:43 +00001557class BaseTouchIntegrationTest : public InputReaderIntegrationTest {
Arthur Hungaab25622020-01-16 11:22:11 +08001558protected:
Arthur Hungaab25622020-01-16 11:22:11 +08001559 const std::string UNIQUE_ID = "local:0";
1560
Chris Yea52ade12020-08-27 16:49:20 -07001561 void SetUp() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001562#if !defined(__ANDROID__)
1563 GTEST_SKIP();
1564#endif
Arthur Hungaab25622020-01-16 11:22:11 +08001565 InputReaderIntegrationTest::SetUp();
1566 // At least add an internal display.
Michael Wrighta9cf4192022-12-01 23:46:39 +00001567 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
1568 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Arthur Hungaab25622020-01-16 11:22:11 +08001569
1570 mDevice = createUinputDevice<UinputTouchScreen>(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT));
1571 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1572 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
Prabir Pradhanda20b172022-09-26 17:01:18 +00001573 const auto info = findDeviceByName(mDevice->getName());
1574 ASSERT_TRUE(info);
1575 mDeviceInfo = *info;
Arthur Hungaab25622020-01-16 11:22:11 +08001576 }
1577
1578 void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
Michael Wrighta9cf4192022-12-01 23:46:39 +00001579 ui::Rotation orientation, const std::string& uniqueId,
Arthur Hungaab25622020-01-16 11:22:11 +08001580 std::optional<uint8_t> physicalPort,
1581 ViewportType viewportType) {
Harry Cutts33476232023-01-30 19:57:29 +00001582 mFakePolicy->addDisplayViewport(displayId, width, height, orientation, /*isActive=*/true,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001583 uniqueId, physicalPort, viewportType);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00001584 mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::DISPLAY_INFO);
Arthur Hungaab25622020-01-16 11:22:11 +08001585 }
1586
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001587 void assertReceivedMotion(int32_t action, const std::vector<Point>& points) {
1588 NotifyMotionArgs args;
1589 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1590 EXPECT_EQ(action, args.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07001591 ASSERT_EQ(points.size(), args.getPointerCount());
1592 for (size_t i = 0; i < args.getPointerCount(); i++) {
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001593 EXPECT_EQ(points[i].x, args.pointerCoords[i].getX());
1594 EXPECT_EQ(points[i].y, args.pointerCoords[i].getY());
1595 }
1596 }
1597
Arthur Hungaab25622020-01-16 11:22:11 +08001598 std::unique_ptr<UinputTouchScreen> mDevice;
Prabir Pradhanda20b172022-09-26 17:01:18 +00001599 InputDeviceInfo mDeviceInfo;
Arthur Hungaab25622020-01-16 11:22:11 +08001600};
1601
Arpit Singh440bf652023-08-09 09:23:43 +00001602enum class TouchIntegrationTestDisplays { DISPLAY_INTERNAL, DISPLAY_INPUT_PORT, DISPLAY_UNIQUE_ID };
1603
1604class TouchIntegrationTest : public BaseTouchIntegrationTest,
1605 public testing::WithParamInterface<TouchIntegrationTestDisplays> {
1606protected:
1607 static constexpr std::optional<uint8_t> DISPLAY_PORT = 0;
1608 const std::string INPUT_PORT = "uinput_touch/input0";
1609
1610 void SetUp() override {
1611#if !defined(__ANDROID__)
1612 GTEST_SKIP();
1613#endif
1614 if (GetParam() == TouchIntegrationTestDisplays::DISPLAY_INTERNAL) {
1615 BaseTouchIntegrationTest::SetUp();
1616 return;
1617 }
1618
1619 // setup policy with a input-port or UniqueId association to the display
1620 bool isInputPortAssociation =
1621 GetParam() == TouchIntegrationTestDisplays::DISPLAY_INPUT_PORT;
1622
1623 mFakePolicy = sp<FakeInputReaderPolicy>::make();
1624 if (isInputPortAssociation) {
1625 mFakePolicy->addInputPortAssociation(INPUT_PORT, DISPLAY_PORT.value());
1626 } else {
1627 mFakePolicy->addInputUniqueIdAssociation(INPUT_PORT, UNIQUE_ID);
1628 }
1629 mFakePointerController = std::make_shared<FakePointerController>();
1630 mFakePolicy->setPointerController(mFakePointerController);
1631
1632 InputReaderIntegrationTest::setupInputReader();
1633
1634 mDevice = createUinputDevice<UinputTouchScreen>(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT),
1635 INPUT_PORT);
1636 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1637
1638 // Add a display linked to a physical port or UniqueId.
1639 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
1640 UNIQUE_ID, isInputPortAssociation ? DISPLAY_PORT : NO_PORT,
1641 ViewportType::INTERNAL);
1642 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1643 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1644 const auto info = findDeviceByName(mDevice->getName());
1645 ASSERT_TRUE(info);
1646 mDeviceInfo = *info;
1647 }
1648};
1649
1650TEST_P(TouchIntegrationTest, MultiTouchDeviceSource) {
Prabir Pradhanf9a41282022-10-25 17:15:50 +00001651 // The UinputTouchScreen is an MT device that supports MT_TOOL_TYPE and also supports stylus
1652 // buttons. It should show up as a touchscreen, stylus, and keyboard (for reporting button
1653 // presses).
1654 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD,
1655 mDeviceInfo.getSources());
1656}
1657
Arpit Singh440bf652023-08-09 09:23:43 +00001658TEST_P(TouchIntegrationTest, InputEvent_ProcessSingleTouch) {
Arthur Hungaab25622020-01-16 11:22:11 +08001659 NotifyMotionArgs args;
1660 const Point centerPoint = mDevice->getCenterPoint();
1661
1662 // ACTION_DOWN
Arthur Hung9ad18942021-06-19 02:04:46 +00001663 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001664 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001665 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001666 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1667 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1668
1669 // ACTION_MOVE
1670 mDevice->sendMove(centerPoint + Point(1, 1));
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001671 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001672 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1673 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1674
1675 // ACTION_UP
1676 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001677 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001678 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1679 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
1680}
1681
Arpit Singh440bf652023-08-09 09:23:43 +00001682TEST_P(TouchIntegrationTest, InputEvent_ProcessMultiTouch) {
Arthur Hungaab25622020-01-16 11:22:11 +08001683 NotifyMotionArgs args;
1684 const Point centerPoint = mDevice->getCenterPoint();
1685
1686 // ACTION_DOWN
Arthur Hung9ad18942021-06-19 02:04:46 +00001687 mDevice->sendSlot(FIRST_SLOT);
1688 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001689 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001690 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001691 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1692 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1693
1694 // ACTION_POINTER_DOWN (Second slot)
1695 const Point secondPoint = centerPoint + Point(100, 100);
1696 mDevice->sendSlot(SECOND_SLOT);
1697 mDevice->sendTrackingId(SECOND_TRACKING_ID);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001698 mDevice->sendDown(secondPoint);
1699 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001700 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001701 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001702
1703 // ACTION_MOVE (Second slot)
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001704 mDevice->sendMove(secondPoint + Point(1, 1));
1705 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001706 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1707 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1708
1709 // ACTION_POINTER_UP (Second slot)
arthurhungcc7f9802020-04-30 17:55:40 +08001710 mDevice->sendPointerUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001711 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001712 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001713 ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001714
1715 // ACTION_UP
1716 mDevice->sendSlot(FIRST_SLOT);
1717 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001718 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001719 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1720 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
1721}
1722
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001723/**
1724 * What happens when a pointer goes up while another pointer moves in the same frame? Are POINTER_UP
1725 * events guaranteed to contain the same data as a preceding MOVE, or can they contain different
1726 * data?
1727 * In this test, we try to send a change in coordinates in Pointer 0 in the same frame as the
1728 * liftoff of Pointer 1. We check that POINTER_UP event is generated first, and the MOVE event
1729 * for Pointer 0 only is generated after.
1730 * Suppose we are only interested in learning the movement of Pointer 0. If we only observe MOVE
1731 * events, we will not miss any information.
1732 * Even though the Pointer 1 up event contains updated Pointer 0 coordinates, there is another MOVE
1733 * event generated afterwards that contains the newest movement of pointer 0.
1734 * This is important for palm rejection. If there is a subsequent InputListener stage that detects
1735 * palms, and wants to cancel Pointer 1, then it is safe to simply drop POINTER_1_UP event without
1736 * losing information about non-palm pointers.
1737 */
Arpit Singh440bf652023-08-09 09:23:43 +00001738TEST_P(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerUp) {
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001739 NotifyMotionArgs args;
1740 const Point centerPoint = mDevice->getCenterPoint();
1741
1742 // ACTION_DOWN
1743 mDevice->sendSlot(FIRST_SLOT);
1744 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1745 mDevice->sendDown(centerPoint);
1746 mDevice->sendSync();
1747 assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
1748
1749 // ACTION_POINTER_DOWN (Second slot)
1750 const Point secondPoint = centerPoint + Point(100, 100);
1751 mDevice->sendSlot(SECOND_SLOT);
1752 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1753 mDevice->sendDown(secondPoint);
1754 mDevice->sendSync();
1755 assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
1756
1757 // ACTION_MOVE (First slot)
1758 mDevice->sendSlot(FIRST_SLOT);
1759 mDevice->sendMove(centerPoint + Point(5, 5));
1760 // ACTION_POINTER_UP (Second slot)
1761 mDevice->sendSlot(SECOND_SLOT);
1762 mDevice->sendPointerUp();
1763 // Send a single sync for the above 2 pointer updates
1764 mDevice->sendSync();
1765
1766 // First, we should get POINTER_UP for the second pointer
1767 assertReceivedMotion(ACTION_POINTER_1_UP,
1768 {/*first pointer */ centerPoint + Point(5, 5),
1769 /*second pointer*/ secondPoint});
1770
1771 // Next, the MOVE event for the first pointer
1772 assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
1773}
1774
1775/**
1776 * Similar scenario as above. The difference is that when the second pointer goes up, it will first
1777 * move, and then it will go up, all in the same frame.
1778 * In this scenario, the movement of the second pointer just prior to liftoff is ignored, and never
1779 * gets sent to the listener.
1780 */
Arpit Singh440bf652023-08-09 09:23:43 +00001781TEST_P(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerMoveAndUp) {
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001782 NotifyMotionArgs args;
1783 const Point centerPoint = mDevice->getCenterPoint();
1784
1785 // ACTION_DOWN
1786 mDevice->sendSlot(FIRST_SLOT);
1787 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1788 mDevice->sendDown(centerPoint);
1789 mDevice->sendSync();
1790 assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
1791
1792 // ACTION_POINTER_DOWN (Second slot)
1793 const Point secondPoint = centerPoint + Point(100, 100);
1794 mDevice->sendSlot(SECOND_SLOT);
1795 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1796 mDevice->sendDown(secondPoint);
1797 mDevice->sendSync();
1798 assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
1799
1800 // ACTION_MOVE (First slot)
1801 mDevice->sendSlot(FIRST_SLOT);
1802 mDevice->sendMove(centerPoint + Point(5, 5));
1803 // ACTION_POINTER_UP (Second slot)
1804 mDevice->sendSlot(SECOND_SLOT);
1805 mDevice->sendMove(secondPoint + Point(6, 6));
1806 mDevice->sendPointerUp();
1807 // Send a single sync for the above 2 pointer updates
1808 mDevice->sendSync();
1809
1810 // First, we should get POINTER_UP for the second pointer
1811 // The movement of the second pointer during the liftoff frame is ignored.
1812 // The coordinates 'secondPoint + Point(6, 6)' are never sent to the listener.
1813 assertReceivedMotion(ACTION_POINTER_1_UP,
1814 {/*first pointer */ centerPoint + Point(5, 5),
1815 /*second pointer*/ secondPoint});
1816
1817 // Next, the MOVE event for the first pointer
1818 assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
1819}
1820
Arpit Singh440bf652023-08-09 09:23:43 +00001821TEST_P(TouchIntegrationTest, InputEvent_ProcessPalm) {
Arthur Hungaab25622020-01-16 11:22:11 +08001822 NotifyMotionArgs args;
1823 const Point centerPoint = mDevice->getCenterPoint();
1824
1825 // ACTION_DOWN
arthurhungcc7f9802020-04-30 17:55:40 +08001826 mDevice->sendSlot(FIRST_SLOT);
1827 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001828 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001829 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001830 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1831 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1832
arthurhungcc7f9802020-04-30 17:55:40 +08001833 // ACTION_POINTER_DOWN (second slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001834 const Point secondPoint = centerPoint + Point(100, 100);
1835 mDevice->sendSlot(SECOND_SLOT);
1836 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1837 mDevice->sendDown(secondPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001838 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001839 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001840 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001841
arthurhungcc7f9802020-04-30 17:55:40 +08001842 // ACTION_MOVE (second slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001843 mDevice->sendMove(secondPoint + Point(1, 1));
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001844 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001845 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1846 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1847
arthurhungcc7f9802020-04-30 17:55:40 +08001848 // Send MT_TOOL_PALM (second slot), which indicates that the touch IC has determined this to be
1849 // a palm event.
1850 // Expect to receive the ACTION_POINTER_UP with cancel flag.
Arthur Hungaab25622020-01-16 11:22:11 +08001851 mDevice->sendToolType(MT_TOOL_PALM);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001852 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001853 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001854 ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
arthurhungcc7f9802020-04-30 17:55:40 +08001855 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, args.flags);
Arthur Hungaab25622020-01-16 11:22:11 +08001856
arthurhungcc7f9802020-04-30 17:55:40 +08001857 // Send up to second slot, expect first slot send moving.
1858 mDevice->sendPointerUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001859 mDevice->sendSync();
arthurhungcc7f9802020-04-30 17:55:40 +08001860 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1861 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001862
arthurhungcc7f9802020-04-30 17:55:40 +08001863 // Send ACTION_UP (first slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001864 mDevice->sendSlot(FIRST_SLOT);
1865 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001866 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001867
arthurhungcc7f9802020-04-30 17:55:40 +08001868 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1869 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001870}
1871
Prabir Pradhanc09ec6d2023-08-14 22:31:43 +00001872/**
1873 * Some drivers historically have reported axis values outside of the range specified in the
1874 * evdev axis info. Ensure we don't crash when this happens. For example, a driver may report a
1875 * pressure value greater than the reported maximum, since it unclear what specific meaning the
1876 * maximum value for pressure has (beyond the maximum value that can be produced by a sensor),
1877 * and no units for pressure (resolution) is specified by the evdev documentation.
1878 */
1879TEST_P(TouchIntegrationTest, AcceptsAxisValuesOutsideReportedRange) {
1880 const Point centerPoint = mDevice->getCenterPoint();
1881
1882 // Down with pressure outside the reported range
1883 mDevice->sendSlot(FIRST_SLOT);
1884 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1885 mDevice->sendDown(centerPoint);
1886 mDevice->sendPressure(UinputTouchScreen::RAW_PRESSURE_MAX + 2);
1887 mDevice->sendSync();
1888 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1889 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
1890
1891 // Move to a point outside the reported range
1892 mDevice->sendMove(Point(DISPLAY_WIDTH, DISPLAY_HEIGHT) + Point(1, 1));
1893 mDevice->sendSync();
1894 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1895 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
1896
1897 // Up
1898 mDevice->sendUp();
1899 mDevice->sendSync();
1900 ASSERT_NO_FATAL_FAILURE(
1901 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
1902}
1903
Arpit Singh440bf652023-08-09 09:23:43 +00001904TEST_P(TouchIntegrationTest, NotifiesPolicyWhenStylusGestureStarted) {
Prabir Pradhanda20b172022-09-26 17:01:18 +00001905 const Point centerPoint = mDevice->getCenterPoint();
1906
1907 // Send down with the pen tool selected. The policy should be notified of the stylus presence.
1908 mDevice->sendSlot(FIRST_SLOT);
1909 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1910 mDevice->sendToolType(MT_TOOL_PEN);
1911 mDevice->sendDown(centerPoint);
1912 mDevice->sendSync();
1913 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1914 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07001915 WithToolType(ToolType::STYLUS))));
Prabir Pradhanda20b172022-09-26 17:01:18 +00001916
1917 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
1918
1919 // Release the stylus touch.
1920 mDevice->sendUp();
1921 mDevice->sendSync();
1922 ASSERT_NO_FATAL_FAILURE(
1923 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
1924
1925 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
1926
1927 // Touch down with the finger, without the pen tool selected. The policy is not notified.
1928 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1929 mDevice->sendToolType(MT_TOOL_FINGER);
1930 mDevice->sendDown(centerPoint);
1931 mDevice->sendSync();
1932 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1933 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07001934 WithToolType(ToolType::FINGER))));
Prabir Pradhanda20b172022-09-26 17:01:18 +00001935
1936 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
1937
1938 mDevice->sendUp();
1939 mDevice->sendSync();
1940 ASSERT_NO_FATAL_FAILURE(
1941 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
1942
1943 // Send a move event with the stylus tool without BTN_TOUCH to generate a hover enter.
1944 // The policy should be notified of the stylus presence.
1945 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1946 mDevice->sendToolType(MT_TOOL_PEN);
1947 mDevice->sendMove(centerPoint);
1948 mDevice->sendSync();
1949 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1950 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07001951 WithToolType(ToolType::STYLUS))));
Prabir Pradhanda20b172022-09-26 17:01:18 +00001952
1953 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
1954}
1955
Arpit Singh440bf652023-08-09 09:23:43 +00001956TEST_P(TouchIntegrationTest, ExternalStylusConnectedDuringTouchGesture) {
Prabir Pradhan85cf63e2023-08-07 21:02:13 +00001957 const Point centerPoint = mDevice->getCenterPoint();
1958
1959 // Down
1960 mDevice->sendSlot(FIRST_SLOT);
1961 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1962 mDevice->sendDown(centerPoint);
1963 mDevice->sendSync();
1964 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1965 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
1966
1967 // Move
1968 mDevice->sendMove(centerPoint + Point(1, 1));
1969 mDevice->sendSync();
1970 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1971 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
1972
1973 // Connecting an external stylus mid-gesture should not interrupt the ongoing gesture stream.
1974 auto externalStylus = createUinputDevice<UinputExternalStylus>();
1975 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1976 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1977 const auto stylusInfo = findDeviceByName(externalStylus->getName());
1978 ASSERT_TRUE(stylusInfo);
Prabir Pradhan85cf63e2023-08-07 21:02:13 +00001979
1980 // Move
1981 mDevice->sendMove(centerPoint + Point(2, 2));
1982 mDevice->sendSync();
1983 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1984 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
1985
1986 // Disconnecting an external stylus mid-gesture should not interrupt the ongoing gesture stream.
1987 externalStylus.reset();
1988 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1989 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1990 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
1991
1992 // Up
1993 mDevice->sendUp();
1994 mDevice->sendSync();
1995 ASSERT_NO_FATAL_FAILURE(
1996 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
1997
1998 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
1999}
2000
Arpit Singh440bf652023-08-09 09:23:43 +00002001INSTANTIATE_TEST_SUITE_P(TouchIntegrationTestDisplayVariants, TouchIntegrationTest,
2002 testing::Values(TouchIntegrationTestDisplays::DISPLAY_INTERNAL,
2003 TouchIntegrationTestDisplays::DISPLAY_INPUT_PORT,
2004 TouchIntegrationTestDisplays::DISPLAY_UNIQUE_ID));
2005
Prabir Pradhan124ea442022-10-28 20:27:44 +00002006// --- StylusButtonIntegrationTest ---
Prabir Pradhane1a41a82022-10-14 18:06:50 +00002007
Prabir Pradhan124ea442022-10-28 20:27:44 +00002008// Verify the behavior of button presses reported by various kinds of styluses, including buttons
2009// reported by the touchscreen's device, by a fused external stylus, and by an un-fused external
2010// stylus.
2011template <typename UinputStylusDevice>
Arpit Singh440bf652023-08-09 09:23:43 +00002012class StylusButtonIntegrationTest : public BaseTouchIntegrationTest {
Prabir Pradhan124ea442022-10-28 20:27:44 +00002013protected:
2014 void SetUp() override {
2015#if !defined(__ANDROID__)
2016 GTEST_SKIP();
2017#endif
Arpit Singh440bf652023-08-09 09:23:43 +00002018 BaseTouchIntegrationTest::SetUp();
Prabir Pradhan124ea442022-10-28 20:27:44 +00002019 mTouchscreen = mDevice.get();
2020 mTouchscreenInfo = mDeviceInfo;
2021
2022 setUpStylusDevice();
2023 }
2024
2025 UinputStylusDevice* mStylus{nullptr};
2026 InputDeviceInfo mStylusInfo{};
2027
2028 UinputTouchScreen* mTouchscreen{nullptr};
2029 InputDeviceInfo mTouchscreenInfo{};
2030
2031private:
2032 // When we are attempting to test stylus button events that are sent from the touchscreen,
2033 // use the same Uinput device for the touchscreen and the stylus.
2034 template <typename T = UinputStylusDevice>
2035 std::enable_if_t<std::is_same_v<UinputTouchScreen, T>, void> setUpStylusDevice() {
2036 mStylus = mDevice.get();
2037 mStylusInfo = mDeviceInfo;
2038 }
2039
2040 // When we are attempting to stylus buttons from an external stylus being merged with touches
2041 // from a touchscreen, create a new Uinput device through which stylus buttons can be injected.
2042 template <typename T = UinputStylusDevice>
2043 std::enable_if_t<!std::is_same_v<UinputTouchScreen, T>, void> setUpStylusDevice() {
2044 mStylusDeviceLifecycleTracker = createUinputDevice<T>();
2045 mStylus = mStylusDeviceLifecycleTracker.get();
2046 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2047 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2048 const auto info = findDeviceByName(mStylus->getName());
2049 ASSERT_TRUE(info);
2050 mStylusInfo = *info;
2051 }
2052
2053 std::unique_ptr<UinputStylusDevice> mStylusDeviceLifecycleTracker{};
2054
2055 // Hide the base class's device to expose it with a different name for readability.
Arpit Singh440bf652023-08-09 09:23:43 +00002056 using BaseTouchIntegrationTest::mDevice;
2057 using BaseTouchIntegrationTest::mDeviceInfo;
Prabir Pradhan124ea442022-10-28 20:27:44 +00002058};
2059
2060using StylusButtonIntegrationTestTypes =
2061 ::testing::Types<UinputTouchScreen, UinputExternalStylus, UinputExternalStylusWithPressure>;
2062TYPED_TEST_SUITE(StylusButtonIntegrationTest, StylusButtonIntegrationTestTypes);
2063
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002064TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsGenerateKeyEvents) {
Prabir Pradhan124ea442022-10-28 20:27:44 +00002065 const auto stylusId = TestFixture::mStylusInfo.getId();
2066
2067 TestFixture::mStylus->pressKey(BTN_STYLUS);
2068 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2069 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
2070 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2071
2072 TestFixture::mStylus->releaseKey(BTN_STYLUS);
2073 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhane1a41a82022-10-14 18:06:50 +00002074 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002075 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
Prabir Pradhane1a41a82022-10-14 18:06:50 +00002076}
2077
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002078TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsSurroundingTouchGesture) {
Prabir Pradhan124ea442022-10-28 20:27:44 +00002079 const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
2080 const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
2081 const auto stylusId = TestFixture::mStylusInfo.getId();
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002082
2083 // Press the stylus button.
Prabir Pradhan124ea442022-10-28 20:27:44 +00002084 TestFixture::mStylus->pressKey(BTN_STYLUS);
2085 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002086 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002087 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002088
2089 // Start and finish a stylus gesture.
Prabir Pradhan124ea442022-10-28 20:27:44 +00002090 TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
2091 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2092 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2093 TestFixture::mTouchscreen->sendDown(centerPoint);
2094 TestFixture::mTouchscreen->sendSync();
2095 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002096 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002097 WithToolType(ToolType::STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002098 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2099 WithDeviceId(touchscreenId))));
2100 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002101 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002102 WithToolType(ToolType::STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002103 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2104 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002105
Prabir Pradhan124ea442022-10-28 20:27:44 +00002106 TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
2107 TestFixture::mTouchscreen->sendSync();
2108 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002109 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002110 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002111 WithDeviceId(touchscreenId))));
2112 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002113 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002114 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002115 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002116
2117 // Release the stylus button.
Prabir Pradhan124ea442022-10-28 20:27:44 +00002118 TestFixture::mStylus->releaseKey(BTN_STYLUS);
2119 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002120 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002121 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002122}
2123
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002124TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsSurroundingHoveringTouchGesture) {
Prabir Pradhan9a561c22022-11-07 16:11:23 +00002125 const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
2126 const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
2127 const auto stylusId = TestFixture::mStylusInfo.getId();
2128 auto toolTypeDevice =
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002129 AllOf(WithToolType(ToolType::STYLUS), WithDeviceId(touchscreenId));
Prabir Pradhan9a561c22022-11-07 16:11:23 +00002130
2131 // Press the stylus button.
2132 TestFixture::mStylus->pressKey(BTN_STYLUS);
2133 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2134 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
2135 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2136
2137 // Start hovering with the stylus.
2138 TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
2139 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2140 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2141 TestFixture::mTouchscreen->sendMove(centerPoint);
2142 TestFixture::mTouchscreen->sendSync();
2143 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2144 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
2145 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2146 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2147 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
2148 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2149 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2150 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
2151 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2152
2153 // Touch down with the stylus.
2154 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2155 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2156 TestFixture::mTouchscreen->sendDown(centerPoint);
2157 TestFixture::mTouchscreen->sendSync();
2158 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2159 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
2160 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2161
2162 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2163 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2164 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2165
2166 // Stop touching with the stylus, and start hovering.
2167 TestFixture::mTouchscreen->sendUp();
2168 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2169 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2170 TestFixture::mTouchscreen->sendMove(centerPoint);
2171 TestFixture::mTouchscreen->sendSync();
2172 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2173 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_UP),
2174 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2175 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2176 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
2177 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2178 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2179 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
2180 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2181
2182 // Stop hovering.
2183 TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
2184 TestFixture::mTouchscreen->sendSync();
2185 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2186 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
2187 WithButtonState(0))));
2188 // TODO(b/257971675): Fix inconsistent button state when exiting hover.
2189 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2190 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
2191 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2192
2193 // Release the stylus button.
2194 TestFixture::mStylus->releaseKey(BTN_STYLUS);
2195 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2196 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
2197 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2198}
2199
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002200TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsWithinTouchGesture) {
Prabir Pradhan124ea442022-10-28 20:27:44 +00002201 const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
2202 const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
2203 const auto stylusId = TestFixture::mStylusInfo.getId();
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002204
2205 // Start a stylus gesture.
Prabir Pradhan124ea442022-10-28 20:27:44 +00002206 TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
2207 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2208 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2209 TestFixture::mTouchscreen->sendDown(centerPoint);
2210 TestFixture::mTouchscreen->sendSync();
2211 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002212 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002213 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002214 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002215
2216 // Press and release a stylus button. Each change in button state also generates a MOVE event.
Prabir Pradhan124ea442022-10-28 20:27:44 +00002217 TestFixture::mStylus->pressKey(BTN_STYLUS);
2218 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002219 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002220 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2221 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002222 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002223 WithToolType(ToolType::STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002224 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2225 WithDeviceId(touchscreenId))));
2226 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002227 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002228 WithToolType(ToolType::STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002229 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2230 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002231
Prabir Pradhan124ea442022-10-28 20:27:44 +00002232 TestFixture::mStylus->releaseKey(BTN_STYLUS);
2233 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002234 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002235 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2236 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002237 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002238 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002239 WithDeviceId(touchscreenId))));
2240 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002241 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002242 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002243 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002244
2245 // Finish the stylus gesture.
Prabir Pradhan124ea442022-10-28 20:27:44 +00002246 TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
2247 TestFixture::mTouchscreen->sendSync();
2248 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002249 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002250 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002251 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002252}
2253
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002254TYPED_TEST(StylusButtonIntegrationTest, StylusButtonMotionEventsDisabled) {
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00002255 TestFixture::mFakePolicy->setStylusButtonMotionEventsEnabled(false);
2256 TestFixture::mReader->requestRefreshConfiguration(
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002257 InputReaderConfiguration::Change::STYLUS_BUTTON_REPORTING);
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00002258
2259 const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
2260 const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
2261 const auto stylusId = TestFixture::mStylusInfo.getId();
2262
2263 // Start a stylus gesture. By the time this event is processed, the configuration change that
2264 // was requested is guaranteed to be completed.
2265 TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
2266 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2267 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2268 TestFixture::mTouchscreen->sendDown(centerPoint);
2269 TestFixture::mTouchscreen->sendSync();
2270 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2271 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002272 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00002273 WithDeviceId(touchscreenId))));
2274
2275 // Press and release a stylus button. Each change only generates a MOVE motion event.
2276 // Key events are unaffected.
2277 TestFixture::mStylus->pressKey(BTN_STYLUS);
2278 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2279 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
2280 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2281 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2282 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002283 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00002284 WithDeviceId(touchscreenId))));
2285
2286 TestFixture::mStylus->releaseKey(BTN_STYLUS);
2287 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2288 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
2289 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2290 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2291 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002292 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00002293 WithDeviceId(touchscreenId))));
2294
2295 // Finish the stylus gesture.
2296 TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
2297 TestFixture::mTouchscreen->sendSync();
2298 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2299 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002300 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00002301 WithDeviceId(touchscreenId))));
2302}
2303
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002304// --- ExternalStylusIntegrationTest ---
2305
2306// Verify the behavior of an external stylus. An external stylus can report pressure or button
2307// data independently of the touchscreen, which is then sent as a MotionEvent as part of an
2308// ongoing stylus gesture that is being emitted by the touchscreen.
Arpit Singh440bf652023-08-09 09:23:43 +00002309using ExternalStylusIntegrationTest = BaseTouchIntegrationTest;
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002310
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002311TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureReported) {
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002312 const Point centerPoint = mDevice->getCenterPoint();
2313
2314 // Create an external stylus capable of reporting pressure data that
2315 // should be fused with a touch pointer.
2316 std::unique_ptr<UinputExternalStylusWithPressure> stylus =
2317 createUinputDevice<UinputExternalStylusWithPressure>();
2318 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2319 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2320 const auto stylusInfo = findDeviceByName(stylus->getName());
2321 ASSERT_TRUE(stylusInfo);
2322
2323 ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2324
2325 const auto touchscreenId = mDeviceInfo.getId();
2326
2327 // Set a pressure value on the stylus. It doesn't generate any events.
2328 const auto& RAW_PRESSURE_MAX = UinputExternalStylusWithPressure::RAW_PRESSURE_MAX;
2329 stylus->setPressure(100);
2330 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2331
2332 // Start a finger gesture, and ensure it shows up as stylus gesture
2333 // with the pressure set by the external stylus.
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002334 mDevice->sendSlot(FIRST_SLOT);
Chris Ye1b0c7342020-07-28 21:57:03 -07002335 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002336 mDevice->sendToolType(MT_TOOL_FINGER);
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00002337 mDevice->sendDown(centerPoint);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002338 mDevice->sendSync();
2339 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2340 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002341 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002342 WithDeviceId(touchscreenId), WithPressure(100.f / RAW_PRESSURE_MAX))));
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002343
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002344 // Change the pressure on the external stylus, and ensure the touchscreen generates a MOVE
2345 // event with the updated pressure.
2346 stylus->setPressure(200);
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +00002347 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2348 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002349 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002350 WithDeviceId(touchscreenId), WithPressure(200.f / RAW_PRESSURE_MAX))));
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002351
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002352 // The external stylus did not generate any events.
2353 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2354 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
2355}
2356
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002357TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureNotReported) {
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002358 const Point centerPoint = mDevice->getCenterPoint();
2359
2360 // Create an external stylus capable of reporting pressure data that
2361 // should be fused with a touch pointer.
2362 std::unique_ptr<UinputExternalStylusWithPressure> stylus =
2363 createUinputDevice<UinputExternalStylusWithPressure>();
2364 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2365 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2366 const auto stylusInfo = findDeviceByName(stylus->getName());
2367 ASSERT_TRUE(stylusInfo);
2368
2369 ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2370
2371 const auto touchscreenId = mDeviceInfo.getId();
2372
2373 // Set a pressure value of 0 on the stylus. It doesn't generate any events.
2374 const auto& RAW_PRESSURE_MAX = UinputExternalStylusWithPressure::RAW_PRESSURE_MAX;
Prabir Pradhan3f7545f2022-10-19 16:56:39 +00002375 // Send a non-zero value first to prevent the kernel from consuming the zero event.
2376 stylus->setPressure(100);
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002377 stylus->setPressure(0);
Prabir Pradhan3f7545f2022-10-19 16:56:39 +00002378 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002379
2380 // Start a finger gesture. The touch device will withhold generating any touches for
2381 // up to 72 milliseconds while waiting for pressure data from the external stylus.
2382 mDevice->sendSlot(FIRST_SLOT);
2383 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2384 mDevice->sendToolType(MT_TOOL_FINGER);
2385 mDevice->sendDown(centerPoint);
2386 auto waitUntil = std::chrono::system_clock::now() +
2387 std::chrono::milliseconds(ns2ms(EXTERNAL_STYLUS_DATA_TIMEOUT));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07002388 mDevice->sendSync();
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002389 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled(waitUntil));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002390
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002391 // Since the external stylus did not report a pressure value within the timeout,
2392 // it shows up as a finger pointer.
2393 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2394 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002395 WithToolType(ToolType::FINGER), WithDeviceId(touchscreenId),
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002396 WithPressure(1.f))));
2397
2398 // Change the pressure on the external stylus. Since the pressure was not present at the start
2399 // of the gesture, it is ignored for now.
2400 stylus->setPressure(200);
2401 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2402
2403 // Finish the finger gesture.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002404 mDevice->sendTrackingId(INVALID_TRACKING_ID);
2405 mDevice->sendSync();
2406 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2407 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002408 WithToolType(ToolType::FINGER))));
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002409
2410 // Start a new gesture. Since we have a valid pressure value, it shows up as a stylus.
2411 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2412 mDevice->sendToolType(MT_TOOL_FINGER);
2413 mDevice->sendDown(centerPoint);
2414 mDevice->sendSync();
2415 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2416 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002417 WithToolType(ToolType::STYLUS), WithButtonState(0),
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002418 WithDeviceId(touchscreenId), WithPressure(200.f / RAW_PRESSURE_MAX))));
2419
2420 // The external stylus did not generate any events.
2421 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2422 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002423}
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00002424
Prabir Pradhan39d60aa2023-07-13 22:01:04 +00002425TEST_F(ExternalStylusIntegrationTest, UnfusedExternalStylus) {
Prabir Pradhan3f7545f2022-10-19 16:56:39 +00002426 const Point centerPoint = mDevice->getCenterPoint();
2427
2428 // Create an external stylus device that does not support pressure. It should not affect any
2429 // touch pointers.
2430 std::unique_ptr<UinputExternalStylus> stylus = createUinputDevice<UinputExternalStylus>();
2431 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2432 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2433 const auto stylusInfo = findDeviceByName(stylus->getName());
2434 ASSERT_TRUE(stylusInfo);
2435
2436 ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2437
2438 const auto touchscreenId = mDeviceInfo.getId();
2439
2440 // Start a finger gesture and ensure a finger pointer is generated for it, without waiting for
2441 // pressure data from the external stylus.
2442 mDevice->sendSlot(FIRST_SLOT);
2443 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2444 mDevice->sendToolType(MT_TOOL_FINGER);
2445 mDevice->sendDown(centerPoint);
2446 auto waitUntil = std::chrono::system_clock::now() +
2447 std::chrono::milliseconds(ns2ms(EXTERNAL_STYLUS_DATA_TIMEOUT));
2448 mDevice->sendSync();
2449 ASSERT_NO_FATAL_FAILURE(
2450 mTestListener
2451 ->assertNotifyMotionWasCalled(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2452 WithToolType(
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002453 ToolType::FINGER),
Prabir Pradhan3f7545f2022-10-19 16:56:39 +00002454 WithButtonState(0),
2455 WithDeviceId(touchscreenId),
2456 WithPressure(1.f)),
2457 waitUntil));
2458
2459 // The external stylus did not generate any events.
2460 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2461 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
2462}
2463
Michael Wrightd02c5b62014-02-10 15:10:22 -08002464// --- InputDeviceTest ---
2465class InputDeviceTest : public testing::Test {
2466protected:
2467 static const char* DEVICE_NAME;
2468 static const char* DEVICE_LOCATION;
2469 static const int32_t DEVICE_ID;
2470 static const int32_t DEVICE_GENERATION;
2471 static const int32_t DEVICE_CONTROLLER_NUMBER;
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01002472 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002473 static const int32_t EVENTHUB_ID;
2474 static const std::string DEVICE_BLUETOOTH_ADDRESS;
2475
2476 std::shared_ptr<FakeEventHub> mFakeEventHub;
2477 sp<FakeInputReaderPolicy> mFakePolicy;
2478 std::unique_ptr<TestInputListener> mFakeListener;
2479 std::unique_ptr<InstrumentedInputReader> mReader;
2480 std::shared_ptr<InputDevice> mDevice;
2481
2482 void SetUp() override {
2483 mFakeEventHub = std::make_unique<FakeEventHub>();
2484 mFakePolicy = sp<FakeInputReaderPolicy>::make();
2485 mFakeListener = std::make_unique<TestInputListener>();
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002486 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002487 *mFakeListener);
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002488 InputDeviceIdentifier identifier;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002489 identifier.name = DEVICE_NAME;
2490 identifier.location = DEVICE_LOCATION;
2491 identifier.bluetoothAddress = DEVICE_BLUETOOTH_ADDRESS;
2492 mDevice = std::make_shared<InputDevice>(mReader->getContext(), DEVICE_ID, DEVICE_GENERATION,
2493 identifier);
2494 mReader->pushNextDevice(mDevice);
2495 mFakeEventHub->addDevice(EVENTHUB_ID, DEVICE_NAME, ftl::Flags<InputDeviceClass>(0));
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002496 mReader->loopOnce();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002497 }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002498
2499 void TearDown() override {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002500 mFakeListener.reset();
2501 mFakePolicy.clear();
2502 }
2503};
2504
2505const char* InputDeviceTest::DEVICE_NAME = "device";
2506const char* InputDeviceTest::DEVICE_LOCATION = "USB1";
2507const int32_t InputDeviceTest::DEVICE_ID = END_RESERVED_ID + 1000;
2508const int32_t InputDeviceTest::DEVICE_GENERATION = 2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002509const int32_t InputDeviceTest::DEVICE_CONTROLLER_NUMBER = 0;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002510const ftl::Flags<InputDeviceClass> InputDeviceTest::DEVICE_CLASSES =
2511 InputDeviceClass::KEYBOARD | InputDeviceClass::TOUCH | InputDeviceClass::JOYSTICK;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002512const int32_t InputDeviceTest::EVENTHUB_ID = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002513const std::string InputDeviceTest::DEVICE_BLUETOOTH_ADDRESS = "11:AA:22:BB:33:CC";
2514
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002515TEST_F(InputDeviceTest, ImmutableProperties) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002516 ASSERT_EQ(DEVICE_ID, mDevice->getId());
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002517 ASSERT_STREQ(DEVICE_NAME, mDevice->getName().c_str());
2518 ASSERT_EQ(ftl::Flags<InputDeviceClass>(0), mDevice->getClasses());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002519}
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002520
Michael Wrightd02c5b62014-02-10 15:10:22 -08002521TEST_F(InputDeviceTest, WhenDeviceCreated_EnabledIsFalse) {
2522 ASSERT_EQ(mDevice->isEnabled(), false);
2523}
2524
2525TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
2526 // Configuration.
2527 InputReaderConfiguration config;
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002528 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
Michael Wrightd02c5b62014-02-10 15:10:22 -08002529
2530 // Reset.
2531 unused += mDevice->reset(ARBITRARY_TIME);
2532
2533 NotifyDeviceResetArgs resetArgs;
2534 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2535 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
2536 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
2537
2538 // Metadata.
2539 ASSERT_TRUE(mDevice->isIgnored());
2540 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mDevice->getSources());
2541
2542 InputDeviceInfo info = mDevice->getDeviceInfo();
2543 ASSERT_EQ(DEVICE_ID, info.getId());
2544 ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
2545 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType());
2546 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources());
2547
2548 // State queries.
2549 ASSERT_EQ(0, mDevice->getMetaState());
2550
2551 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, 0))
2552 << "Ignored device should return unknown key code state.";
2553 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 0))
2554 << "Ignored device should return unknown scan code state.";
2555 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 0))
2556 << "Ignored device should return unknown switch state.";
2557
2558 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B};
2559 uint8_t flags[2] = { 0, 1 };
2560 ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, keyCodes, flags))
2561 << "Ignored device should never mark any key codes.";
2562 ASSERT_EQ(0, flags[0]) << "Flag for unsupported key should be unchanged.";
2563 ASSERT_EQ(1, flags[1]) << "Flag for unsupported key should be unchanged.";
2564}
2565
2566TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) {
2567 // Configuration.
2568 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "key", "value");
2569
2570 FakeInputMapper& mapper1 =
Arpit Singh8e6fb252023-04-06 11:49:17 +00002571 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2572 AINPUT_SOURCE_KEYBOARD);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002573 mapper1.setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC);
2574 mapper1.setMetaState(AMETA_ALT_ON);
2575 mapper1.addSupportedKeyCode(AKEYCODE_A);
2576 mapper1.addSupportedKeyCode(AKEYCODE_B);
2577 mapper1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
2578 mapper1.setKeyCodeState(AKEYCODE_B, AKEY_STATE_UP);
2579 mapper1.setScanCodeState(2, AKEY_STATE_DOWN);
2580 mapper1.setScanCodeState(3, AKEY_STATE_UP);
2581 mapper1.setSwitchState(4, AKEY_STATE_DOWN);
2582
2583 FakeInputMapper& mapper2 =
Arpit Singh8e6fb252023-04-06 11:49:17 +00002584 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2585 AINPUT_SOURCE_TOUCHSCREEN);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002586 mapper2.setMetaState(AMETA_SHIFT_ON);
2587
2588 InputReaderConfiguration config;
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002589 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
Michael Wrightd02c5b62014-02-10 15:10:22 -08002590
Harry Cuttsf13161a2023-03-08 14:15:49 +00002591 std::optional<std::string> propertyValue = mDevice->getConfiguration().getString("key");
2592 ASSERT_TRUE(propertyValue.has_value())
Michael Wrightd02c5b62014-02-10 15:10:22 -08002593 << "Device should have read configuration during configuration phase.";
Harry Cuttsf13161a2023-03-08 14:15:49 +00002594 ASSERT_EQ("value", *propertyValue);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002595
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002596 ASSERT_NO_FATAL_FAILURE(mapper1.assertConfigureWasCalled());
2597 ASSERT_NO_FATAL_FAILURE(mapper2.assertConfigureWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002598
2599 // Reset
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002600 unused += mDevice->reset(ARBITRARY_TIME);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002601 ASSERT_NO_FATAL_FAILURE(mapper1.assertResetWasCalled());
2602 ASSERT_NO_FATAL_FAILURE(mapper2.assertResetWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002603
2604 NotifyDeviceResetArgs resetArgs;
2605 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2606 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
2607 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
2608
2609 // Metadata.
2610 ASSERT_FALSE(mDevice->isIgnored());
2611 ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), mDevice->getSources());
2612
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00002613 InputDeviceInfo info = mDevice->getDeviceInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002614 ASSERT_EQ(DEVICE_ID, info.getId());
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01002615 ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002616 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType());
2617 ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources());
2618
2619 // State queries.
2620 ASSERT_EQ(AMETA_ALT_ON | AMETA_SHIFT_ON, mDevice->getMetaState())
2621 << "Should query mappers and combine meta states.";
2622
2623 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2624 << "Should return unknown key code state when source not supported.";
2625 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2626 << "Should return unknown scan code state when source not supported.";
2627 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2628 << "Should return unknown switch state when source not supported.";
2629
2630 ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, AKEYCODE_A))
2631 << "Should query mapper when source is supported.";
2632 ASSERT_EQ(AKEY_STATE_UP, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 3))
2633 << "Should query mapper when source is supported.";
2634 ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 4))
2635 << "Should query mapper when source is supported.";
2636
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002637 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2};
Michael Wrightd02c5b62014-02-10 15:10:22 -08002638 uint8_t flags[4] = { 0, 0, 0, 1 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002639 ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -08002640 << "Should do nothing when source is unsupported.";
2641 ASSERT_EQ(0, flags[0]) << "Flag should be unchanged when source is unsupported.";
2642 ASSERT_EQ(0, flags[1]) << "Flag should be unchanged when source is unsupported.";
2643 ASSERT_EQ(0, flags[2]) << "Flag should be unchanged when source is unsupported.";
2644 ASSERT_EQ(1, flags[3]) << "Flag should be unchanged when source is unsupported.";
2645
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002646 ASSERT_TRUE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -08002647 << "Should query mapper when source is supported.";
2648 ASSERT_EQ(1, flags[0]) << "Flag for supported key should be set.";
2649 ASSERT_EQ(1, flags[1]) << "Flag for supported key should be set.";
2650 ASSERT_EQ(0, flags[2]) << "Flag for unsupported key should be unchanged.";
2651 ASSERT_EQ(1, flags[3]) << "Flag for unsupported key should be unchanged.";
2652
2653 // Event handling.
2654 RawEvent event;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002655 event.deviceId = EVENTHUB_ID;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002656 unused += mDevice->process(&event, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002657
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002658 ASSERT_NO_FATAL_FAILURE(mapper1.assertProcessWasCalled());
2659 ASSERT_NO_FATAL_FAILURE(mapper2.assertProcessWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002660}
2661
Yeabkal Wubshite03e8b12023-06-27 16:23:12 -07002662TEST_F(InputDeviceTest, WakeDevice_AddsWakeFlagToProcessNotifyArgs) {
2663 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "1");
2664 FakeInputMapper& mapper =
2665 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2666 AINPUT_SOURCE_KEYBOARD);
2667 NotifyMotionArgs args1;
2668 NotifySwitchArgs args2;
2669 NotifyKeyArgs args3;
2670 mapper.setProcessResult({args1, args2, args3});
2671
2672 InputReaderConfiguration config;
2673 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
2674
2675 RawEvent event;
2676 event.deviceId = EVENTHUB_ID;
2677 std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1);
2678
2679 for (auto& arg : notifyArgs) {
2680 if (const auto notifyMotionArgs = std::get_if<NotifyMotionArgs>(&arg)) {
2681 ASSERT_EQ(POLICY_FLAG_WAKE, notifyMotionArgs->policyFlags);
2682 } else if (const auto notifySwitchArgs = std::get_if<NotifySwitchArgs>(&arg)) {
2683 ASSERT_EQ(POLICY_FLAG_WAKE, notifySwitchArgs->policyFlags);
2684 } else if (const auto notifyKeyArgs = std::get_if<NotifyKeyArgs>(&arg)) {
2685 ASSERT_EQ(POLICY_FLAG_WAKE, notifyKeyArgs->policyFlags);
2686 }
2687 }
2688}
2689
2690TEST_F(InputDeviceTest, NotWakeDevice_DoesNotAddWakeFlagToProcessNotifyArgs) {
2691 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "0");
2692 FakeInputMapper& mapper =
2693 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2694 AINPUT_SOURCE_KEYBOARD);
2695 NotifyMotionArgs args;
2696 mapper.setProcessResult({args});
2697
2698 InputReaderConfiguration config;
2699 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
2700
2701 RawEvent event;
2702 event.deviceId = EVENTHUB_ID;
2703 std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1);
2704
2705 // POLICY_FLAG_WAKE is not added to the NotifyArgs.
2706 ASSERT_EQ(0u, std::get<NotifyMotionArgs>(notifyArgs.front()).policyFlags);
2707}
2708
2709TEST_F(InputDeviceTest, NotWakeDevice_DoesNotRemoveExistingWakeFlagFromProcessNotifyArgs) {
2710 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "0");
2711 FakeInputMapper& mapper =
2712 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2713 AINPUT_SOURCE_KEYBOARD);
2714 NotifyMotionArgs args;
2715 args.policyFlags = POLICY_FLAG_WAKE;
2716 mapper.setProcessResult({args});
2717
2718 InputReaderConfiguration config;
2719 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
2720
2721 RawEvent event;
2722 event.deviceId = EVENTHUB_ID;
2723 std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1);
2724
2725 // The POLICY_FLAG_WAKE is preserved, despite the device being a non-wake device.
2726 ASSERT_EQ(POLICY_FLAG_WAKE, std::get<NotifyMotionArgs>(notifyArgs.front()).policyFlags);
2727}
2728
Arthur Hung2c9a3342019-07-23 14:18:59 +08002729// A single input device is associated with a specific display. Check that:
2730// 1. Device is disabled if the viewport corresponding to the associated display is not found
Arpit Singh48189772023-05-30 14:12:49 +00002731// 2. Device is disabled when configure API is called
Arthur Hung2c9a3342019-07-23 14:18:59 +08002732TEST_F(InputDeviceTest, Configure_AssignsDisplayPort) {
Arpit Singh8e6fb252023-04-06 11:49:17 +00002733 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2734 AINPUT_SOURCE_TOUCHSCREEN);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002735
2736 // First Configuration.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002737 std::list<NotifyArgs> unused =
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002738 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2739 /*changes=*/{});
Arthur Hung2c9a3342019-07-23 14:18:59 +08002740
2741 // Device should be enabled by default.
2742 ASSERT_TRUE(mDevice->isEnabled());
2743
2744 // Prepare associated info.
2745 constexpr uint8_t hdmi = 1;
2746 const std::string UNIQUE_ID = "local:1";
2747
2748 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002749 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002750 InputReaderConfiguration::Change::DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002751 // Device should be disabled because it is associated with a specific display via
2752 // input port <-> display port association, but the corresponding display is not found
2753 ASSERT_FALSE(mDevice->isEnabled());
2754
2755 // Prepare displays.
2756 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Harry Cutts33476232023-01-30 19:57:29 +00002757 ui::ROTATION_0, /*isActive=*/true, UNIQUE_ID, hdmi,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00002758 ViewportType::INTERNAL);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002759 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002760 InputReaderConfiguration::Change::DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002761 ASSERT_TRUE(mDevice->isEnabled());
2762
2763 // Device should be disabled after set disable.
2764 mFakePolicy->addDisabledDevice(mDevice->getId());
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002765 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002766 InputReaderConfiguration::Change::ENABLED_STATE);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002767 ASSERT_FALSE(mDevice->isEnabled());
2768
2769 // Device should still be disabled even found the associated display.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002770 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002771 InputReaderConfiguration::Change::DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002772 ASSERT_FALSE(mDevice->isEnabled());
2773}
Michael Wrightd02c5b62014-02-10 15:10:22 -08002774
Christine Franks1ba71cc2021-04-07 14:37:42 -07002775TEST_F(InputDeviceTest, Configure_AssignsDisplayUniqueId) {
2776 // Device should be enabled by default.
2777 mFakePolicy->clearViewports();
Arpit Singh8e6fb252023-04-06 11:49:17 +00002778 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2779 AINPUT_SOURCE_KEYBOARD);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002780 std::list<NotifyArgs> unused =
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002781 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2782 /*changes=*/{});
Christine Franks1ba71cc2021-04-07 14:37:42 -07002783 ASSERT_TRUE(mDevice->isEnabled());
2784
2785 // Device should be disabled because it is associated with a specific display, but the
2786 // corresponding display is not found.
Christine Franks2a2293c2022-01-18 11:51:16 -08002787 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002788 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002789 InputReaderConfiguration::Change::DISPLAY_INFO);
Christine Franks1ba71cc2021-04-07 14:37:42 -07002790 ASSERT_FALSE(mDevice->isEnabled());
2791
2792 // Device should be enabled when a display is found.
2793 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +00002794 ui::ROTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID,
Christine Franks1ba71cc2021-04-07 14:37:42 -07002795 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002796 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002797 InputReaderConfiguration::Change::DISPLAY_INFO);
Christine Franks1ba71cc2021-04-07 14:37:42 -07002798 ASSERT_TRUE(mDevice->isEnabled());
2799
2800 // Device should be disabled after set disable.
2801 mFakePolicy->addDisabledDevice(mDevice->getId());
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002802 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002803 InputReaderConfiguration::Change::ENABLED_STATE);
Christine Franks1ba71cc2021-04-07 14:37:42 -07002804 ASSERT_FALSE(mDevice->isEnabled());
2805
2806 // Device should still be disabled even found the associated display.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002807 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002808 InputReaderConfiguration::Change::DISPLAY_INFO);
Christine Franks1ba71cc2021-04-07 14:37:42 -07002809 ASSERT_FALSE(mDevice->isEnabled());
2810}
2811
Christine Franks2a2293c2022-01-18 11:51:16 -08002812TEST_F(InputDeviceTest, Configure_UniqueId_CorrectlyMatches) {
2813 mFakePolicy->clearViewports();
Arpit Singh8e6fb252023-04-06 11:49:17 +00002814 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2815 AINPUT_SOURCE_KEYBOARD);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002816 std::list<NotifyArgs> unused =
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002817 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2818 /*changes=*/{});
Christine Franks2a2293c2022-01-18 11:51:16 -08002819
Christine Franks2a2293c2022-01-18 11:51:16 -08002820 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
2821 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +00002822 ui::ROTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID,
Christine Franks2a2293c2022-01-18 11:51:16 -08002823 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002824 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00002825 InputReaderConfiguration::Change::DISPLAY_INFO);
Christine Franks2a2293c2022-01-18 11:51:16 -08002826 ASSERT_EQ(DISPLAY_UNIQUE_ID, mDevice->getAssociatedDisplayUniqueId());
2827}
2828
Siarhei Vishniakou30feb8c2022-09-28 10:48:29 -07002829/**
2830 * This test reproduces a crash caused by a dangling reference that remains after device is added
2831 * and removed. The reference is accessed in InputDevice::dump(..);
2832 */
2833TEST_F(InputDeviceTest, DumpDoesNotCrash) {
2834 constexpr int32_t TEST_EVENTHUB_ID = 10;
2835 mFakeEventHub->addDevice(TEST_EVENTHUB_ID, "Test EventHub device", InputDeviceClass::BATTERY);
2836
Harry Cutts33476232023-01-30 19:57:29 +00002837 InputDevice device(mReader->getContext(), /*id=*/1, /*generation=*/2, /*identifier=*/{});
Arpit Singh82f29a12023-06-13 15:05:53 +00002838 auto _ = device.addEventHubDevice(ARBITRARY_TIME, TEST_EVENTHUB_ID,
2839 mFakePolicy->getReaderConfiguration());
Siarhei Vishniakou30feb8c2022-09-28 10:48:29 -07002840 device.removeEventHubDevice(TEST_EVENTHUB_ID);
2841 std::string dumpStr, eventHubDevStr;
2842 device.dump(dumpStr, eventHubDevStr);
2843}
2844
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00002845TEST_F(InputDeviceTest, GetBluetoothAddress) {
2846 const auto& address = mReader->getBluetoothAddress(DEVICE_ID);
2847 ASSERT_TRUE(address);
2848 ASSERT_EQ(DEVICE_BLUETOOTH_ADDRESS, *address);
2849}
2850
Michael Wrightd02c5b62014-02-10 15:10:22 -08002851// --- SwitchInputMapperTest ---
2852
2853class SwitchInputMapperTest : public InputMapperTest {
2854protected:
2855};
2856
2857TEST_F(SwitchInputMapperTest, GetSources) {
Arpit Singhdf992eb2023-04-26 16:12:10 +00002858 SwitchInputMapper& mapper = constructAndAddMapper<SwitchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002859
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002860 ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002861}
2862
2863TEST_F(SwitchInputMapperTest, GetSwitchState) {
Arpit Singhdf992eb2023-04-26 16:12:10 +00002864 SwitchInputMapper& mapper = constructAndAddMapper<SwitchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002865
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002866 mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002867 ASSERT_EQ(1, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002868
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002869 mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002870 ASSERT_EQ(0, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002871}
2872
2873TEST_F(SwitchInputMapperTest, Process) {
Arpit Singhdf992eb2023-04-26 16:12:10 +00002874 SwitchInputMapper& mapper = constructAndAddMapper<SwitchInputMapper>();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002875 std::list<NotifyArgs> out;
2876 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_LID, 1);
2877 ASSERT_TRUE(out.empty());
2878 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_JACK_PHYSICAL_INSERT, 1);
2879 ASSERT_TRUE(out.empty());
2880 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_HEADPHONE_INSERT, 0);
2881 ASSERT_TRUE(out.empty());
2882 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002883
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002884 ASSERT_EQ(1u, out.size());
2885 const NotifySwitchArgs& args = std::get<NotifySwitchArgs>(*out.begin());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002886 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
Dan Albert1bd2fc02016-02-02 15:11:57 -08002887 ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT), args.switchValues);
2888 ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT) | (1 << SW_HEADPHONE_INSERT),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002889 args.switchMask);
2890 ASSERT_EQ(uint32_t(0), args.policyFlags);
2891}
2892
Chris Ye87143712020-11-10 05:05:58 +00002893// --- VibratorInputMapperTest ---
2894class VibratorInputMapperTest : public InputMapperTest {
2895protected:
2896 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::VIBRATOR); }
2897};
2898
2899TEST_F(VibratorInputMapperTest, GetSources) {
Arpit Singh0f26b302023-04-26 16:23:13 +00002900 VibratorInputMapper& mapper = constructAndAddMapper<VibratorInputMapper>();
Chris Ye87143712020-11-10 05:05:58 +00002901
2902 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mapper.getSources());
2903}
2904
2905TEST_F(VibratorInputMapperTest, GetVibratorIds) {
Arpit Singh0f26b302023-04-26 16:23:13 +00002906 VibratorInputMapper& mapper = constructAndAddMapper<VibratorInputMapper>();
Chris Ye87143712020-11-10 05:05:58 +00002907
2908 ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
2909}
2910
2911TEST_F(VibratorInputMapperTest, Vibrate) {
2912 constexpr uint8_t DEFAULT_AMPLITUDE = 192;
Chris Yefb552902021-02-03 17:18:37 -08002913 constexpr int32_t VIBRATION_TOKEN = 100;
Arpit Singh0f26b302023-04-26 16:23:13 +00002914 VibratorInputMapper& mapper = constructAndAddMapper<VibratorInputMapper>();
Chris Ye87143712020-11-10 05:05:58 +00002915
2916 VibrationElement pattern(2);
2917 VibrationSequence sequence(2);
2918 pattern.duration = std::chrono::milliseconds(200);
Harry Cutts33476232023-01-30 19:57:29 +00002919 pattern.channels = {{/*vibratorId=*/0, DEFAULT_AMPLITUDE / 2},
2920 {/*vibratorId=*/1, DEFAULT_AMPLITUDE}};
Chris Ye87143712020-11-10 05:05:58 +00002921 sequence.addElement(pattern);
2922 pattern.duration = std::chrono::milliseconds(500);
Harry Cutts33476232023-01-30 19:57:29 +00002923 pattern.channels = {{/*vibratorId=*/0, DEFAULT_AMPLITUDE / 4},
2924 {/*vibratorId=*/1, DEFAULT_AMPLITUDE}};
Chris Ye87143712020-11-10 05:05:58 +00002925 sequence.addElement(pattern);
2926
2927 std::vector<int64_t> timings = {0, 1};
2928 std::vector<uint8_t> amplitudes = {DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE / 2};
2929
2930 ASSERT_FALSE(mapper.isVibrating());
Chris Yefb552902021-02-03 17:18:37 -08002931 // Start vibrating
Harry Cutts33476232023-01-30 19:57:29 +00002932 std::list<NotifyArgs> out = mapper.vibrate(sequence, /*repeat=*/-1, VIBRATION_TOKEN);
Chris Ye87143712020-11-10 05:05:58 +00002933 ASSERT_TRUE(mapper.isVibrating());
Chris Yefb552902021-02-03 17:18:37 -08002934 // Verify vibrator state listener was notified.
2935 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002936 ASSERT_EQ(1u, out.size());
2937 const NotifyVibratorStateArgs& vibrateArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
2938 ASSERT_EQ(DEVICE_ID, vibrateArgs.deviceId);
2939 ASSERT_TRUE(vibrateArgs.isOn);
Chris Yefb552902021-02-03 17:18:37 -08002940 // Stop vibrating
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002941 out = mapper.cancelVibrate(VIBRATION_TOKEN);
Chris Yefb552902021-02-03 17:18:37 -08002942 ASSERT_FALSE(mapper.isVibrating());
2943 // Verify vibrator state listener was notified.
2944 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002945 ASSERT_EQ(1u, out.size());
2946 const NotifyVibratorStateArgs& cancelArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
2947 ASSERT_EQ(DEVICE_ID, cancelArgs.deviceId);
2948 ASSERT_FALSE(cancelArgs.isOn);
Chris Ye87143712020-11-10 05:05:58 +00002949}
Michael Wrightd02c5b62014-02-10 15:10:22 -08002950
Chris Yef59a2f42020-10-16 12:55:26 -07002951// --- SensorInputMapperTest ---
2952
2953class SensorInputMapperTest : public InputMapperTest {
2954protected:
2955 static const int32_t ACCEL_RAW_MIN;
2956 static const int32_t ACCEL_RAW_MAX;
2957 static const int32_t ACCEL_RAW_FUZZ;
2958 static const int32_t ACCEL_RAW_FLAT;
2959 static const int32_t ACCEL_RAW_RESOLUTION;
2960
2961 static const int32_t GYRO_RAW_MIN;
2962 static const int32_t GYRO_RAW_MAX;
2963 static const int32_t GYRO_RAW_FUZZ;
2964 static const int32_t GYRO_RAW_FLAT;
2965 static const int32_t GYRO_RAW_RESOLUTION;
2966
2967 static const float GRAVITY_MS2_UNIT;
2968 static const float DEGREE_RADIAN_UNIT;
2969
2970 void prepareAccelAxes();
2971 void prepareGyroAxes();
2972 void setAccelProperties();
2973 void setGyroProperties();
2974 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::SENSOR); }
2975};
2976
2977const int32_t SensorInputMapperTest::ACCEL_RAW_MIN = -32768;
2978const int32_t SensorInputMapperTest::ACCEL_RAW_MAX = 32768;
2979const int32_t SensorInputMapperTest::ACCEL_RAW_FUZZ = 16;
2980const int32_t SensorInputMapperTest::ACCEL_RAW_FLAT = 0;
2981const int32_t SensorInputMapperTest::ACCEL_RAW_RESOLUTION = 8192;
2982
2983const int32_t SensorInputMapperTest::GYRO_RAW_MIN = -2097152;
2984const int32_t SensorInputMapperTest::GYRO_RAW_MAX = 2097152;
2985const int32_t SensorInputMapperTest::GYRO_RAW_FUZZ = 16;
2986const int32_t SensorInputMapperTest::GYRO_RAW_FLAT = 0;
2987const int32_t SensorInputMapperTest::GYRO_RAW_RESOLUTION = 1024;
2988
2989const float SensorInputMapperTest::GRAVITY_MS2_UNIT = 9.80665f;
2990const float SensorInputMapperTest::DEGREE_RADIAN_UNIT = 0.0174533f;
2991
2992void SensorInputMapperTest::prepareAccelAxes() {
2993 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
2994 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
2995 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
2996 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
2997 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Z, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
2998 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
2999}
3000
3001void SensorInputMapperTest::prepareGyroAxes() {
3002 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RX, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
3003 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
3004 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RY, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
3005 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
3006 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RZ, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
3007 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
3008}
3009
3010void SensorInputMapperTest::setAccelProperties() {
3011 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 0, InputDeviceSensorType::ACCELEROMETER,
3012 /* sensorDataIndex */ 0);
3013 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 1, InputDeviceSensorType::ACCELEROMETER,
3014 /* sensorDataIndex */ 1);
3015 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 2, InputDeviceSensorType::ACCELEROMETER,
3016 /* sensorDataIndex */ 2);
3017 mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP);
3018 addConfigurationProperty("sensor.accelerometer.reportingMode", "0");
3019 addConfigurationProperty("sensor.accelerometer.maxDelay", "100000");
3020 addConfigurationProperty("sensor.accelerometer.minDelay", "5000");
3021 addConfigurationProperty("sensor.accelerometer.power", "1.5");
3022}
3023
3024void SensorInputMapperTest::setGyroProperties() {
3025 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 3, InputDeviceSensorType::GYROSCOPE,
3026 /* sensorDataIndex */ 0);
3027 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 4, InputDeviceSensorType::GYROSCOPE,
3028 /* sensorDataIndex */ 1);
3029 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 5, InputDeviceSensorType::GYROSCOPE,
3030 /* sensorDataIndex */ 2);
3031 mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP);
3032 addConfigurationProperty("sensor.gyroscope.reportingMode", "0");
3033 addConfigurationProperty("sensor.gyroscope.maxDelay", "100000");
3034 addConfigurationProperty("sensor.gyroscope.minDelay", "5000");
3035 addConfigurationProperty("sensor.gyroscope.power", "0.8");
3036}
3037
3038TEST_F(SensorInputMapperTest, GetSources) {
Arpit Singhfb706c32023-04-26 15:07:55 +00003039 SensorInputMapper& mapper = constructAndAddMapper<SensorInputMapper>();
Chris Yef59a2f42020-10-16 12:55:26 -07003040
3041 ASSERT_EQ(static_cast<uint32_t>(AINPUT_SOURCE_SENSOR), mapper.getSources());
3042}
3043
3044TEST_F(SensorInputMapperTest, ProcessAccelerometerSensor) {
3045 setAccelProperties();
3046 prepareAccelAxes();
Arpit Singhfb706c32023-04-26 15:07:55 +00003047 SensorInputMapper& mapper = constructAndAddMapper<SensorInputMapper>();
Chris Yef59a2f42020-10-16 12:55:26 -07003048
3049 ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::ACCELEROMETER,
3050 std::chrono::microseconds(10000),
3051 std::chrono::microseconds(0)));
Chris Yee14523a2020-12-19 13:46:00 -08003052 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003053 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, 20000);
3054 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, -20000);
3055 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Z, 40000);
3056 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
3057 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Chris Yef59a2f42020-10-16 12:55:26 -07003058
3059 NotifySensorArgs args;
3060 std::vector<float> values = {20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT,
3061 -20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT,
3062 40000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT};
3063
3064 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args));
3065 ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR);
3066 ASSERT_EQ(args.deviceId, DEVICE_ID);
3067 ASSERT_EQ(args.sensorType, InputDeviceSensorType::ACCELEROMETER);
3068 ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
3069 ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME);
3070 ASSERT_EQ(args.values, values);
3071 mapper.flushSensor(InputDeviceSensorType::ACCELEROMETER);
3072}
3073
3074TEST_F(SensorInputMapperTest, ProcessGyroscopeSensor) {
3075 setGyroProperties();
3076 prepareGyroAxes();
Arpit Singhfb706c32023-04-26 15:07:55 +00003077 SensorInputMapper& mapper = constructAndAddMapper<SensorInputMapper>();
Chris Yef59a2f42020-10-16 12:55:26 -07003078
3079 ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::GYROSCOPE,
3080 std::chrono::microseconds(10000),
3081 std::chrono::microseconds(0)));
Chris Yee14523a2020-12-19 13:46:00 -08003082 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003083 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RX, 20000);
3084 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RY, -20000);
3085 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RZ, 40000);
3086 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
3087 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Chris Yef59a2f42020-10-16 12:55:26 -07003088
3089 NotifySensorArgs args;
3090 std::vector<float> values = {20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT,
3091 -20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT,
3092 40000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT};
3093
3094 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args));
3095 ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR);
3096 ASSERT_EQ(args.deviceId, DEVICE_ID);
3097 ASSERT_EQ(args.sensorType, InputDeviceSensorType::GYROSCOPE);
3098 ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
3099 ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME);
3100 ASSERT_EQ(args.values, values);
3101 mapper.flushSensor(InputDeviceSensorType::GYROSCOPE);
3102}
3103
Michael Wrightd02c5b62014-02-10 15:10:22 -08003104// --- KeyboardInputMapperTest ---
3105
3106class KeyboardInputMapperTest : public InputMapperTest {
3107protected:
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003108 const std::string UNIQUE_ID = "local:0";
Zixuan Qufecb6062022-11-12 04:44:31 +00003109 const KeyboardLayoutInfo DEVICE_KEYBOARD_LAYOUT_INFO = KeyboardLayoutInfo("en-US", "qwerty");
Michael Wrighta9cf4192022-12-01 23:46:39 +00003110 void prepareDisplay(ui::Rotation orientation);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003111
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003112 void testDPadKeyRotation(KeyboardInputMapper& mapper, int32_t originalScanCode,
Arthur Hung2c9a3342019-07-23 14:18:59 +08003113 int32_t originalKeyCode, int32_t rotatedKeyCode,
3114 int32_t displayId = ADISPLAY_ID_NONE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003115};
3116
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003117/* Similar to setDisplayInfoAndReconfigure, but pre-populates all parameters except for the
3118 * orientation.
3119 */
Michael Wrighta9cf4192022-12-01 23:46:39 +00003120void KeyboardInputMapperTest::prepareDisplay(ui::Rotation orientation) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003121 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation, UNIQUE_ID,
3122 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003123}
3124
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003125void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper& mapper,
Arthur Hung2c9a3342019-07-23 14:18:59 +08003126 int32_t originalScanCode, int32_t originalKeyCode,
3127 int32_t rotatedKeyCode, int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003128 NotifyKeyArgs args;
3129
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003130 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003131 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3132 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3133 ASSERT_EQ(originalScanCode, args.scanCode);
3134 ASSERT_EQ(rotatedKeyCode, args.keyCode);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003135 ASSERT_EQ(displayId, args.displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003136
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003137 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003138 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3139 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3140 ASSERT_EQ(originalScanCode, args.scanCode);
3141 ASSERT_EQ(rotatedKeyCode, args.keyCode);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003142 ASSERT_EQ(displayId, args.displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003143}
3144
Michael Wrightd02c5b62014-02-10 15:10:22 -08003145TEST_F(KeyboardInputMapperTest, GetSources) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003146 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003147 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003148 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003149
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003150 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003151}
3152
3153TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) {
3154 const int32_t USAGE_A = 0x070004;
3155 const int32_t USAGE_UNKNOWN = 0x07ffff;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003156 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3157 mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
Chris Yea52ade12020-08-27 16:49:20 -07003158 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, POLICY_FLAG_WAKE);
3159 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, POLICY_FLAG_WAKE);
3160 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, POLICY_FLAG_WAKE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003161
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003162 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003163 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003164 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003165 // Initial metastate is AMETA_NONE.
3166 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003167
3168 // Key down by scan code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003169 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003170 NotifyKeyArgs args;
3171 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3172 ASSERT_EQ(DEVICE_ID, args.deviceId);
3173 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3174 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3175 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3176 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3177 ASSERT_EQ(KEY_HOME, args.scanCode);
3178 ASSERT_EQ(AMETA_NONE, args.metaState);
3179 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3180 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3181 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3182
3183 // Key up by scan code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003184 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003185 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3186 ASSERT_EQ(DEVICE_ID, args.deviceId);
3187 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3188 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3189 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3190 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3191 ASSERT_EQ(KEY_HOME, args.scanCode);
3192 ASSERT_EQ(AMETA_NONE, args.metaState);
3193 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3194 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3195 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3196
3197 // Key down by usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003198 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_A);
3199 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, 0, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003200 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3201 ASSERT_EQ(DEVICE_ID, args.deviceId);
3202 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3203 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3204 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3205 ASSERT_EQ(AKEYCODE_A, args.keyCode);
3206 ASSERT_EQ(0, args.scanCode);
3207 ASSERT_EQ(AMETA_NONE, args.metaState);
3208 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3209 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3210 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3211
3212 // Key up by usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003213 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_A);
3214 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003215 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3216 ASSERT_EQ(DEVICE_ID, args.deviceId);
3217 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3218 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3219 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3220 ASSERT_EQ(AKEYCODE_A, args.keyCode);
3221 ASSERT_EQ(0, args.scanCode);
3222 ASSERT_EQ(AMETA_NONE, args.metaState);
3223 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3224 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3225 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3226
3227 // Key down with unknown scan code or usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003228 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
3229 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UNKNOWN, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003230 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3231 ASSERT_EQ(DEVICE_ID, args.deviceId);
3232 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3233 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3234 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3235 ASSERT_EQ(0, args.keyCode);
3236 ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
3237 ASSERT_EQ(AMETA_NONE, args.metaState);
3238 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3239 ASSERT_EQ(0U, args.policyFlags);
3240 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3241
3242 // Key up with unknown scan code or usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003243 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
3244 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_UNKNOWN, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003245 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3246 ASSERT_EQ(DEVICE_ID, args.deviceId);
3247 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3248 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3249 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3250 ASSERT_EQ(0, args.keyCode);
3251 ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
3252 ASSERT_EQ(AMETA_NONE, args.metaState);
3253 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3254 ASSERT_EQ(0U, args.policyFlags);
3255 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3256}
3257
Vaibhav Devmuraricbba14c2022-10-10 16:54:49 +00003258TEST_F(KeyboardInputMapperTest, Process_KeyRemapping) {
3259 mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
3260 mFakeEventHub->addKey(EVENTHUB_ID, KEY_B, 0, AKEYCODE_B, 0);
3261 mFakeEventHub->addKeyRemapping(EVENTHUB_ID, AKEYCODE_A, AKEYCODE_B);
3262
3263 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003264 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Vaibhav Devmuraricbba14c2022-10-10 16:54:49 +00003265 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3266
3267 // Key down by scan code.
3268 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_A, 1);
3269 NotifyKeyArgs args;
3270 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3271 ASSERT_EQ(AKEYCODE_B, args.keyCode);
3272
3273 // Key up by scan code.
3274 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_A, 0);
3275 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3276 ASSERT_EQ(AKEYCODE_B, args.keyCode);
3277}
3278
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003279/**
3280 * Ensure that the readTime is set to the time when the EV_KEY is received.
3281 */
3282TEST_F(KeyboardInputMapperTest, Process_SendsReadTime) {
3283 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3284
3285 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003286 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003287 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3288 NotifyKeyArgs args;
3289
3290 // Key down
Harry Cutts33476232023-01-30 19:57:29 +00003291 process(mapper, ARBITRARY_TIME, /*readTime=*/12, EV_KEY, KEY_HOME, 1);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003292 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3293 ASSERT_EQ(12, args.readTime);
3294
3295 // Key up
Harry Cutts33476232023-01-30 19:57:29 +00003296 process(mapper, ARBITRARY_TIME, /*readTime=*/15, EV_KEY, KEY_HOME, 1);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003297 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3298 ASSERT_EQ(15, args.readTime);
3299}
3300
Michael Wrightd02c5b62014-02-10 15:10:22 -08003301TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003302 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFTSHIFT, 0, AKEYCODE_SHIFT_LEFT, 0);
3303 mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
Chris Yea52ade12020-08-27 16:49:20 -07003304 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, 0);
3305 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, 0);
3306 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003307
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003308 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003309 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003310 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003311
Arthur Hung95f68612022-04-07 14:08:22 +08003312 // Initial metastate is AMETA_NONE.
3313 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003314
3315 // Metakey down.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003316 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_LEFTSHIFT, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003317 NotifyKeyArgs args;
3318 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3319 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003320 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
arthurhungdcef2dc2020-08-11 14:47:50 +08003321 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertUpdateGlobalMetaStateWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003322
3323 // Key down.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003324 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_A, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003325 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3326 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003327 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003328
3329 // Key up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003330 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, KEY_A, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003331 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3332 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003333 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003334
3335 // Metakey up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003336 process(mapper, ARBITRARY_TIME + 3, READ_TIME, EV_KEY, KEY_LEFTSHIFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003337 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3338 ASSERT_EQ(AMETA_NONE, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003339 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
arthurhungdcef2dc2020-08-11 14:47:50 +08003340 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertUpdateGlobalMetaStateWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003341}
3342
3343TEST_F(KeyboardInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateDPad) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003344 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3345 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3346 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3347 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003348
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003349 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003350 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003351 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003352
Michael Wrighta9cf4192022-12-01 23:46:39 +00003353 prepareDisplay(ui::ROTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003354 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3355 KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP));
3356 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3357 KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT));
3358 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3359 KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN));
3360 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3361 KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT));
3362}
3363
3364TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003365 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3366 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3367 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3368 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003369
Michael Wrightd02c5b62014-02-10 15:10:22 -08003370 addConfigurationProperty("keyboard.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003371 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003372 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003373 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003374
Michael Wrighta9cf4192022-12-01 23:46:39 +00003375 prepareDisplay(ui::ROTATION_0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003376 ASSERT_NO_FATAL_FAILURE(
3377 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID));
3378 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3379 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3380 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3381 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3382 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3383 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003384
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003385 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003386 prepareDisplay(ui::ROTATION_90);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003387 ASSERT_NO_FATAL_FAILURE(
3388 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3389 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3390 AKEYCODE_DPAD_UP, DISPLAY_ID));
3391 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3392 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3393 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3394 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003395
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003396 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003397 prepareDisplay(ui::ROTATION_180);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003398 ASSERT_NO_FATAL_FAILURE(
3399 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3400 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3401 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3402 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3403 AKEYCODE_DPAD_UP, DISPLAY_ID));
3404 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3405 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003406
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003407 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003408 prepareDisplay(ui::ROTATION_270);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003409 ASSERT_NO_FATAL_FAILURE(
3410 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3411 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3412 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3413 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3414 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3415 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3416 AKEYCODE_DPAD_UP, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003417
3418 // Special case: if orientation changes while key is down, we still emit the same keycode
3419 // in the key up as we did in the key down.
3420 NotifyKeyArgs args;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003421 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003422 prepareDisplay(ui::ROTATION_270);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003423 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003424 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3425 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3426 ASSERT_EQ(KEY_UP, args.scanCode);
3427 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
3428
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003429 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003430 prepareDisplay(ui::ROTATION_180);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003431 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003432 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3433 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3434 ASSERT_EQ(KEY_UP, args.scanCode);
3435 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
3436}
3437
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003438TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_NotOrientationAware) {
3439 // If the keyboard is not orientation aware,
3440 // key events should not be associated with a specific display id
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003441 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003442
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003443 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003444 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003445 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003446 NotifyKeyArgs args;
3447
3448 // Display id should be ADISPLAY_ID_NONE without any display configuration.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003449 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003450 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003451 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003452 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3453 ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
3454
Michael Wrighta9cf4192022-12-01 23:46:39 +00003455 prepareDisplay(ui::ROTATION_0);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003456 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003457 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003458 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003459 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3460 ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
3461}
3462
3463TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_OrientationAware) {
3464 // If the keyboard is orientation aware,
3465 // key events should be associated with the internal viewport
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003466 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003467
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003468 addConfigurationProperty("keyboard.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003469 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003470 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003471 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003472 NotifyKeyArgs args;
3473
3474 // Display id should be ADISPLAY_ID_NONE without any display configuration.
3475 // ^--- already checked by the previous test
3476
Michael Wrighta9cf4192022-12-01 23:46:39 +00003477 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003478 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003479 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003480 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003481 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003482 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3483 ASSERT_EQ(DISPLAY_ID, args.displayId);
3484
3485 constexpr int32_t newDisplayId = 2;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003486 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003487 setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003488 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003489 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003490 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003491 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003492 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3493 ASSERT_EQ(newDisplayId, args.displayId);
3494}
3495
Michael Wrightd02c5b62014-02-10 15:10:22 -08003496TEST_F(KeyboardInputMapperTest, GetKeyCodeState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003497 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003498 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003499 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003500
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003501 mFakeEventHub->setKeyCodeState(EVENTHUB_ID, AKEYCODE_A, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003502 ASSERT_EQ(1, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003503
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003504 mFakeEventHub->setKeyCodeState(EVENTHUB_ID, AKEYCODE_A, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003505 ASSERT_EQ(0, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003506}
3507
Philip Junker4af3b3d2021-12-14 10:36:55 +01003508TEST_F(KeyboardInputMapperTest, GetKeyCodeForKeyLocation) {
3509 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003510 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Philip Junker4af3b3d2021-12-14 10:36:55 +01003511 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3512
3513 mFakeEventHub->addKeyCodeMapping(EVENTHUB_ID, AKEYCODE_Y, AKEYCODE_Z);
3514 ASSERT_EQ(AKEYCODE_Z, mapper.getKeyCodeForKeyLocation(AKEYCODE_Y))
3515 << "If a mapping is available, the result is equal to the mapping";
3516
3517 ASSERT_EQ(AKEYCODE_A, mapper.getKeyCodeForKeyLocation(AKEYCODE_A))
3518 << "If no mapping is available, the result is the key location";
3519}
3520
Michael Wrightd02c5b62014-02-10 15:10:22 -08003521TEST_F(KeyboardInputMapperTest, GetScanCodeState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003522 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003523 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003524 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003525
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003526 mFakeEventHub->setScanCodeState(EVENTHUB_ID, KEY_A, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003527 ASSERT_EQ(1, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003528
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003529 mFakeEventHub->setScanCodeState(EVENTHUB_ID, KEY_A, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003530 ASSERT_EQ(0, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003531}
3532
3533TEST_F(KeyboardInputMapperTest, MarkSupportedKeyCodes) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003534 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003535 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003536 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003537
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003538 mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003539
Michael Wrightd02c5b62014-02-10 15:10:22 -08003540 uint8_t flags[2] = { 0, 0 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07003541 ASSERT_TRUE(mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, {AKEYCODE_A, AKEYCODE_B}, flags));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003542 ASSERT_TRUE(flags[0]);
3543 ASSERT_FALSE(flags[1]);
3544}
3545
3546TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003547 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3548 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3549 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3550 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3551 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3552 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003553
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003554 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003555 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003556 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003557 // Initial metastate is AMETA_NONE.
3558 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003559
3560 // Initialization should have turned all of the lights off.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003561 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3562 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3563 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003564
3565 // Toggle caps lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003566 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3567 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003568 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3569 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3570 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003571 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003572
3573 // Toggle num lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003574 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3575 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003576 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3577 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3578 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003579 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003580
3581 // Toggle caps lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003582 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3583 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003584 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3585 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3586 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003587 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003588
3589 // Toggle scroll lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003590 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3591 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003592 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3593 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3594 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003595 ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003596
3597 // Toggle num lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003598 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3599 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003600 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3601 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3602 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003603 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003604
3605 // Toggle scroll lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003606 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3607 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003608 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3609 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3610 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003611 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003612}
3613
Chris Yea52ade12020-08-27 16:49:20 -07003614TEST_F(KeyboardInputMapperTest, NoMetaStateWhenMetaKeysNotPresent) {
3615 mFakeEventHub->addKey(EVENTHUB_ID, BTN_A, 0, AKEYCODE_BUTTON_A, 0);
3616 mFakeEventHub->addKey(EVENTHUB_ID, BTN_B, 0, AKEYCODE_BUTTON_B, 0);
3617 mFakeEventHub->addKey(EVENTHUB_ID, BTN_X, 0, AKEYCODE_BUTTON_X, 0);
3618 mFakeEventHub->addKey(EVENTHUB_ID, BTN_Y, 0, AKEYCODE_BUTTON_Y, 0);
3619
3620 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003621 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Chris Yea52ade12020-08-27 16:49:20 -07003622 AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
3623
Chris Yea52ade12020-08-27 16:49:20 -07003624 // Meta state should be AMETA_NONE after reset
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003625 std::list<NotifyArgs> unused = mapper.reset(ARBITRARY_TIME);
Chris Yea52ade12020-08-27 16:49:20 -07003626 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3627 // Meta state should be AMETA_NONE with update, as device doesn't have the keys.
3628 mapper.updateMetaState(AKEYCODE_NUM_LOCK);
3629 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3630
3631 NotifyKeyArgs args;
3632 // Press button "A"
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003633 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_A, 1);
Chris Yea52ade12020-08-27 16:49:20 -07003634 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3635 ASSERT_EQ(AMETA_NONE, args.metaState);
3636 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3637 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3638 ASSERT_EQ(AKEYCODE_BUTTON_A, args.keyCode);
3639
3640 // Button up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003641 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, BTN_A, 0);
Chris Yea52ade12020-08-27 16:49:20 -07003642 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3643 ASSERT_EQ(AMETA_NONE, args.metaState);
3644 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3645 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3646 ASSERT_EQ(AKEYCODE_BUTTON_A, args.keyCode);
3647}
3648
Arthur Hung2c9a3342019-07-23 14:18:59 +08003649TEST_F(KeyboardInputMapperTest, Configure_AssignsDisplayPort) {
3650 // keyboard 1.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003651 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3652 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3653 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3654 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003655
3656 // keyboard 2.
3657 const std::string USB2 = "USB2";
arthurhungdcef2dc2020-08-11 14:47:50 +08003658 const std::string DEVICE_NAME2 = "KEYBOARD2";
Arthur Hung2c9a3342019-07-23 14:18:59 +08003659 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003660 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
arthurhungdcef2dc2020-08-11 14:47:50 +08003661 std::shared_ptr<InputDevice> device2 =
3662 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07003663 ftl::Flags<InputDeviceClass>(0));
arthurhungdcef2dc2020-08-11 14:47:50 +08003664
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003665 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3666 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3667 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3668 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003669
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003670 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003671 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003672 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003673
Arpit Singh67ca6842023-04-26 14:43:16 +00003674 device2->addEmptyEventHubDevice(SECOND_EVENTHUB_ID);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003675 KeyboardInputMapper& mapper2 =
Arpit Singh67ca6842023-04-26 14:43:16 +00003676 device2->constructAndAddMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID,
3677 mFakePolicy
3678 ->getReaderConfiguration(),
3679 AINPUT_SOURCE_KEYBOARD,
3680 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003681 std::list<NotifyArgs> unused =
3682 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00003683 /*changes=*/{});
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003684 unused += device2->reset(ARBITRARY_TIME);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003685
3686 // Prepared displays and associated info.
3687 constexpr uint8_t hdmi1 = 0;
3688 constexpr uint8_t hdmi2 = 1;
3689 const std::string SECONDARY_UNIQUE_ID = "local:1";
3690
3691 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
3692 mFakePolicy->addInputPortAssociation(USB2, hdmi2);
3693
3694 // No associated display viewport found, should disable the device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003695 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00003696 InputReaderConfiguration::Change::DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003697 ASSERT_FALSE(device2->isEnabled());
3698
3699 // Prepare second display.
3700 constexpr int32_t newDisplayId = 2;
Michael Wrighta9cf4192022-12-01 23:46:39 +00003701 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003702 UNIQUE_ID, hdmi1, ViewportType::INTERNAL);
Michael Wrighta9cf4192022-12-01 23:46:39 +00003703 setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003704 SECONDARY_UNIQUE_ID, hdmi2, ViewportType::EXTERNAL);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003705 // Default device will reconfigure above, need additional reconfiguration for another device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003706 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00003707 InputReaderConfiguration::Change::DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003708
3709 // Device should be enabled after the associated display is found.
3710 ASSERT_TRUE(mDevice->isEnabled());
3711 ASSERT_TRUE(device2->isEnabled());
3712
3713 // Test pad key events
3714 ASSERT_NO_FATAL_FAILURE(
3715 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID));
3716 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3717 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3718 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3719 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3720 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3721 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3722
3723 ASSERT_NO_FATAL_FAILURE(
3724 testDPadKeyRotation(mapper2, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, newDisplayId));
3725 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3726 AKEYCODE_DPAD_RIGHT, newDisplayId));
3727 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3728 AKEYCODE_DPAD_DOWN, newDisplayId));
3729 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3730 AKEYCODE_DPAD_LEFT, newDisplayId));
3731}
Michael Wrightd02c5b62014-02-10 15:10:22 -08003732
arthurhungc903df12020-08-11 15:08:42 +08003733TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleAfterReattach) {
3734 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3735 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3736 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3737 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3738 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3739 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3740
3741 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003742 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
arthurhungc903df12020-08-11 15:08:42 +08003743 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003744 // Initial metastate is AMETA_NONE.
3745 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
arthurhungc903df12020-08-11 15:08:42 +08003746
3747 // Initialization should have turned all of the lights off.
3748 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3749 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3750 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3751
3752 // Toggle caps lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003753 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3754 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003755 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3756 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
3757
3758 // Toggle num lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003759 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3760 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003761 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3762 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState());
3763
3764 // Toggle scroll lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003765 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3766 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003767 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3768 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
3769
3770 mFakeEventHub->removeDevice(EVENTHUB_ID);
3771 mReader->loopOnce();
3772
3773 // keyboard 2 should default toggle keys.
3774 const std::string USB2 = "USB2";
3775 const std::string DEVICE_NAME2 = "KEYBOARD2";
3776 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
3777 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
3778 std::shared_ptr<InputDevice> device2 =
3779 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07003780 ftl::Flags<InputDeviceClass>(0));
arthurhungc903df12020-08-11 15:08:42 +08003781 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3782 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/);
3783 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3784 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3785 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3786 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3787
Arpit Singh67ca6842023-04-26 14:43:16 +00003788 device2->addEmptyEventHubDevice(SECOND_EVENTHUB_ID);
arthurhung6fe95782020-10-05 22:41:16 +08003789 KeyboardInputMapper& mapper2 =
Arpit Singh67ca6842023-04-26 14:43:16 +00003790 device2->constructAndAddMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID,
3791 mFakePolicy
3792 ->getReaderConfiguration(),
3793 AINPUT_SOURCE_KEYBOARD,
3794 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003795 std::list<NotifyArgs> unused =
3796 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00003797 /*changes=*/{});
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003798 unused += device2->reset(ARBITRARY_TIME);
arthurhungc903df12020-08-11 15:08:42 +08003799
3800 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_CAPSL));
3801 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_NUML));
3802 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_SCROLLL));
arthurhung6fe95782020-10-05 22:41:16 +08003803 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON,
3804 mapper2.getMetaState());
arthurhungc903df12020-08-11 15:08:42 +08003805}
3806
Arthur Hungcb40a002021-08-03 14:31:01 +00003807TEST_F(KeyboardInputMapperTest, Process_toggleCapsLockState) {
3808 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3809 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3810 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3811
3812 // Suppose we have two mappers. (DPAD + KEYBOARD)
Arpit Singh67ca6842023-04-26 14:43:16 +00003813 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_DPAD,
Arthur Hungcb40a002021-08-03 14:31:01 +00003814 AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
3815 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003816 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Arthur Hungcb40a002021-08-03 14:31:01 +00003817 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003818 // Initial metastate is AMETA_NONE.
3819 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Arthur Hungcb40a002021-08-03 14:31:01 +00003820
3821 mReader->toggleCapsLockState(DEVICE_ID);
3822 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
3823}
3824
Arthur Hungfb3cc112022-04-13 07:39:50 +00003825TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleInMultiDevices) {
3826 // keyboard 1.
3827 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3828 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3829 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3830 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3831 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3832 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3833
3834 KeyboardInputMapper& mapper1 =
Arpit Singh67ca6842023-04-26 14:43:16 +00003835 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Arthur Hungfb3cc112022-04-13 07:39:50 +00003836 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3837
3838 // keyboard 2.
3839 const std::string USB2 = "USB2";
3840 const std::string DEVICE_NAME2 = "KEYBOARD2";
3841 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
3842 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
3843 std::shared_ptr<InputDevice> device2 =
3844 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
3845 ftl::Flags<InputDeviceClass>(0));
3846 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3847 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/);
3848 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3849 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3850 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3851 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3852
Arpit Singh67ca6842023-04-26 14:43:16 +00003853 device2->addEmptyEventHubDevice(SECOND_EVENTHUB_ID);
Arthur Hungfb3cc112022-04-13 07:39:50 +00003854 KeyboardInputMapper& mapper2 =
Arpit Singh67ca6842023-04-26 14:43:16 +00003855 device2->constructAndAddMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID,
3856 mFakePolicy
3857 ->getReaderConfiguration(),
3858 AINPUT_SOURCE_KEYBOARD,
3859 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003860 std::list<NotifyArgs> unused =
3861 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00003862 /*changes=*/{});
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003863 unused += device2->reset(ARBITRARY_TIME);
Arthur Hungfb3cc112022-04-13 07:39:50 +00003864
Arthur Hung95f68612022-04-07 14:08:22 +08003865 // Initial metastate is AMETA_NONE.
3866 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3867 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3868
3869 // Toggle num lock on and off.
3870 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3871 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Arthur Hungfb3cc112022-04-13 07:39:50 +00003872 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3873 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper1.getMetaState());
3874 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper2.getMetaState());
3875
3876 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3877 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
3878 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3879 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3880 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3881
3882 // Toggle caps lock on and off.
3883 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3884 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
3885 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3886 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper1.getMetaState());
3887 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper2.getMetaState());
3888
3889 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3890 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
3891 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3892 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3893 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3894
3895 // Toggle scroll lock on and off.
3896 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3897 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
3898 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3899 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper1.getMetaState());
3900 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper2.getMetaState());
3901
3902 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3903 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
3904 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3905 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3906 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3907}
3908
Arthur Hung2141d542022-08-23 07:45:21 +00003909TEST_F(KeyboardInputMapperTest, Process_DisabledDevice) {
3910 const int32_t USAGE_A = 0x070004;
3911 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3912 mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
3913
3914 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003915 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Arthur Hung2141d542022-08-23 07:45:21 +00003916 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3917 // Key down by scan code.
3918 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
3919 NotifyKeyArgs args;
3920 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3921 ASSERT_EQ(DEVICE_ID, args.deviceId);
3922 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3923 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3924 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3925 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3926 ASSERT_EQ(KEY_HOME, args.scanCode);
3927 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3928
3929 // Disable device, it should synthesize cancellation events for down events.
3930 mFakePolicy->addDisabledDevice(DEVICE_ID);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00003931 configureDevice(InputReaderConfiguration::Change::ENABLED_STATE);
Arthur Hung2141d542022-08-23 07:45:21 +00003932
3933 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3934 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3935 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3936 ASSERT_EQ(KEY_HOME, args.scanCode);
3937 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED, args.flags);
3938}
3939
Zixuan Qufecb6062022-11-12 04:44:31 +00003940TEST_F(KeyboardInputMapperTest, Configure_AssignKeyboardLayoutInfo) {
Arpit Singh67ca6842023-04-26 14:43:16 +00003941 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3942 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Zixuan Qufecb6062022-11-12 04:44:31 +00003943 std::list<NotifyArgs> unused =
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00003944 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3945 /*changes=*/{});
Zixuan Qufecb6062022-11-12 04:44:31 +00003946
Vaibhav Devmurari0a6fee82023-04-11 18:53:04 +00003947 uint32_t generation = mReader->getContext()->getGeneration();
Zixuan Qufecb6062022-11-12 04:44:31 +00003948 mFakePolicy->addKeyboardLayoutAssociation(DEVICE_LOCATION, DEVICE_KEYBOARD_LAYOUT_INFO);
3949
3950 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00003951 InputReaderConfiguration::Change::KEYBOARD_LAYOUT_ASSOCIATION);
Zixuan Qufecb6062022-11-12 04:44:31 +00003952
3953 InputDeviceInfo deviceInfo = mDevice->getDeviceInfo();
3954 ASSERT_EQ(DEVICE_KEYBOARD_LAYOUT_INFO.languageTag,
3955 deviceInfo.getKeyboardLayoutInfo()->languageTag);
3956 ASSERT_EQ(DEVICE_KEYBOARD_LAYOUT_INFO.layoutType,
3957 deviceInfo.getKeyboardLayoutInfo()->layoutType);
Vaibhav Devmurari0a6fee82023-04-11 18:53:04 +00003958 ASSERT_TRUE(mReader->getContext()->getGeneration() != generation);
3959
3960 // Call change layout association with the same values: Generation shouldn't change
3961 generation = mReader->getContext()->getGeneration();
3962 mFakePolicy->addKeyboardLayoutAssociation(DEVICE_LOCATION, DEVICE_KEYBOARD_LAYOUT_INFO);
3963 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3964 InputReaderConfiguration::Change::KEYBOARD_LAYOUT_ASSOCIATION);
3965 ASSERT_TRUE(mReader->getContext()->getGeneration() == generation);
Zixuan Qufecb6062022-11-12 04:44:31 +00003966}
3967
Vaibhav Devmurari7fb41132023-01-02 13:30:26 +00003968TEST_F(KeyboardInputMapperTest, LayoutInfoCorrectlyMapped) {
3969 mFakeEventHub->setRawLayoutInfo(EVENTHUB_ID,
3970 RawLayoutInfo{.languageTag = "en", .layoutType = "extended"});
3971
3972 // Configuration
Arpit Singh67ca6842023-04-26 14:43:16 +00003973 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Vaibhav Devmurari7fb41132023-01-02 13:30:26 +00003974 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3975 InputReaderConfiguration config;
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00003976 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
Vaibhav Devmurari7fb41132023-01-02 13:30:26 +00003977
3978 ASSERT_EQ("en", mDevice->getDeviceInfo().getKeyboardLayoutInfo()->languageTag);
3979 ASSERT_EQ("extended", mDevice->getDeviceInfo().getKeyboardLayoutInfo()->layoutType);
3980}
3981
Justin Chung71ddb432023-03-27 04:29:07 +00003982TEST_F(KeyboardInputMapperTest, Process_GesureEventToSetFlagKeepTouchMode) {
3983 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, POLICY_FLAG_GESTURE);
3984 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00003985 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Justin Chung71ddb432023-03-27 04:29:07 +00003986 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3987 NotifyKeyArgs args;
3988
3989 // Key down
3990 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_LEFT, 1);
3991 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3992 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_KEEP_TOUCH_MODE, args.flags);
3993}
3994
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003995// --- KeyboardInputMapperTest_ExternalDevice ---
3996
3997class KeyboardInputMapperTest_ExternalDevice : public InputMapperTest {
3998protected:
Chris Yea52ade12020-08-27 16:49:20 -07003999 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004000};
4001
4002TEST_F(KeyboardInputMapperTest_ExternalDevice, WakeBehavior) {
Vaibhav Devmurari16257862023-03-06 10:06:32 +00004003 // For external devices, keys will trigger wake on key down. Media keys should also trigger
4004 // wake if triggered from external devices.
Powei Fengd041c5d2019-05-03 17:11:33 -07004005
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004006 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, 0);
4007 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, 0);
4008 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAYPAUSE, 0, AKEYCODE_MEDIA_PLAY_PAUSE,
4009 POLICY_FLAG_WAKE);
Powei Fengd041c5d2019-05-03 17:11:33 -07004010
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004011 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00004012 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004013 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Powei Fengd041c5d2019-05-03 17:11:33 -07004014
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004015 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004016 NotifyKeyArgs args;
4017 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4018 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4019
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004020 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004021 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4022 ASSERT_EQ(uint32_t(0), args.policyFlags);
4023
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004024 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAY, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004025 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Vaibhav Devmurari16257862023-03-06 10:06:32 +00004026 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
Powei Fengd041c5d2019-05-03 17:11:33 -07004027
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004028 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAY, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004029 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4030 ASSERT_EQ(uint32_t(0), args.policyFlags);
4031
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004032 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAYPAUSE, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004033 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4034 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4035
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004036 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAYPAUSE, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004037 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4038 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4039}
4040
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004041TEST_F(KeyboardInputMapperTest_ExternalDevice, DoNotWakeByDefaultBehavior) {
Powei Fengd041c5d2019-05-03 17:11:33 -07004042 // Tv Remote key's wake behavior is prescribed by the keylayout file.
Powei Fengd041c5d2019-05-03 17:11:33 -07004043
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004044 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
4045 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
4046 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, POLICY_FLAG_WAKE);
Powei Fengd041c5d2019-05-03 17:11:33 -07004047
Powei Fengd041c5d2019-05-03 17:11:33 -07004048 addConfigurationProperty("keyboard.doNotWakeByDefault", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004049 KeyboardInputMapper& mapper =
Arpit Singh67ca6842023-04-26 14:43:16 +00004050 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004051 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Powei Fengd041c5d2019-05-03 17:11:33 -07004052
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004053 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004054 NotifyKeyArgs args;
4055 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4056 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4057
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004058 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004059 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4060 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4061
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004062 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_DOWN, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004063 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4064 ASSERT_EQ(uint32_t(0), args.policyFlags);
4065
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004066 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_DOWN, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004067 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4068 ASSERT_EQ(uint32_t(0), args.policyFlags);
4069
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004070 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAY, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07004071 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4072 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4073
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004074 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAY, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07004075 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
4076 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
4077}
4078
Michael Wrightd02c5b62014-02-10 15:10:22 -08004079// --- CursorInputMapperTest ---
4080
4081class CursorInputMapperTest : public InputMapperTest {
4082protected:
4083 static const int32_t TRACKBALL_MOVEMENT_THRESHOLD;
4084
Michael Wright17db18e2020-06-26 20:51:44 +01004085 std::shared_ptr<FakePointerController> mFakePointerController;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004086
Chris Yea52ade12020-08-27 16:49:20 -07004087 void SetUp() override {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004088 InputMapperTest::SetUp();
4089
Michael Wright17db18e2020-06-26 20:51:44 +01004090 mFakePointerController = std::make_shared<FakePointerController>();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00004091 mFakePolicy->setPointerController(mFakePointerController);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004092 }
4093
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004094 void testMotionRotation(CursorInputMapper& mapper, int32_t originalX, int32_t originalY,
4095 int32_t rotatedX, int32_t rotatedY);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004096
Michael Wrighta9cf4192022-12-01 23:46:39 +00004097 void prepareDisplay(ui::Rotation orientation) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004098 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation,
4099 DISPLAY_UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
4100 }
4101
4102 void prepareSecondaryDisplay() {
4103 setDisplayInfoAndReconfigure(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +00004104 ui::ROTATION_0, SECONDARY_DISPLAY_UNIQUE_ID, NO_PORT,
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004105 ViewportType::EXTERNAL);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004106 }
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004107
4108 static void assertCursorPointerCoords(const PointerCoords& coords, float x, float y,
4109 float pressure) {
4110 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(coords, x, y, pressure, 0.0f, 0.0f, 0.0f, 0.0f,
4111 0.0f, 0.0f, 0.0f, EPSILON));
4112 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004113};
4114
4115const int32_t CursorInputMapperTest::TRACKBALL_MOVEMENT_THRESHOLD = 6;
4116
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004117void CursorInputMapperTest::testMotionRotation(CursorInputMapper& mapper, int32_t originalX,
4118 int32_t originalY, int32_t rotatedX,
4119 int32_t rotatedY) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004120 NotifyMotionArgs args;
4121
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004122 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, originalX);
4123 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, originalY);
4124 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004125 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4126 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004127 ASSERT_NO_FATAL_FAILURE(
4128 assertCursorPointerCoords(args.pointerCoords[0],
4129 float(rotatedX) / TRACKBALL_MOVEMENT_THRESHOLD,
4130 float(rotatedY) / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004131}
4132
4133TEST_F(CursorInputMapperTest, WhenModeIsPointer_GetSources_ReturnsMouse) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004134 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00004135 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004136
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004137 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004138}
4139
4140TEST_F(CursorInputMapperTest, WhenModeIsNavigation_GetSources_ReturnsTrackball) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004141 addConfigurationProperty("cursor.mode", "navigation");
Arpit Singhe036ad72023-04-27 12:48:15 +00004142 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004143
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004144 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004145}
4146
4147TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeFromPointerController) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004148 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00004149 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004150
4151 InputDeviceInfo info;
Harry Cuttsd02ea102023-03-17 18:21:30 +00004152 mapper.populateDeviceInfo(info);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004153
4154 // Initially there may not be a valid motion range.
Yi Kong9b14ac62018-07-17 13:48:38 -07004155 ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE));
4156 ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004157 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
4158 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE, 0.0f, 1.0f, 0.0f, 0.0f));
4159
4160 // When the bounds are set, then there should be a valid motion range.
4161 mFakePointerController->setBounds(1, 2, 800 - 1, 480 - 1);
4162
4163 InputDeviceInfo info2;
Harry Cuttsd02ea102023-03-17 18:21:30 +00004164 mapper.populateDeviceInfo(info2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004165
4166 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
4167 AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE,
4168 1, 800 - 1, 0.0f, 0.0f));
4169 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
4170 AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE,
4171 2, 480 - 1, 0.0f, 0.0f));
4172 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
4173 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE,
4174 0.0f, 1.0f, 0.0f, 0.0f));
4175}
4176
4177TEST_F(CursorInputMapperTest, WhenModeIsNavigation_PopulateDeviceInfo_ReturnsScaledRange) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004178 addConfigurationProperty("cursor.mode", "navigation");
Arpit Singhe036ad72023-04-27 12:48:15 +00004179 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004180
4181 InputDeviceInfo info;
Harry Cuttsd02ea102023-03-17 18:21:30 +00004182 mapper.populateDeviceInfo(info);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004183
4184 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
4185 AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_TRACKBALL,
4186 -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
4187 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
4188 AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_TRACKBALL,
4189 -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
4190 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
4191 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TRACKBALL,
4192 0.0f, 1.0f, 0.0f, 0.0f));
4193}
4194
4195TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004196 addConfigurationProperty("cursor.mode", "navigation");
Arpit Singhe036ad72023-04-27 12:48:15 +00004197 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004198
arthurhungdcef2dc2020-08-11 14:47:50 +08004199 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004200
4201 NotifyMotionArgs args;
4202
4203 // Button press.
4204 // Mostly testing non x/y behavior here so we don't need to check again elsewhere.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004205 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4206 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004207 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4208 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
4209 ASSERT_EQ(DEVICE_ID, args.deviceId);
4210 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4211 ASSERT_EQ(uint32_t(0), args.policyFlags);
4212 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
4213 ASSERT_EQ(0, args.flags);
4214 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4215 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
4216 ASSERT_EQ(0, args.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004217 ASSERT_EQ(uint32_t(1), args.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004218 ASSERT_EQ(0, args.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07004219 ASSERT_EQ(ToolType::MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004220 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004221 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4222 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4223 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4224
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004225 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4226 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
4227 ASSERT_EQ(DEVICE_ID, args.deviceId);
4228 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4229 ASSERT_EQ(uint32_t(0), args.policyFlags);
4230 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
4231 ASSERT_EQ(0, args.flags);
4232 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4233 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
4234 ASSERT_EQ(0, args.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004235 ASSERT_EQ(uint32_t(1), args.getPointerCount());
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004236 ASSERT_EQ(0, args.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07004237 ASSERT_EQ(ToolType::MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004238 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004239 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4240 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4241 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4242
Michael Wrightd02c5b62014-02-10 15:10:22 -08004243 // Button release. Should have same down time.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004244 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4245 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004246 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4247 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
4248 ASSERT_EQ(DEVICE_ID, args.deviceId);
4249 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4250 ASSERT_EQ(uint32_t(0), args.policyFlags);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004251 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
4252 ASSERT_EQ(0, args.flags);
4253 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4254 ASSERT_EQ(0, args.buttonState);
4255 ASSERT_EQ(0, args.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004256 ASSERT_EQ(uint32_t(1), args.getPointerCount());
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004257 ASSERT_EQ(0, args.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07004258 ASSERT_EQ(ToolType::MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004259 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004260 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4261 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4262 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4263
4264 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4265 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
4266 ASSERT_EQ(DEVICE_ID, args.deviceId);
4267 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4268 ASSERT_EQ(uint32_t(0), args.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004269 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
4270 ASSERT_EQ(0, args.flags);
4271 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4272 ASSERT_EQ(0, args.buttonState);
4273 ASSERT_EQ(0, args.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004274 ASSERT_EQ(uint32_t(1), args.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004275 ASSERT_EQ(0, args.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07004276 ASSERT_EQ(ToolType::MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004277 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004278 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4279 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4280 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4281}
4282
4283TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentXYUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004284 addConfigurationProperty("cursor.mode", "navigation");
Arpit Singhe036ad72023-04-27 12:48:15 +00004285 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004286
4287 NotifyMotionArgs args;
4288
4289 // Motion in X but not Y.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004290 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4291 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004292 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4293 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004294 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4295 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f,
4296 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004297
4298 // Motion in Y but not X.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004299 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, -2);
4300 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004301 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4302 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004303 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f,
4304 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004305}
4306
4307TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004308 addConfigurationProperty("cursor.mode", "navigation");
Arpit Singhe036ad72023-04-27 12:48:15 +00004309 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004310
4311 NotifyMotionArgs args;
4312
4313 // Button press.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004314 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4315 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004316 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4317 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004318 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004319
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004320 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4321 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004322 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004323
Michael Wrightd02c5b62014-02-10 15:10:22 -08004324 // Button release.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004325 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4326 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004327 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004328 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004329 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004330
4331 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004332 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004333 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004334}
4335
4336TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004337 addConfigurationProperty("cursor.mode", "navigation");
Arpit Singhe036ad72023-04-27 12:48:15 +00004338 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004339
4340 NotifyMotionArgs args;
4341
4342 // Combined X, Y and Button.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004343 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4344 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, -2);
4345 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4346 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004347 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4348 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004349 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4350 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4351 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004352
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004353 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4354 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004355 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4356 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4357 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004358
Michael Wrightd02c5b62014-02-10 15:10:22 -08004359 // Move X, Y a bit while pressed.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004360 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 2);
4361 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 1);
4362 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004363 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4364 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004365 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4366 2.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4367 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004368
4369 // Release Button.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004370 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4371 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004372 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004373 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004374 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004375
4376 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004377 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004378 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004379}
4380
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004381TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldNotRotateMotions) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004382 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004383 addConfigurationProperty("cursor.mode", "navigation");
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004384 // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
4385 // need to be rotated.
4386 addConfigurationProperty("cursor.orientationAware", "1");
Arpit Singhe036ad72023-04-27 12:48:15 +00004387 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004388
Michael Wrighta9cf4192022-12-01 23:46:39 +00004389 prepareDisplay(ui::ROTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004390 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1));
4391 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1));
4392 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0));
4393 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, -1));
4394 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1));
4395 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
4396 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0));
4397 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1));
4398}
4399
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004400TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldRotateMotions) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004401 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004402 addConfigurationProperty("cursor.mode", "navigation");
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004403 // Since InputReader works in the un-rotated coordinate space, only devices that are not
4404 // orientation-aware are affected by display rotation.
Arpit Singhe036ad72023-04-27 12:48:15 +00004405 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004406
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004407 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00004408 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004409 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1));
4410 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1));
4411 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0));
4412 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, -1));
4413 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1));
4414 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
4415 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0));
4416 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1));
4417
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004418 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00004419 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004420 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, -1, 0));
4421 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, -1, 1));
4422 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 0, 1));
4423 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, 1));
4424 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 1, 0));
4425 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, -1));
4426 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, -1));
4427 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, -1));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004428
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004429 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00004430 prepareDisplay(ui::ROTATION_180);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004431 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, -1));
4432 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, -1, -1));
4433 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, -1, 0));
4434 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, -1, 1));
4435 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, 1));
4436 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, 1));
4437 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 1, 0));
4438 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, -1));
4439
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004440 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00004441 prepareDisplay(ui::ROTATION_270);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004442 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 1, 0));
4443 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, -1));
4444 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 0, -1));
4445 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, -1, -1));
4446 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, -1, 0));
4447 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, 1));
4448 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, 1));
4449 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, 1));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004450}
4451
4452TEST_F(CursorInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004453 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00004454 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004455
4456 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
4457 mFakePointerController->setPosition(100, 200);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004458
4459 NotifyMotionArgs motionArgs;
4460 NotifyKeyArgs keyArgs;
4461
4462 // press BTN_LEFT, release BTN_LEFT
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004463 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_LEFT, 1);
4464 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004465 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4466 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4467 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004468 ASSERT_NO_FATAL_FAILURE(
4469 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004470
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004471 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4472 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4473 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004474 ASSERT_NO_FATAL_FAILURE(
4475 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004476
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004477 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_LEFT, 0);
4478 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004479 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004480 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004481 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004482 ASSERT_NO_FATAL_FAILURE(
4483 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004484
4485 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004486 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004487 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004488 ASSERT_NO_FATAL_FAILURE(
4489 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004490
4491 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004492 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004493 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004494 ASSERT_NO_FATAL_FAILURE(
4495 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004496
4497 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004498 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_RIGHT, 1);
4499 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 1);
4500 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004501 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4502 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4503 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
Siarhei Vishniakou10ce1572023-03-15 09:15:21 -07004504 motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004505 ASSERT_NO_FATAL_FAILURE(
4506 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004507
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004508 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4509 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4510 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004511 ASSERT_NO_FATAL_FAILURE(
4512 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004513
4514 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4515 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4516 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
Siarhei Vishniakou10ce1572023-03-15 09:15:21 -07004517 motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004518 ASSERT_NO_FATAL_FAILURE(
4519 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004520
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004521 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_RIGHT, 0);
4522 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004523 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004524 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004525 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004526 ASSERT_NO_FATAL_FAILURE(
4527 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004528
4529 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004530 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004531 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004532 ASSERT_NO_FATAL_FAILURE(
4533 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004534
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004535 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
4536 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004537 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004538 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4539 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004540 ASSERT_NO_FATAL_FAILURE(
4541 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004542 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
4543 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004544
4545 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004546 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004547 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004548 ASSERT_NO_FATAL_FAILURE(
4549 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004550
Michael Wrightd02c5b62014-02-10 15:10:22 -08004551 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4552 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004553 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004554 ASSERT_NO_FATAL_FAILURE(
4555 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004556
4557 // press BTN_BACK, release BTN_BACK
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004558 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_BACK, 1);
4559 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004560 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4561 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4562 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004563
Michael Wrightd02c5b62014-02-10 15:10:22 -08004564 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004565 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004566 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004567 ASSERT_NO_FATAL_FAILURE(
4568 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004569
4570 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4571 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4572 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004573 ASSERT_NO_FATAL_FAILURE(
4574 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004575
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004576 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_BACK, 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));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004583
4584 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004585 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004586 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004587
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004588 ASSERT_NO_FATAL_FAILURE(
4589 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004590 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4591 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4592 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4593
4594 // press BTN_SIDE, release BTN_SIDE
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004595 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_SIDE, 1);
4596 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004597 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4598 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4599 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004600
Michael Wrightd02c5b62014-02-10 15:10:22 -08004601 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004602 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004603 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004604 ASSERT_NO_FATAL_FAILURE(
4605 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004606
4607 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4608 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4609 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004610 ASSERT_NO_FATAL_FAILURE(
4611 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004612
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004613 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_SIDE, 0);
4614 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004615 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004616 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004617 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004618 ASSERT_NO_FATAL_FAILURE(
4619 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004620
4621 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4622 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4623 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004624 ASSERT_NO_FATAL_FAILURE(
4625 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004626
Michael Wrightd02c5b62014-02-10 15:10:22 -08004627 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4628 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4629 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4630
4631 // press BTN_FORWARD, release BTN_FORWARD
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004632 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_FORWARD, 1);
4633 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004634 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4635 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4636 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004637
Michael Wrightd02c5b62014-02-10 15:10:22 -08004638 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004639 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004640 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004641 ASSERT_NO_FATAL_FAILURE(
4642 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004643
4644 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4645 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4646 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004647 ASSERT_NO_FATAL_FAILURE(
4648 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004649
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004650 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_FORWARD, 0);
4651 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004652 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004653 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004654 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004655 ASSERT_NO_FATAL_FAILURE(
4656 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004657
4658 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4659 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4660 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004661 ASSERT_NO_FATAL_FAILURE(
4662 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004663
Michael Wrightd02c5b62014-02-10 15:10:22 -08004664 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4665 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4666 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4667
4668 // press BTN_EXTRA, release BTN_EXTRA
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004669 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_EXTRA, 1);
4670 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004671 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4672 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4673 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004674
Michael Wrightd02c5b62014-02-10 15:10:22 -08004675 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004676 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004677 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004678 ASSERT_NO_FATAL_FAILURE(
4679 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004680
4681 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4682 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4683 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004684 ASSERT_NO_FATAL_FAILURE(
4685 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004686
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004687 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_EXTRA, 0);
4688 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004689 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004690 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004691 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004692 ASSERT_NO_FATAL_FAILURE(
4693 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004694
4695 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4696 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4697 ASSERT_EQ(0, motionArgs.buttonState);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004698 ASSERT_NO_FATAL_FAILURE(
4699 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004700
Michael Wrightd02c5b62014-02-10 15:10:22 -08004701 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4702 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4703 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4704}
4705
4706TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerAround) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004707 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00004708 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004709
4710 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
4711 mFakePointerController->setPosition(100, 200);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004712
4713 NotifyMotionArgs args;
4714
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004715 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4716 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4717 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004718 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004719 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4720 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4721 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4722 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 +00004723 ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(110.0f, 220.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004724}
4725
4726TEST_F(CursorInputMapperTest, Process_PointerCapture) {
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004727 addConfigurationProperty("cursor.mode", "pointer");
4728 mFakePolicy->setPointerCapture(true);
Arpit Singhe036ad72023-04-27 12:48:15 +00004729 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004730
4731 NotifyDeviceResetArgs resetArgs;
4732 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
4733 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
4734 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4735
4736 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
4737 mFakePointerController->setPosition(100, 200);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004738
4739 NotifyMotionArgs args;
4740
4741 // Move.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004742 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4743 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4744 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004745 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4746 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4747 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4748 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4749 10.0f, 20.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
Harry Cuttsce86cc32022-12-14 20:36:33 +00004750 ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(100.0f, 200.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004751
4752 // Button press.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004753 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4754 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004755 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4756 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4757 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
4758 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4759 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4760 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4761 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4762 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
4763 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4764 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4765
4766 // Button release.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004767 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4768 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004769 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4770 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4771 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
4772 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4773 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4774 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4775 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4776 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
4777 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4778 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4779
4780 // Another move.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004781 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 30);
4782 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 40);
4783 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004784 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4785 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4786 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4787 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4788 30.0f, 40.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
Harry Cuttsce86cc32022-12-14 20:36:33 +00004789 ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(100.0f, 200.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004790
4791 // Disable pointer capture and check that the device generation got bumped
4792 // and events are generated the usual way.
arthurhungdcef2dc2020-08-11 14:47:50 +08004793 const uint32_t generation = mReader->getContext()->getGeneration();
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004794 mFakePolicy->setPointerCapture(false);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004795 configureDevice(InputReaderConfiguration::Change::POINTER_CAPTURE);
arthurhungdcef2dc2020-08-11 14:47:50 +08004796 ASSERT_TRUE(mReader->getContext()->getGeneration() != generation);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004797
4798 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004799 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4800
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004801 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4802 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4803 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004804 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4805 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004806 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4807 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4808 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 +00004809 ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(110.0f, 220.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004810}
4811
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00004812/**
4813 * When Pointer Capture is enabled, we expect to report unprocessed relative movements, so any
4814 * pointer acceleration or speed processing should not be applied.
4815 */
4816TEST_F(CursorInputMapperTest, PointerCaptureDisablesVelocityProcessing) {
4817 addConfigurationProperty("cursor.mode", "pointer");
Harry Cutts33476232023-01-30 19:57:29 +00004818 const VelocityControlParameters testParams(/*scale=*/5.f, /*low threshold=*/0.f,
4819 /*high threshold=*/100.f, /*acceleration=*/10.f);
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00004820 mFakePolicy->setVelocityControlParams(testParams);
Arpit Singhe036ad72023-04-27 12:48:15 +00004821 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00004822
4823 NotifyDeviceResetArgs resetArgs;
4824 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
4825 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
4826 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4827
4828 NotifyMotionArgs args;
4829
4830 // Move and verify scale is applied.
4831 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4832 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4833 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4834 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4835 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4836 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4837 const float relX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
4838 const float relY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
4839 ASSERT_GT(relX, 10);
4840 ASSERT_GT(relY, 20);
4841
4842 // Enable Pointer Capture
4843 mFakePolicy->setPointerCapture(true);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004844 configureDevice(InputReaderConfiguration::Change::POINTER_CAPTURE);
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00004845 NotifyPointerCaptureChangedArgs captureArgs;
4846 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
4847 ASSERT_TRUE(captureArgs.request.enable);
4848
4849 // Move and verify scale is not applied.
4850 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4851 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4852 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4853 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4854 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4855 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4856 ASSERT_EQ(10, args.pointerCoords[0].getX());
4857 ASSERT_EQ(20, args.pointerCoords[0].getY());
4858}
4859
Prabir Pradhan208360b2022-06-24 18:37:04 +00004860TEST_F(CursorInputMapperTest, PointerCaptureDisablesOrientationChanges) {
4861 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00004862 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Prabir Pradhan208360b2022-06-24 18:37:04 +00004863
4864 NotifyDeviceResetArgs resetArgs;
4865 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
4866 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
4867 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4868
4869 // Ensure the display is rotated.
Michael Wrighta9cf4192022-12-01 23:46:39 +00004870 prepareDisplay(ui::ROTATION_90);
Prabir Pradhan208360b2022-06-24 18:37:04 +00004871
4872 NotifyMotionArgs args;
4873
4874 // Verify that the coordinates are rotated.
4875 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4876 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4877 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4878 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4879 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4880 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4881 ASSERT_EQ(-20, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X));
4882 ASSERT_EQ(10, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
4883
4884 // Enable Pointer Capture.
4885 mFakePolicy->setPointerCapture(true);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004886 configureDevice(InputReaderConfiguration::Change::POINTER_CAPTURE);
Prabir Pradhan208360b2022-06-24 18:37:04 +00004887 NotifyPointerCaptureChangedArgs captureArgs;
4888 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
4889 ASSERT_TRUE(captureArgs.request.enable);
4890
4891 // Move and verify rotation is not applied.
4892 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4893 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4894 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4895 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4896 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4897 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4898 ASSERT_EQ(10, args.pointerCoords[0].getX());
4899 ASSERT_EQ(20, args.pointerCoords[0].getY());
4900}
4901
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004902TEST_F(CursorInputMapperTest, ConfigureDisplayId_NoAssociatedViewport) {
Arpit Singhe036ad72023-04-27 12:48:15 +00004903 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004904
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004905 // Set up the default display.
Michael Wrighta9cf4192022-12-01 23:46:39 +00004906 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004907
4908 // Set up the secondary display as the display on which the pointer should be shown.
4909 // The InputDevice is not associated with any display.
4910 prepareSecondaryDisplay();
4911 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004912 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Garfield Tan888a6a42020-01-09 11:39:16 -08004913
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004914 mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004915 mFakePointerController->setPosition(100, 200);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004916
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004917 // Ensure input events are generated for the secondary display.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004918 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4919 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4920 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004921 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan739dca42022-09-09 20:12:01 +00004922 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4923 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(SECONDARY_DISPLAY_ID),
4924 WithCoords(110.0f, 220.0f))));
Harry Cuttsce86cc32022-12-14 20:36:33 +00004925 ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(110.0f, 220.0f));
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004926}
4927
4928TEST_F(CursorInputMapperTest, ConfigureDisplayId_WithAssociatedViewport) {
Arpit Singhe036ad72023-04-27 12:48:15 +00004929 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004930
4931 // Set up the default display.
Michael Wrighta9cf4192022-12-01 23:46:39 +00004932 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004933
4934 // Set up the secondary display as the display on which the pointer should be shown,
4935 // and associate the InputDevice with the secondary display.
4936 prepareSecondaryDisplay();
4937 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
4938 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, SECONDARY_DISPLAY_UNIQUE_ID);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004939 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004940
4941 mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
4942 mFakePointerController->setPosition(100, 200);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004943
4944 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4945 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4946 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4947 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan739dca42022-09-09 20:12:01 +00004948 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4949 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(SECONDARY_DISPLAY_ID),
4950 WithCoords(110.0f, 220.0f))));
Harry Cuttsce86cc32022-12-14 20:36:33 +00004951 ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(110.0f, 220.0f));
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004952}
4953
4954TEST_F(CursorInputMapperTest, ConfigureDisplayId_IgnoresEventsForMismatchedPointerDisplay) {
Arpit Singhe036ad72023-04-27 12:48:15 +00004955 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004956
4957 // Set up the default display as the display on which the pointer should be shown.
Michael Wrighta9cf4192022-12-01 23:46:39 +00004958 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004959 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
4960
4961 // Associate the InputDevice with the secondary display.
4962 prepareSecondaryDisplay();
4963 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, SECONDARY_DISPLAY_UNIQUE_ID);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00004964 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004965
4966 // The mapper should not generate any events because it is associated with a display that is
4967 // different from the pointer display.
4968 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4969 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4970 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4971 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004972}
4973
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00004974// --- BluetoothCursorInputMapperTest ---
4975
4976class BluetoothCursorInputMapperTest : public CursorInputMapperTest {
4977protected:
4978 void SetUp() override {
4979 InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL, BUS_BLUETOOTH);
4980
4981 mFakePointerController = std::make_shared<FakePointerController>();
4982 mFakePolicy->setPointerController(mFakePointerController);
4983 }
4984};
4985
4986TEST_F(BluetoothCursorInputMapperTest, TimestampSmoothening) {
4987 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00004988 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00004989
4990 nsecs_t kernelEventTime = ARBITRARY_TIME;
4991 nsecs_t expectedEventTime = ARBITRARY_TIME;
4992 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
4993 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
4994 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4995 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4996 WithEventTime(expectedEventTime))));
4997
4998 // Process several events that come in quick succession, according to their timestamps.
4999 for (int i = 0; i < 3; i++) {
5000 constexpr static nsecs_t delta = ms2ns(1);
5001 static_assert(delta < MIN_BLUETOOTH_TIMESTAMP_DELTA);
5002 kernelEventTime += delta;
5003 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
5004
5005 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
5006 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
5007 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5008 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5009 WithEventTime(expectedEventTime))));
5010 }
5011}
5012
5013TEST_F(BluetoothCursorInputMapperTest, TimestampSmootheningIsCapped) {
5014 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00005015 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00005016
5017 nsecs_t expectedEventTime = ARBITRARY_TIME;
5018 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
5019 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5020 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5021 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5022 WithEventTime(expectedEventTime))));
5023
5024 // Process several events with the same timestamp from the kernel.
5025 // Ensure that we do not generate events too far into the future.
5026 constexpr static int32_t numEvents =
5027 MAX_BLUETOOTH_SMOOTHING_DELTA / MIN_BLUETOOTH_TIMESTAMP_DELTA;
5028 for (int i = 0; i < numEvents; i++) {
5029 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
5030
5031 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
5032 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5033 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5034 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5035 WithEventTime(expectedEventTime))));
5036 }
5037
5038 // By processing more events with the same timestamp, we should not generate events with a
5039 // timestamp that is more than the specified max time delta from the timestamp at its injection.
5040 const nsecs_t cappedEventTime = ARBITRARY_TIME + MAX_BLUETOOTH_SMOOTHING_DELTA;
5041 for (int i = 0; i < 3; i++) {
5042 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
5043 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
5044 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5045 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5046 WithEventTime(cappedEventTime))));
5047 }
5048}
5049
5050TEST_F(BluetoothCursorInputMapperTest, TimestampSmootheningNotUsed) {
5051 addConfigurationProperty("cursor.mode", "pointer");
Arpit Singhe036ad72023-04-27 12:48:15 +00005052 CursorInputMapper& mapper = constructAndAddMapper<CursorInputMapper>();
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00005053
5054 nsecs_t kernelEventTime = ARBITRARY_TIME;
5055 nsecs_t expectedEventTime = ARBITRARY_TIME;
5056 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
5057 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
5058 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5059 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5060 WithEventTime(expectedEventTime))));
5061
5062 // If the next event has a timestamp that is sufficiently spaced out so that Bluetooth timestamp
5063 // smoothening is not needed, its timestamp is not affected.
5064 kernelEventTime += MAX_BLUETOOTH_SMOOTHING_DELTA + ms2ns(1);
5065 expectedEventTime = kernelEventTime;
5066
5067 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
5068 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
5069 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5070 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
5071 WithEventTime(expectedEventTime))));
5072}
5073
Michael Wrightd02c5b62014-02-10 15:10:22 -08005074// --- TouchInputMapperTest ---
5075
5076class TouchInputMapperTest : public InputMapperTest {
5077protected:
5078 static const int32_t RAW_X_MIN;
5079 static const int32_t RAW_X_MAX;
5080 static const int32_t RAW_Y_MIN;
5081 static const int32_t RAW_Y_MAX;
5082 static const int32_t RAW_TOUCH_MIN;
5083 static const int32_t RAW_TOUCH_MAX;
5084 static const int32_t RAW_TOOL_MIN;
5085 static const int32_t RAW_TOOL_MAX;
5086 static const int32_t RAW_PRESSURE_MIN;
5087 static const int32_t RAW_PRESSURE_MAX;
5088 static const int32_t RAW_ORIENTATION_MIN;
5089 static const int32_t RAW_ORIENTATION_MAX;
5090 static const int32_t RAW_DISTANCE_MIN;
5091 static const int32_t RAW_DISTANCE_MAX;
5092 static const int32_t RAW_TILT_MIN;
5093 static const int32_t RAW_TILT_MAX;
5094 static const int32_t RAW_ID_MIN;
5095 static const int32_t RAW_ID_MAX;
5096 static const int32_t RAW_SLOT_MIN;
5097 static const int32_t RAW_SLOT_MAX;
5098 static const float X_PRECISION;
5099 static const float Y_PRECISION;
Santos Cordonfa5cf462017-04-05 10:37:00 -07005100 static const float X_PRECISION_VIRTUAL;
5101 static const float Y_PRECISION_VIRTUAL;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005102
5103 static const float GEOMETRIC_SCALE;
Jason Gerecke489fda82012-09-07 17:19:40 -07005104 static const TouchAffineTransformation AFFINE_TRANSFORM;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005105
5106 static const VirtualKeyDefinition VIRTUAL_KEYS[2];
5107
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005108 const std::string UNIQUE_ID = "local:0";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07005109 const std::string SECONDARY_UNIQUE_ID = "local:1";
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005110
Michael Wrightd02c5b62014-02-10 15:10:22 -08005111 enum Axes {
5112 POSITION = 1 << 0,
5113 TOUCH = 1 << 1,
5114 TOOL = 1 << 2,
5115 PRESSURE = 1 << 3,
5116 ORIENTATION = 1 << 4,
5117 MINOR = 1 << 5,
5118 ID = 1 << 6,
5119 DISTANCE = 1 << 7,
5120 TILT = 1 << 8,
5121 SLOT = 1 << 9,
5122 TOOL_TYPE = 1 << 10,
5123 };
5124
Michael Wrighta9cf4192022-12-01 23:46:39 +00005125 void prepareDisplay(ui::Rotation orientation, std::optional<uint8_t> port = NO_PORT);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07005126 void prepareSecondaryDisplay(ViewportType type, std::optional<uint8_t> port = NO_PORT);
Michael Wrighta9cf4192022-12-01 23:46:39 +00005127 void prepareVirtualDisplay(ui::Rotation orientation);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005128 void prepareVirtualKeys();
Jason Gerecke489fda82012-09-07 17:19:40 -07005129 void prepareLocationCalibration();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005130 int32_t toRawX(float displayX);
5131 int32_t toRawY(float displayY);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005132 int32_t toRotatedRawX(float displayX);
5133 int32_t toRotatedRawY(float displayY);
Jason Gerecke489fda82012-09-07 17:19:40 -07005134 float toCookedX(float rawX, float rawY);
5135 float toCookedY(float rawX, float rawY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005136 float toDisplayX(int32_t rawX);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005137 float toDisplayX(int32_t rawX, int32_t displayWidth);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005138 float toDisplayY(int32_t rawY);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005139 float toDisplayY(int32_t rawY, int32_t displayHeight);
5140
Michael Wrightd02c5b62014-02-10 15:10:22 -08005141};
5142
5143const int32_t TouchInputMapperTest::RAW_X_MIN = 25;
5144const int32_t TouchInputMapperTest::RAW_X_MAX = 1019;
5145const int32_t TouchInputMapperTest::RAW_Y_MIN = 30;
5146const int32_t TouchInputMapperTest::RAW_Y_MAX = 1009;
5147const int32_t TouchInputMapperTest::RAW_TOUCH_MIN = 0;
5148const int32_t TouchInputMapperTest::RAW_TOUCH_MAX = 31;
5149const int32_t TouchInputMapperTest::RAW_TOOL_MIN = 0;
5150const int32_t TouchInputMapperTest::RAW_TOOL_MAX = 15;
Michael Wrightaa449c92017-12-13 21:21:43 +00005151const int32_t TouchInputMapperTest::RAW_PRESSURE_MIN = 0;
5152const int32_t TouchInputMapperTest::RAW_PRESSURE_MAX = 255;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005153const int32_t TouchInputMapperTest::RAW_ORIENTATION_MIN = -7;
5154const int32_t TouchInputMapperTest::RAW_ORIENTATION_MAX = 7;
5155const int32_t TouchInputMapperTest::RAW_DISTANCE_MIN = 0;
5156const int32_t TouchInputMapperTest::RAW_DISTANCE_MAX = 7;
5157const int32_t TouchInputMapperTest::RAW_TILT_MIN = 0;
5158const int32_t TouchInputMapperTest::RAW_TILT_MAX = 150;
5159const int32_t TouchInputMapperTest::RAW_ID_MIN = 0;
5160const int32_t TouchInputMapperTest::RAW_ID_MAX = 9;
5161const int32_t TouchInputMapperTest::RAW_SLOT_MIN = 0;
5162const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9;
5163const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH;
5164const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT;
Santos Cordonfa5cf462017-04-05 10:37:00 -07005165const float TouchInputMapperTest::X_PRECISION_VIRTUAL =
5166 float(RAW_X_MAX - RAW_X_MIN + 1) / VIRTUAL_DISPLAY_WIDTH;
5167const float TouchInputMapperTest::Y_PRECISION_VIRTUAL =
5168 float(RAW_Y_MAX - RAW_Y_MIN + 1) / VIRTUAL_DISPLAY_HEIGHT;
Jason Gerecke489fda82012-09-07 17:19:40 -07005169const TouchAffineTransformation TouchInputMapperTest::AFFINE_TRANSFORM =
5170 TouchAffineTransformation(1, -2, 3, -4, 5, -6);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005171
5172const float TouchInputMapperTest::GEOMETRIC_SCALE =
5173 avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN + 1),
5174 float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN + 1));
5175
5176const VirtualKeyDefinition TouchInputMapperTest::VIRTUAL_KEYS[2] = {
5177 { KEY_HOME, 60, DISPLAY_HEIGHT + 15, 20, 20 },
5178 { KEY_MENU, DISPLAY_HEIGHT - 60, DISPLAY_WIDTH + 15, 20, 20 },
5179};
5180
Michael Wrighta9cf4192022-12-01 23:46:39 +00005181void TouchInputMapperTest::prepareDisplay(ui::Rotation orientation, std::optional<uint8_t> port) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01005182 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation, UNIQUE_ID,
5183 port, ViewportType::INTERNAL);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07005184}
5185
5186void TouchInputMapperTest::prepareSecondaryDisplay(ViewportType type, std::optional<uint8_t> port) {
5187 setDisplayInfoAndReconfigure(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +00005188 ui::ROTATION_0, SECONDARY_UNIQUE_ID, port, type);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005189}
5190
Michael Wrighta9cf4192022-12-01 23:46:39 +00005191void TouchInputMapperTest::prepareVirtualDisplay(ui::Rotation orientation) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01005192 setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH, VIRTUAL_DISPLAY_HEIGHT,
5193 orientation, VIRTUAL_DISPLAY_UNIQUE_ID, NO_PORT,
5194 ViewportType::VIRTUAL);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005195}
5196
Michael Wrightd02c5b62014-02-10 15:10:22 -08005197void TouchInputMapperTest::prepareVirtualKeys() {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005198 mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[0]);
5199 mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[1]);
5200 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
5201 mFakeEventHub->addKey(EVENTHUB_ID, KEY_MENU, 0, AKEYCODE_MENU, POLICY_FLAG_WAKE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005202}
5203
Jason Gerecke489fda82012-09-07 17:19:40 -07005204void TouchInputMapperTest::prepareLocationCalibration() {
5205 mFakePolicy->setTouchAffineTransformation(AFFINE_TRANSFORM);
5206}
5207
Michael Wrightd02c5b62014-02-10 15:10:22 -08005208int32_t TouchInputMapperTest::toRawX(float displayX) {
5209 return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH + RAW_X_MIN);
5210}
5211
5212int32_t TouchInputMapperTest::toRawY(float displayY) {
5213 return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT + RAW_Y_MIN);
5214}
5215
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005216int32_t TouchInputMapperTest::toRotatedRawX(float displayX) {
5217 return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_HEIGHT + RAW_X_MIN);
5218}
5219
5220int32_t TouchInputMapperTest::toRotatedRawY(float displayY) {
5221 return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_WIDTH + RAW_Y_MIN);
5222}
5223
Jason Gerecke489fda82012-09-07 17:19:40 -07005224float TouchInputMapperTest::toCookedX(float rawX, float rawY) {
5225 AFFINE_TRANSFORM.applyTo(rawX, rawY);
5226 return rawX;
5227}
5228
5229float TouchInputMapperTest::toCookedY(float rawX, float rawY) {
5230 AFFINE_TRANSFORM.applyTo(rawX, rawY);
5231 return rawY;
5232}
5233
Michael Wrightd02c5b62014-02-10 15:10:22 -08005234float TouchInputMapperTest::toDisplayX(int32_t rawX) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005235 return toDisplayX(rawX, DISPLAY_WIDTH);
5236}
5237
5238float TouchInputMapperTest::toDisplayX(int32_t rawX, int32_t displayWidth) {
5239 return float(rawX - RAW_X_MIN) * displayWidth / (RAW_X_MAX - RAW_X_MIN + 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005240}
5241
5242float TouchInputMapperTest::toDisplayY(int32_t rawY) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005243 return toDisplayY(rawY, DISPLAY_HEIGHT);
5244}
5245
5246float TouchInputMapperTest::toDisplayY(int32_t rawY, int32_t displayHeight) {
5247 return float(rawY - RAW_Y_MIN) * displayHeight / (RAW_Y_MAX - RAW_Y_MIN + 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005248}
5249
5250
5251// --- SingleTouchInputMapperTest ---
5252
5253class SingleTouchInputMapperTest : public TouchInputMapperTest {
5254protected:
5255 void prepareButtons();
5256 void prepareAxes(int axes);
5257
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005258 void processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
5259 void processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
5260 void processUp(SingleTouchInputMapper& mappery);
5261 void processPressure(SingleTouchInputMapper& mapper, int32_t pressure);
5262 void processToolMajor(SingleTouchInputMapper& mapper, int32_t toolMajor);
5263 void processDistance(SingleTouchInputMapper& mapper, int32_t distance);
5264 void processTilt(SingleTouchInputMapper& mapper, int32_t tiltX, int32_t tiltY);
5265 void processKey(SingleTouchInputMapper& mapper, int32_t code, int32_t value);
5266 void processSync(SingleTouchInputMapper& mapper);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005267};
5268
5269void SingleTouchInputMapperTest::prepareButtons() {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005270 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005271}
5272
5273void SingleTouchInputMapperTest::prepareAxes(int axes) {
5274 if (axes & POSITION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005275 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
5276 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005277 }
5278 if (axes & PRESSURE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005279 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MIN,
5280 RAW_PRESSURE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005281 }
5282 if (axes & TOOL) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005283 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TOOL_WIDTH, RAW_TOOL_MIN, RAW_TOOL_MAX, 0,
5284 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005285 }
5286 if (axes & DISTANCE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005287 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_DISTANCE, RAW_DISTANCE_MIN,
5288 RAW_DISTANCE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005289 }
5290 if (axes & TILT) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005291 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_X, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
5292 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_Y, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005293 }
5294}
5295
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005296void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005297 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
5298 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
5299 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005300}
5301
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005302void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005303 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
5304 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005305}
5306
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005307void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005308 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005309}
5310
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005311void SingleTouchInputMapperTest::processPressure(SingleTouchInputMapper& mapper, int32_t pressure) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005312 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_PRESSURE, pressure);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005313}
5314
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005315void SingleTouchInputMapperTest::processToolMajor(SingleTouchInputMapper& mapper,
5316 int32_t toolMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005317 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TOOL_WIDTH, toolMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005318}
5319
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005320void SingleTouchInputMapperTest::processDistance(SingleTouchInputMapper& mapper, int32_t distance) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005321 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_DISTANCE, distance);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005322}
5323
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005324void SingleTouchInputMapperTest::processTilt(SingleTouchInputMapper& mapper, int32_t tiltX,
5325 int32_t tiltY) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005326 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_X, tiltX);
5327 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_Y, tiltY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005328}
5329
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005330void SingleTouchInputMapperTest::processKey(SingleTouchInputMapper& mapper, int32_t code,
5331 int32_t value) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005332 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005333}
5334
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005335void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005336 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005337}
5338
Michael Wrightd02c5b62014-02-10 15:10:22 -08005339TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndNotACursor_ReturnsPointer) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005340 prepareButtons();
5341 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00005342 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005343
Josep del Río2d8c79a2023-01-23 19:33:50 +00005344 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005345}
5346
Michael Wrightd02c5b62014-02-10 15:10:22 -08005347TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005348 prepareButtons();
5349 prepareAxes(POSITION);
5350 addConfigurationProperty("touch.deviceType", "touchScreen");
Arpit Singha8c236b2023-04-25 13:56:05 +00005351 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005352
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005353 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005354}
5355
5356TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005357 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005358 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005359 prepareButtons();
5360 prepareAxes(POSITION);
5361 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00005362 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005363
5364 // Unknown key.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005365 ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005366
5367 // Virtual key is down.
5368 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5369 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5370 processDown(mapper, x, y);
5371 processSync(mapper);
5372 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5373
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005374 ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005375
5376 // Virtual key is up.
5377 processUp(mapper);
5378 processSync(mapper);
5379 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5380
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005381 ASSERT_EQ(AKEY_STATE_UP, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005382}
5383
5384TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005385 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005386 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005387 prepareButtons();
5388 prepareAxes(POSITION);
5389 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00005390 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005391
5392 // Unknown key.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005393 ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005394
5395 // Virtual key is down.
5396 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5397 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5398 processDown(mapper, x, y);
5399 processSync(mapper);
5400 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5401
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005402 ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005403
5404 // Virtual key is up.
5405 processUp(mapper);
5406 processSync(mapper);
5407 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5408
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005409 ASSERT_EQ(AKEY_STATE_UP, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005410}
5411
5412TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005413 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005414 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005415 prepareButtons();
5416 prepareAxes(POSITION);
5417 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00005418 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005419
Michael Wrightd02c5b62014-02-10 15:10:22 -08005420 uint8_t flags[2] = { 0, 0 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07005421 ASSERT_TRUE(
5422 mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, {AKEYCODE_HOME, AKEYCODE_A}, flags));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005423 ASSERT_TRUE(flags[0]);
5424 ASSERT_FALSE(flags[1]);
5425}
5426
5427TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005428 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005429 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005430 prepareButtons();
5431 prepareAxes(POSITION);
5432 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00005433 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005434
arthurhungdcef2dc2020-08-11 14:47:50 +08005435 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005436
5437 NotifyKeyArgs args;
5438
5439 // Press virtual key.
5440 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5441 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5442 processDown(mapper, x, y);
5443 processSync(mapper);
5444
5445 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
5446 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
5447 ASSERT_EQ(DEVICE_ID, args.deviceId);
5448 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
5449 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
5450 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
5451 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
5452 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
5453 ASSERT_EQ(KEY_HOME, args.scanCode);
5454 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
5455 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
5456
5457 // Release virtual key.
5458 processUp(mapper);
5459 processSync(mapper);
5460
5461 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
5462 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
5463 ASSERT_EQ(DEVICE_ID, args.deviceId);
5464 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
5465 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
5466 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
5467 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
5468 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
5469 ASSERT_EQ(KEY_HOME, args.scanCode);
5470 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
5471 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
5472
5473 // Should not have sent any motions.
5474 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5475}
5476
5477TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005478 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005479 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005480 prepareButtons();
5481 prepareAxes(POSITION);
5482 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00005483 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005484
arthurhungdcef2dc2020-08-11 14:47:50 +08005485 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005486
5487 NotifyKeyArgs keyArgs;
5488
5489 // Press virtual key.
5490 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5491 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5492 processDown(mapper, x, y);
5493 processSync(mapper);
5494
5495 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5496 ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
5497 ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
5498 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
5499 ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
5500 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5501 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, keyArgs.flags);
5502 ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
5503 ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
5504 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
5505 ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
5506
5507 // Move out of bounds. This should generate a cancel and a pointer down since we moved
5508 // into the display area.
5509 y -= 100;
5510 processMove(mapper, x, y);
5511 processSync(mapper);
5512
5513 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5514 ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
5515 ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
5516 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
5517 ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
5518 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5519 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
5520 | AKEY_EVENT_FLAG_CANCELED, keyArgs.flags);
5521 ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
5522 ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
5523 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
5524 ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
5525
5526 NotifyMotionArgs motionArgs;
5527 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5528 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5529 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5530 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5531 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5532 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5533 ASSERT_EQ(0, motionArgs.flags);
5534 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5535 ASSERT_EQ(0, motionArgs.buttonState);
5536 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07005537 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005538 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07005539 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005540 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5541 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5542 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5543 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5544 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5545
5546 // Keep moving out of bounds. Should generate a pointer move.
5547 y -= 50;
5548 processMove(mapper, x, y);
5549 processSync(mapper);
5550
5551 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5552 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5553 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5554 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5555 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5556 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5557 ASSERT_EQ(0, motionArgs.flags);
5558 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5559 ASSERT_EQ(0, motionArgs.buttonState);
5560 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07005561 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005562 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07005563 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005564 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5565 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5566 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5567 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5568 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5569
5570 // Release out of bounds. Should generate a pointer up.
5571 processUp(mapper);
5572 processSync(mapper);
5573
5574 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5575 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5576 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5577 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5578 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5579 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5580 ASSERT_EQ(0, motionArgs.flags);
5581 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5582 ASSERT_EQ(0, motionArgs.buttonState);
5583 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07005584 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005585 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07005586 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005587 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5588 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5589 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5590 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5591 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5592
5593 // Should not have sent any more keys or motions.
5594 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5595 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5596}
5597
5598TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005599 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005600 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005601 prepareButtons();
5602 prepareAxes(POSITION);
5603 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00005604 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005605
arthurhungdcef2dc2020-08-11 14:47:50 +08005606 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005607
5608 NotifyMotionArgs motionArgs;
5609
5610 // Initially go down out of bounds.
5611 int32_t x = -10;
5612 int32_t y = -10;
5613 processDown(mapper, x, y);
5614 processSync(mapper);
5615
5616 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5617
5618 // Move into the display area. Should generate a pointer down.
5619 x = 50;
5620 y = 75;
5621 processMove(mapper, x, y);
5622 processSync(mapper);
5623
5624 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5625 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5626 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5627 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5628 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5629 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5630 ASSERT_EQ(0, motionArgs.flags);
5631 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5632 ASSERT_EQ(0, motionArgs.buttonState);
5633 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07005634 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005635 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07005636 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005637 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5638 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5639 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5640 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5641 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5642
5643 // Release. Should generate a pointer up.
5644 processUp(mapper);
5645 processSync(mapper);
5646
5647 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5648 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5649 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5650 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5651 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5652 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5653 ASSERT_EQ(0, motionArgs.flags);
5654 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5655 ASSERT_EQ(0, motionArgs.buttonState);
5656 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07005657 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005658 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07005659 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005660 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5661 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5662 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5663 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5664 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5665
5666 // Should not have sent any more keys or motions.
5667 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5668 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5669}
5670
Santos Cordonfa5cf462017-04-05 10:37:00 -07005671TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture_VirtualDisplay) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005672 addConfigurationProperty("touch.deviceType", "touchScreen");
5673 addConfigurationProperty("touch.displayId", VIRTUAL_DISPLAY_UNIQUE_ID);
5674
Michael Wrighta9cf4192022-12-01 23:46:39 +00005675 prepareVirtualDisplay(ui::ROTATION_0);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005676 prepareButtons();
5677 prepareAxes(POSITION);
5678 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00005679 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Santos Cordonfa5cf462017-04-05 10:37:00 -07005680
arthurhungdcef2dc2020-08-11 14:47:50 +08005681 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005682
5683 NotifyMotionArgs motionArgs;
5684
5685 // Down.
5686 int32_t x = 100;
5687 int32_t y = 125;
5688 processDown(mapper, x, y);
5689 processSync(mapper);
5690
5691 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5692 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5693 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5694 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
5695 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5696 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5697 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5698 ASSERT_EQ(0, motionArgs.flags);
5699 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5700 ASSERT_EQ(0, motionArgs.buttonState);
5701 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07005702 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Santos Cordonfa5cf462017-04-05 10:37:00 -07005703 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07005704 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005705 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5706 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
5707 1, 0, 0, 0, 0, 0, 0, 0));
5708 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
5709 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
5710 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5711
5712 // Move.
5713 x += 50;
5714 y += 75;
5715 processMove(mapper, x, y);
5716 processSync(mapper);
5717
5718 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5719 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5720 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5721 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
5722 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5723 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5724 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5725 ASSERT_EQ(0, motionArgs.flags);
5726 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5727 ASSERT_EQ(0, motionArgs.buttonState);
5728 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07005729 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Santos Cordonfa5cf462017-04-05 10:37:00 -07005730 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07005731 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005732 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5733 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
5734 1, 0, 0, 0, 0, 0, 0, 0));
5735 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
5736 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
5737 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5738
5739 // Up.
5740 processUp(mapper);
5741 processSync(mapper);
5742
5743 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5744 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5745 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5746 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
5747 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5748 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5749 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5750 ASSERT_EQ(0, motionArgs.flags);
5751 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5752 ASSERT_EQ(0, motionArgs.buttonState);
5753 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07005754 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Santos Cordonfa5cf462017-04-05 10:37:00 -07005755 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07005756 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005757 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5758 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
5759 1, 0, 0, 0, 0, 0, 0, 0));
5760 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
5761 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
5762 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5763
5764 // Should not have sent any more keys or motions.
5765 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5766 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5767}
5768
Michael Wrightd02c5b62014-02-10 15:10:22 -08005769TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005770 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005771 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005772 prepareButtons();
5773 prepareAxes(POSITION);
5774 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00005775 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005776
arthurhungdcef2dc2020-08-11 14:47:50 +08005777 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005778
5779 NotifyMotionArgs motionArgs;
5780
5781 // Down.
5782 int32_t x = 100;
5783 int32_t y = 125;
5784 processDown(mapper, x, y);
5785 processSync(mapper);
5786
5787 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5788 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5789 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5790 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5791 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5792 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5793 ASSERT_EQ(0, motionArgs.flags);
5794 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5795 ASSERT_EQ(0, motionArgs.buttonState);
5796 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07005797 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005798 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07005799 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005800 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5801 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5802 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5803 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5804 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5805
5806 // Move.
5807 x += 50;
5808 y += 75;
5809 processMove(mapper, x, y);
5810 processSync(mapper);
5811
5812 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5813 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5814 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5815 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5816 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5817 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5818 ASSERT_EQ(0, motionArgs.flags);
5819 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5820 ASSERT_EQ(0, motionArgs.buttonState);
5821 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07005822 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005823 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07005824 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005825 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5826 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5827 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5828 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5829 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5830
5831 // Up.
5832 processUp(mapper);
5833 processSync(mapper);
5834
5835 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5836 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5837 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5838 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5839 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5840 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5841 ASSERT_EQ(0, motionArgs.flags);
5842 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5843 ASSERT_EQ(0, motionArgs.buttonState);
5844 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07005845 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005846 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07005847 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005848 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5849 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5850 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5851 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5852 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5853
5854 // Should not have sent any more keys or motions.
5855 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5856 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5857}
5858
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005859TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_DoesNotRotateMotions) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005860 addConfigurationProperty("touch.deviceType", "touchScreen");
5861 prepareButtons();
5862 prepareAxes(POSITION);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005863 // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
5864 // need to be rotated. Touchscreens are orientation-aware by default.
Arpit Singha8c236b2023-04-25 13:56:05 +00005865 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005866
5867 NotifyMotionArgs args;
5868
5869 // Rotation 90.
Michael Wrighta9cf4192022-12-01 23:46:39 +00005870 prepareDisplay(ui::ROTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005871 processDown(mapper, toRawX(50), toRawY(75));
5872 processSync(mapper);
5873
5874 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5875 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5876 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5877
5878 processUp(mapper);
5879 processSync(mapper);
5880 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5881}
5882
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005883TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_RotatesMotions) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005884 addConfigurationProperty("touch.deviceType", "touchScreen");
5885 prepareButtons();
5886 prepareAxes(POSITION);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005887 // Since InputReader works in the un-rotated coordinate space, only devices that are not
5888 // orientation-aware are affected by display rotation.
5889 addConfigurationProperty("touch.orientationAware", "0");
Arpit Singha8c236b2023-04-25 13:56:05 +00005890 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005891
5892 NotifyMotionArgs args;
5893
5894 // Rotation 0.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005895 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005896 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005897 processDown(mapper, toRawX(50), toRawY(75));
5898 processSync(mapper);
5899
5900 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5901 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5902 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5903
5904 processUp(mapper);
5905 processSync(mapper);
5906 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5907
5908 // Rotation 90.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005909 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005910 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanea31d4f2022-11-10 20:48:01 +00005911 processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005912 processSync(mapper);
5913
5914 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5915 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5916 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5917
5918 processUp(mapper);
5919 processSync(mapper);
5920 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5921
5922 // Rotation 180.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005923 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005924 prepareDisplay(ui::ROTATION_180);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005925 processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
5926 processSync(mapper);
5927
5928 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5929 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5930 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5931
5932 processUp(mapper);
5933 processSync(mapper);
5934 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5935
5936 // Rotation 270.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005937 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005938 prepareDisplay(ui::ROTATION_270);
Prabir Pradhanea31d4f2022-11-10 20:48:01 +00005939 processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005940 processSync(mapper);
5941
5942 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5943 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5944 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5945
5946 processUp(mapper);
5947 processSync(mapper);
5948 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5949}
5950
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005951TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation0_RotatesMotions) {
5952 addConfigurationProperty("touch.deviceType", "touchScreen");
5953 prepareButtons();
5954 prepareAxes(POSITION);
5955 addConfigurationProperty("touch.orientationAware", "1");
5956 addConfigurationProperty("touch.orientation", "ORIENTATION_0");
5957 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005958 prepareDisplay(ui::ROTATION_0);
Arpit Singha8c236b2023-04-25 13:56:05 +00005959 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005960 NotifyMotionArgs args;
5961
5962 // Orientation 0.
5963 processDown(mapper, toRawX(50), toRawY(75));
5964 processSync(mapper);
5965
5966 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5967 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5968 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5969
5970 processUp(mapper);
5971 processSync(mapper);
5972 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5973}
5974
5975TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation90_RotatesMotions) {
5976 addConfigurationProperty("touch.deviceType", "touchScreen");
5977 prepareButtons();
5978 prepareAxes(POSITION);
5979 addConfigurationProperty("touch.orientationAware", "1");
5980 addConfigurationProperty("touch.orientation", "ORIENTATION_90");
5981 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005982 prepareDisplay(ui::ROTATION_0);
Arpit Singha8c236b2023-04-25 13:56:05 +00005983 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005984 NotifyMotionArgs args;
5985
5986 // Orientation 90.
5987 processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
5988 processSync(mapper);
5989
5990 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5991 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5992 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5993
5994 processUp(mapper);
5995 processSync(mapper);
5996 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5997}
5998
5999TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation180_RotatesMotions) {
6000 addConfigurationProperty("touch.deviceType", "touchScreen");
6001 prepareButtons();
6002 prepareAxes(POSITION);
6003 addConfigurationProperty("touch.orientationAware", "1");
6004 addConfigurationProperty("touch.orientation", "ORIENTATION_180");
6005 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006006 prepareDisplay(ui::ROTATION_0);
Arpit Singha8c236b2023-04-25 13:56:05 +00006007 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006008 NotifyMotionArgs args;
6009
6010 // Orientation 180.
6011 processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
6012 processSync(mapper);
6013
6014 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6015 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6016 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6017
6018 processUp(mapper);
6019 processSync(mapper);
6020 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6021}
6022
6023TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation270_RotatesMotions) {
6024 addConfigurationProperty("touch.deviceType", "touchScreen");
6025 prepareButtons();
6026 prepareAxes(POSITION);
6027 addConfigurationProperty("touch.orientationAware", "1");
6028 addConfigurationProperty("touch.orientation", "ORIENTATION_270");
6029 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006030 prepareDisplay(ui::ROTATION_0);
Arpit Singha8c236b2023-04-25 13:56:05 +00006031 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006032 NotifyMotionArgs args;
6033
6034 // Orientation 270.
6035 processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
6036 processSync(mapper);
6037
6038 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6039 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6040 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6041
6042 processUp(mapper);
6043 processSync(mapper);
6044 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6045}
6046
6047TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationSpecified_RotatesMotionWithDisplay) {
6048 addConfigurationProperty("touch.deviceType", "touchScreen");
6049 prepareButtons();
6050 prepareAxes(POSITION);
6051 // Since InputReader works in the un-rotated coordinate space, only devices that are not
6052 // orientation-aware are affected by display rotation.
6053 addConfigurationProperty("touch.orientationAware", "0");
6054 addConfigurationProperty("touch.orientation", "ORIENTATION_90");
Arpit Singha8c236b2023-04-25 13:56:05 +00006055 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006056
6057 NotifyMotionArgs args;
6058
6059 // Orientation 90, Rotation 0.
6060 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006061 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006062 processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
6063 processSync(mapper);
6064
6065 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6066 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6067 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6068
6069 processUp(mapper);
6070 processSync(mapper);
6071 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6072
6073 // Orientation 90, Rotation 90.
6074 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006075 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanea31d4f2022-11-10 20:48:01 +00006076 processDown(mapper, toRawX(50), toRawY(75));
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006077 processSync(mapper);
6078
6079 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6080 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6081 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6082
6083 processUp(mapper);
6084 processSync(mapper);
6085 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6086
6087 // Orientation 90, Rotation 180.
6088 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006089 prepareDisplay(ui::ROTATION_180);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07006090 processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
6091 processSync(mapper);
6092
6093 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6094 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6095 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6096
6097 processUp(mapper);
6098 processSync(mapper);
6099 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6100
6101 // Orientation 90, Rotation 270.
6102 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00006103 prepareDisplay(ui::ROTATION_270);
Prabir Pradhanea31d4f2022-11-10 20:48:01 +00006104 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 -07006105 processSync(mapper);
6106
6107 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6108 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6109 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6110
6111 processUp(mapper);
6112 processSync(mapper);
6113 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6114}
6115
Prabir Pradhan675f25a2022-11-10 22:04:07 +00006116TEST_F(SingleTouchInputMapperTest, Process_IgnoresTouchesOutsidePhysicalFrame) {
6117 addConfigurationProperty("touch.deviceType", "touchScreen");
6118 prepareButtons();
6119 prepareAxes(POSITION);
6120 addConfigurationProperty("touch.orientationAware", "1");
6121 prepareDisplay(ui::ROTATION_0);
Arpit Singha8c236b2023-04-25 13:56:05 +00006122 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan675f25a2022-11-10 22:04:07 +00006123
6124 // Set a physical frame in the display viewport.
6125 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
6126 viewport->physicalLeft = 20;
6127 viewport->physicalTop = 600;
6128 viewport->physicalRight = 30;
6129 viewport->physicalBottom = 610;
6130 mFakePolicy->updateViewport(*viewport);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00006131 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhan675f25a2022-11-10 22:04:07 +00006132
6133 // Start the touch.
6134 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
6135 processSync(mapper);
6136
6137 // Expect all input starting outside the physical frame to be ignored.
6138 const std::array<Point, 6> outsidePoints = {
6139 {{0, 0}, {19, 605}, {31, 605}, {25, 599}, {25, 611}, {DISPLAY_WIDTH, DISPLAY_HEIGHT}}};
6140 for (const auto& p : outsidePoints) {
6141 processMove(mapper, toRawX(p.x), toRawY(p.y));
6142 processSync(mapper);
6143 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6144 }
6145
6146 // Move the touch into the physical frame.
6147 processMove(mapper, toRawX(25), toRawY(605));
6148 processSync(mapper);
6149 NotifyMotionArgs args;
6150 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6151 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
6152 EXPECT_NEAR(25, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6153 EXPECT_NEAR(605, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6154
6155 // Once the touch down is reported, continue reporting input, even if it is outside the frame.
6156 for (const auto& p : outsidePoints) {
6157 processMove(mapper, toRawX(p.x), toRawY(p.y));
6158 processSync(mapper);
6159 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6160 EXPECT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
6161 EXPECT_NEAR(p.x, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
6162 EXPECT_NEAR(p.y, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
6163 }
6164
6165 processUp(mapper);
6166 processSync(mapper);
6167 EXPECT_NO_FATAL_FAILURE(
6168 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
6169}
6170
Harry Cutts1db43992023-06-19 17:05:07 +00006171TEST_F(SingleTouchInputMapperTest, Process_DoesntCheckPhysicalFrameForTouchpads) {
6172 std::shared_ptr<FakePointerController> fakePointerController =
6173 std::make_shared<FakePointerController>();
6174 mFakePolicy->setPointerController(fakePointerController);
6175
6176 addConfigurationProperty("touch.deviceType", "pointer");
6177 prepareAxes(POSITION);
6178 prepareDisplay(ui::ROTATION_0);
6179 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
6180
6181 // Set a physical frame in the display viewport.
6182 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
6183 viewport->physicalLeft = 20;
6184 viewport->physicalTop = 600;
6185 viewport->physicalRight = 30;
6186 viewport->physicalBottom = 610;
6187 mFakePolicy->updateViewport(*viewport);
6188 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
6189
6190 // Start the touch.
6191 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
6192 processSync(mapper);
6193
6194 // Expect all input starting outside the physical frame to result in NotifyMotionArgs being
6195 // produced.
6196 const std::array<Point, 6> outsidePoints = {
6197 {{0, 0}, {19, 605}, {31, 605}, {25, 599}, {25, 611}, {DISPLAY_WIDTH, DISPLAY_HEIGHT}}};
6198 for (const auto& p : outsidePoints) {
6199 processMove(mapper, toRawX(p.x), toRawY(p.y));
6200 processSync(mapper);
6201 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
6202 }
6203}
6204
Michael Wrightd02c5b62014-02-10 15:10:22 -08006205TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006206 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006207 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006208 prepareButtons();
6209 prepareAxes(POSITION | PRESSURE | TOOL | DISTANCE | TILT);
Arpit Singha8c236b2023-04-25 13:56:05 +00006210 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006211
6212 // These calculations are based on the input device calibration documentation.
6213 int32_t rawX = 100;
6214 int32_t rawY = 200;
6215 int32_t rawPressure = 10;
6216 int32_t rawToolMajor = 12;
6217 int32_t rawDistance = 2;
6218 int32_t rawTiltX = 30;
6219 int32_t rawTiltY = 110;
6220
6221 float x = toDisplayX(rawX);
6222 float y = toDisplayY(rawY);
6223 float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
6224 float size = float(rawToolMajor) / RAW_TOOL_MAX;
6225 float tool = float(rawToolMajor) * GEOMETRIC_SCALE;
6226 float distance = float(rawDistance);
6227
6228 float tiltCenter = (RAW_TILT_MAX + RAW_TILT_MIN) * 0.5f;
6229 float tiltScale = M_PI / 180;
6230 float tiltXAngle = (rawTiltX - tiltCenter) * tiltScale;
6231 float tiltYAngle = (rawTiltY - tiltCenter) * tiltScale;
6232 float orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
6233 float tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
6234
6235 processDown(mapper, rawX, rawY);
6236 processPressure(mapper, rawPressure);
6237 processToolMajor(mapper, rawToolMajor);
6238 processDistance(mapper, rawDistance);
6239 processTilt(mapper, rawTiltX, rawTiltY);
6240 processSync(mapper);
6241
6242 NotifyMotionArgs args;
6243 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6244 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
6245 x, y, pressure, size, tool, tool, tool, tool, orientation, distance));
6246 ASSERT_EQ(tilt, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TILT));
6247}
6248
Jason Gerecke489fda82012-09-07 17:19:40 -07006249TEST_F(SingleTouchInputMapperTest, Process_XYAxes_AffineCalibration) {
Jason Gerecke489fda82012-09-07 17:19:40 -07006250 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006251 prepareDisplay(ui::ROTATION_0);
Jason Gerecke489fda82012-09-07 17:19:40 -07006252 prepareLocationCalibration();
6253 prepareButtons();
6254 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00006255 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Jason Gerecke489fda82012-09-07 17:19:40 -07006256
6257 int32_t rawX = 100;
6258 int32_t rawY = 200;
6259
6260 float x = toDisplayX(toCookedX(rawX, rawY));
6261 float y = toDisplayY(toCookedY(rawX, rawY));
6262
6263 processDown(mapper, rawX, rawY);
6264 processSync(mapper);
6265
6266 NotifyMotionArgs args;
6267 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6268 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
6269 x, y, 1, 0, 0, 0, 0, 0, 0, 0));
6270}
6271
Michael Wrightd02c5b62014-02-10 15:10:22 -08006272TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006273 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006274 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006275 prepareButtons();
6276 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00006277 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006278
6279 NotifyMotionArgs motionArgs;
6280 NotifyKeyArgs keyArgs;
6281
6282 processDown(mapper, 100, 200);
6283 processSync(mapper);
6284 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6285 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6286 ASSERT_EQ(0, motionArgs.buttonState);
6287
6288 // press BTN_LEFT, release BTN_LEFT
6289 processKey(mapper, BTN_LEFT, 1);
6290 processSync(mapper);
6291 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6292 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6293 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
6294
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006295 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6296 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6297 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
6298
Michael Wrightd02c5b62014-02-10 15:10:22 -08006299 processKey(mapper, BTN_LEFT, 0);
6300 processSync(mapper);
6301 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006302 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006303 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006304
6305 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006306 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006307 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006308
6309 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
6310 processKey(mapper, BTN_RIGHT, 1);
6311 processKey(mapper, BTN_MIDDLE, 1);
6312 processSync(mapper);
6313 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6314 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6315 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
6316 motionArgs.buttonState);
6317
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006318 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6319 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6320 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
6321
6322 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6323 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6324 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
6325 motionArgs.buttonState);
6326
Michael Wrightd02c5b62014-02-10 15:10:22 -08006327 processKey(mapper, BTN_RIGHT, 0);
6328 processSync(mapper);
6329 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006330 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006331 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006332
6333 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006334 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006335 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006336
6337 processKey(mapper, BTN_MIDDLE, 0);
6338 processSync(mapper);
6339 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006340 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006341 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006342
6343 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006344 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006345 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006346
6347 // press BTN_BACK, release BTN_BACK
6348 processKey(mapper, BTN_BACK, 1);
6349 processSync(mapper);
6350 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6351 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6352 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006353
Michael Wrightd02c5b62014-02-10 15:10:22 -08006354 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006355 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006356 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
6357
6358 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6359 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6360 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006361
6362 processKey(mapper, BTN_BACK, 0);
6363 processSync(mapper);
6364 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006365 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006366 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006367
6368 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006369 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006370 ASSERT_EQ(0, motionArgs.buttonState);
6371
Michael Wrightd02c5b62014-02-10 15:10:22 -08006372 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6373 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6374 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
6375
6376 // press BTN_SIDE, release BTN_SIDE
6377 processKey(mapper, BTN_SIDE, 1);
6378 processSync(mapper);
6379 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6380 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6381 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006382
Michael Wrightd02c5b62014-02-10 15:10:22 -08006383 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006384 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006385 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
6386
6387 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6388 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6389 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006390
6391 processKey(mapper, BTN_SIDE, 0);
6392 processSync(mapper);
6393 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006394 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006395 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006396
6397 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006398 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006399 ASSERT_EQ(0, motionArgs.buttonState);
6400
Michael Wrightd02c5b62014-02-10 15:10:22 -08006401 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6402 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6403 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
6404
6405 // press BTN_FORWARD, release BTN_FORWARD
6406 processKey(mapper, BTN_FORWARD, 1);
6407 processSync(mapper);
6408 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6409 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6410 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006411
Michael Wrightd02c5b62014-02-10 15:10:22 -08006412 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006413 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006414 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
6415
6416 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6417 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6418 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006419
6420 processKey(mapper, BTN_FORWARD, 0);
6421 processSync(mapper);
6422 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006423 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006424 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006425
6426 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006427 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006428 ASSERT_EQ(0, motionArgs.buttonState);
6429
Michael Wrightd02c5b62014-02-10 15:10:22 -08006430 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6431 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6432 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
6433
6434 // press BTN_EXTRA, release BTN_EXTRA
6435 processKey(mapper, BTN_EXTRA, 1);
6436 processSync(mapper);
6437 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6438 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6439 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006440
Michael Wrightd02c5b62014-02-10 15:10:22 -08006441 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006442 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006443 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
6444
6445 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6446 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6447 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006448
6449 processKey(mapper, BTN_EXTRA, 0);
6450 processSync(mapper);
6451 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006452 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006453 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006454
6455 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006456 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006457 ASSERT_EQ(0, motionArgs.buttonState);
6458
Michael Wrightd02c5b62014-02-10 15:10:22 -08006459 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6460 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6461 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
6462
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006463 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6464
Michael Wrightd02c5b62014-02-10 15:10:22 -08006465 // press BTN_STYLUS, release BTN_STYLUS
6466 processKey(mapper, BTN_STYLUS, 1);
6467 processSync(mapper);
6468 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6469 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006470 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
6471
6472 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6473 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6474 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006475
6476 processKey(mapper, BTN_STYLUS, 0);
6477 processSync(mapper);
6478 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006479 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006480 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006481
6482 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006483 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006484 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006485
6486 // press BTN_STYLUS2, release BTN_STYLUS2
6487 processKey(mapper, BTN_STYLUS2, 1);
6488 processSync(mapper);
6489 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6490 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006491 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
6492
6493 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6494 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6495 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006496
6497 processKey(mapper, BTN_STYLUS2, 0);
6498 processSync(mapper);
6499 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006500 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006501 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006502
6503 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006504 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006505 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006506
6507 // release touch
6508 processUp(mapper);
6509 processSync(mapper);
6510 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6511 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6512 ASSERT_EQ(0, motionArgs.buttonState);
6513}
6514
6515TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006516 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006517 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006518 prepareButtons();
6519 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00006520 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006521
6522 NotifyMotionArgs motionArgs;
6523
6524 // default tool type is finger
6525 processDown(mapper, 100, 200);
6526 processSync(mapper);
6527 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6528 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006529 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006530
6531 // eraser
6532 processKey(mapper, BTN_TOOL_RUBBER, 1);
6533 processSync(mapper);
6534 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6535 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006536 ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006537
6538 // stylus
6539 processKey(mapper, BTN_TOOL_RUBBER, 0);
6540 processKey(mapper, BTN_TOOL_PEN, 1);
6541 processSync(mapper);
6542 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6543 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006544 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006545
6546 // brush
6547 processKey(mapper, BTN_TOOL_PEN, 0);
6548 processKey(mapper, BTN_TOOL_BRUSH, 1);
6549 processSync(mapper);
6550 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6551 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006552 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006553
6554 // pencil
6555 processKey(mapper, BTN_TOOL_BRUSH, 0);
6556 processKey(mapper, BTN_TOOL_PENCIL, 1);
6557 processSync(mapper);
6558 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6559 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006560 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006561
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08006562 // air-brush
Michael Wrightd02c5b62014-02-10 15:10:22 -08006563 processKey(mapper, BTN_TOOL_PENCIL, 0);
6564 processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
6565 processSync(mapper);
6566 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6567 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006568 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006569
6570 // mouse
6571 processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
6572 processKey(mapper, BTN_TOOL_MOUSE, 1);
6573 processSync(mapper);
6574 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6575 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006576 ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006577
6578 // lens
6579 processKey(mapper, BTN_TOOL_MOUSE, 0);
6580 processKey(mapper, BTN_TOOL_LENS, 1);
6581 processSync(mapper);
6582 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6583 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006584 ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006585
6586 // double-tap
6587 processKey(mapper, BTN_TOOL_LENS, 0);
6588 processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
6589 processSync(mapper);
6590 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6591 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006592 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006593
6594 // triple-tap
6595 processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
6596 processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
6597 processSync(mapper);
6598 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6599 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006600 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006601
6602 // quad-tap
6603 processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
6604 processKey(mapper, BTN_TOOL_QUADTAP, 1);
6605 processSync(mapper);
6606 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6607 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006608 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006609
6610 // finger
6611 processKey(mapper, BTN_TOOL_QUADTAP, 0);
6612 processKey(mapper, BTN_TOOL_FINGER, 1);
6613 processSync(mapper);
6614 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6615 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006616 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006617
6618 // stylus trumps finger
6619 processKey(mapper, BTN_TOOL_PEN, 1);
6620 processSync(mapper);
6621 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6622 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006623 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006624
6625 // eraser trumps stylus
6626 processKey(mapper, BTN_TOOL_RUBBER, 1);
6627 processSync(mapper);
6628 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6629 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006630 ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006631
6632 // mouse trumps eraser
6633 processKey(mapper, BTN_TOOL_MOUSE, 1);
6634 processSync(mapper);
6635 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6636 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006637 ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006638
6639 // back to default tool type
6640 processKey(mapper, BTN_TOOL_MOUSE, 0);
6641 processKey(mapper, BTN_TOOL_RUBBER, 0);
6642 processKey(mapper, BTN_TOOL_PEN, 0);
6643 processKey(mapper, BTN_TOOL_FINGER, 0);
6644 processSync(mapper);
6645 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6646 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07006647 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006648}
6649
6650TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006651 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006652 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006653 prepareButtons();
6654 prepareAxes(POSITION);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006655 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_FINGER, 0, AKEYCODE_UNKNOWN, 0);
Arpit Singha8c236b2023-04-25 13:56:05 +00006656 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006657
6658 NotifyMotionArgs motionArgs;
6659
6660 // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
6661 processKey(mapper, BTN_TOOL_FINGER, 1);
6662 processMove(mapper, 100, 200);
6663 processSync(mapper);
6664 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6665 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6666 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6667 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6668
6669 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6670 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6671 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6672 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6673
6674 // move a little
6675 processMove(mapper, 150, 250);
6676 processSync(mapper);
6677 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6678 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6679 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6680 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6681
6682 // down when BTN_TOUCH is pressed, pressure defaults to 1
6683 processKey(mapper, BTN_TOUCH, 1);
6684 processSync(mapper);
6685 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6686 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6687 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6688 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6689
6690 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6691 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6692 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6693 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6694
6695 // up when BTN_TOUCH is released, hover restored
6696 processKey(mapper, BTN_TOUCH, 0);
6697 processSync(mapper);
6698 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6699 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6700 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6701 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6702
6703 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6704 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6705 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6706 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6707
6708 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6709 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6710 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6711 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6712
6713 // exit hover when pointer goes away
6714 processKey(mapper, BTN_TOOL_FINGER, 0);
6715 processSync(mapper);
6716 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6717 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6718 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6719 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6720}
6721
6722TEST_F(SingleTouchInputMapperTest, Process_WhenAbsPressureIsPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006723 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006724 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006725 prepareButtons();
6726 prepareAxes(POSITION | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +00006727 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006728
6729 NotifyMotionArgs motionArgs;
6730
6731 // initially hovering because pressure is 0
6732 processDown(mapper, 100, 200);
6733 processPressure(mapper, 0);
6734 processSync(mapper);
6735 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6736 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6737 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6738 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6739
6740 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6741 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6742 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6743 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6744
6745 // move a little
6746 processMove(mapper, 150, 250);
6747 processSync(mapper);
6748 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6749 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6750 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6751 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6752
6753 // down when pressure is non-zero
6754 processPressure(mapper, RAW_PRESSURE_MAX);
6755 processSync(mapper);
6756 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6757 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6758 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6759 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6760
6761 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6762 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6763 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6764 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6765
6766 // up when pressure becomes 0, hover restored
6767 processPressure(mapper, 0);
6768 processSync(mapper);
6769 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6770 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6771 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6772 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6773
6774 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6775 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6776 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6777 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6778
6779 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6780 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6781 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6782 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6783
6784 // exit hover when pointer goes away
6785 processUp(mapper);
6786 processSync(mapper);
6787 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6788 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6789 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6790 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6791}
6792
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00006793TEST_F(SingleTouchInputMapperTest, Reset_CancelsOngoingGesture) {
6794 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006795 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00006796 prepareButtons();
6797 prepareAxes(POSITION | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +00006798 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00006799
6800 // Touch down.
6801 processDown(mapper, 100, 200);
6802 processPressure(mapper, 1);
6803 processSync(mapper);
6804 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6805 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
6806
6807 // Reset the mapper. This should cancel the ongoing gesture.
6808 resetMapper(mapper, ARBITRARY_TIME);
6809 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6810 WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
6811
6812 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6813}
6814
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006815TEST_F(SingleTouchInputMapperTest, Reset_RecreatesTouchState) {
6816 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006817 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006818 prepareButtons();
6819 prepareAxes(POSITION | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +00006820 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006821
6822 // Set the initial state for the touch pointer.
6823 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_X, 100);
6824 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_Y, 200);
6825 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MAX);
6826 mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1);
6827
6828 // Reset the mapper. When the mapper is reset, we expect it to attempt to recreate the touch
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00006829 // state by reading the current axis values. Since there was no ongoing gesture, calling reset
6830 // does not generate any events.
6831 resetMapper(mapper, ARBITRARY_TIME);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006832
6833 // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
6834 // the recreated touch state to generate a down event.
6835 processSync(mapper);
6836 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6837 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
6838
6839 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6840}
6841
lilinnan687e58f2022-07-19 16:00:50 +08006842TEST_F(SingleTouchInputMapperTest,
6843 Process_WhenViewportDisplayIdChanged_TouchIsCanceledAndDeviceIsReset) {
6844 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006845 prepareDisplay(ui::ROTATION_0);
lilinnan687e58f2022-07-19 16:00:50 +08006846 prepareButtons();
6847 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00006848 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
lilinnan687e58f2022-07-19 16:00:50 +08006849 NotifyMotionArgs motionArgs;
6850
6851 // Down.
Prabir Pradhan3e5ec702022-07-29 16:26:24 +00006852 processDown(mapper, 100, 200);
lilinnan687e58f2022-07-19 16:00:50 +08006853 processSync(mapper);
6854
6855 // We should receive a down event
6856 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6857 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6858
6859 // Change display id
6860 clearViewports();
6861 prepareSecondaryDisplay(ViewportType::INTERNAL);
6862
6863 // We should receive a cancel event
6864 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6865 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
6866 // Then receive reset called
6867 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6868}
6869
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006870TEST_F(SingleTouchInputMapperTest,
6871 Process_WhenViewportActiveStatusChanged_TouchIsCanceledAndDeviceIsReset) {
6872 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006873 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006874 prepareButtons();
6875 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00006876 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006877 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6878 NotifyMotionArgs motionArgs;
6879
6880 // Start a new gesture.
6881 processDown(mapper, 100, 200);
6882 processSync(mapper);
6883 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6884 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6885
6886 // Make the viewport inactive. This will put the device in disabled mode.
6887 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
6888 viewport->isActive = false;
6889 mFakePolicy->updateViewport(*viewport);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00006890 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006891
6892 // We should receive a cancel event for the ongoing gesture.
6893 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6894 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
6895 // Then we should be notified that the device was reset.
6896 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6897
6898 // No events are generated while the viewport is inactive.
6899 processMove(mapper, 101, 201);
6900 processSync(mapper);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006901 processUp(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006902 processSync(mapper);
6903 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6904
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006905 // Start a new gesture while the viewport is still inactive.
6906 processDown(mapper, 300, 400);
6907 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_X, 300);
6908 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_Y, 400);
6909 mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1);
6910 processSync(mapper);
6911
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006912 // Make the viewport active again. The device should resume processing events.
6913 viewport->isActive = true;
6914 mFakePolicy->updateViewport(*viewport);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00006915 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006916
6917 // The device is reset because it changes back to direct mode, without generating any events.
6918 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6919 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6920
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006921 // In the next sync, the touch state that was recreated when the device was reset is reported.
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006922 processSync(mapper);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006923 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6924 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006925
6926 // No more events.
6927 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6928 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
6929}
6930
Prabir Pradhan211ba622022-10-31 21:09:21 +00006931TEST_F(SingleTouchInputMapperTest, ButtonIsReleasedOnTouchUp) {
6932 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006933 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan211ba622022-10-31 21:09:21 +00006934 prepareButtons();
6935 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00006936 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan211ba622022-10-31 21:09:21 +00006937 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6938
6939 // Press a stylus button.
6940 processKey(mapper, BTN_STYLUS, 1);
6941 processSync(mapper);
6942
6943 // Start a touch gesture and ensure the BUTTON_PRESS event is generated.
6944 processDown(mapper, 100, 200);
6945 processSync(mapper);
6946 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6947 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
6948 WithCoords(toDisplayX(100), toDisplayY(200)),
6949 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
6950 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6951 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
6952 WithCoords(toDisplayX(100), toDisplayY(200)),
6953 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
6954
6955 // Release the touch gesture. Ensure that the BUTTON_RELEASE event is generated even though
6956 // the button has not actually been released, since there will be no pointers through which the
6957 // button state can be reported. The event is generated at the location of the pointer before
6958 // it went up.
6959 processUp(mapper);
6960 processSync(mapper);
6961 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6962 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
6963 WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
6964 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6965 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
6966 WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
6967}
6968
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00006969TEST_F(SingleTouchInputMapperTest, StylusButtonMotionEventsDisabled) {
6970 addConfigurationProperty("touch.deviceType", "touchScreen");
6971 prepareDisplay(ui::ROTATION_0);
6972 prepareButtons();
6973 prepareAxes(POSITION);
6974
6975 mFakePolicy->setStylusButtonMotionEventsEnabled(false);
6976
Arpit Singha8c236b2023-04-25 13:56:05 +00006977 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan7aa7ff02022-12-21 21:05:38 +00006978 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6979
6980 // Press a stylus button.
6981 processKey(mapper, BTN_STYLUS, 1);
6982 processSync(mapper);
6983
6984 // Start a touch gesture and ensure that the stylus button is not reported.
6985 processDown(mapper, 100, 200);
6986 processSync(mapper);
6987 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6988 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithButtonState(0))));
6989
6990 // Release and press the stylus button again.
6991 processKey(mapper, BTN_STYLUS, 0);
6992 processSync(mapper);
6993 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6994 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
6995 processKey(mapper, BTN_STYLUS, 1);
6996 processSync(mapper);
6997 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6998 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
6999
7000 // Release the touch gesture.
7001 processUp(mapper);
7002 processSync(mapper);
7003 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7004 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
7005
7006 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7007}
7008
Ambrus Weisz7bc23bf2022-10-04 13:13:07 +00007009TEST_F(SingleTouchInputMapperTest, WhenDeviceTypeIsSetToTouchNavigation_setsCorrectType) {
7010 mFakePolicy->addDeviceTypeAssociation(DEVICE_LOCATION, "touchNavigation");
7011 prepareDisplay(ui::ROTATION_0);
7012 prepareButtons();
7013 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00007014 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Ambrus Weisz7bc23bf2022-10-04 13:13:07 +00007015 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
7016
7017 ASSERT_EQ(AINPUT_SOURCE_TOUCH_NAVIGATION, mapper.getSources());
7018}
7019
Seunghwan Choi356026c2023-02-01 14:37:25 +09007020TEST_F(SingleTouchInputMapperTest, Process_WhenConfigEnabled_ShouldShowDirectStylusPointer) {
7021 std::shared_ptr<FakePointerController> fakePointerController =
7022 std::make_shared<FakePointerController>();
7023 addConfigurationProperty("touch.deviceType", "touchScreen");
7024 prepareDisplay(ui::ROTATION_0);
7025 prepareButtons();
7026 prepareAxes(POSITION);
7027 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
7028 mFakePolicy->setPointerController(fakePointerController);
7029 mFakePolicy->setStylusPointerIconEnabled(true);
Arpit Singha8c236b2023-04-25 13:56:05 +00007030 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Seunghwan Choi356026c2023-02-01 14:37:25 +09007031
7032 processKey(mapper, BTN_TOOL_PEN, 1);
7033 processMove(mapper, 100, 200);
7034 processSync(mapper);
7035 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7036 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007037 WithToolType(ToolType::STYLUS),
Seunghwan Choi356026c2023-02-01 14:37:25 +09007038 WithPointerCoords(0, toDisplayX(100), toDisplayY(200)))));
7039 ASSERT_TRUE(fakePointerController->isPointerShown());
7040 ASSERT_NO_FATAL_FAILURE(
7041 fakePointerController->assertPosition(toDisplayX(100), toDisplayY(200)));
7042}
7043
7044TEST_F(SingleTouchInputMapperTest, Process_WhenConfigDisabled_ShouldNotShowDirectStylusPointer) {
7045 std::shared_ptr<FakePointerController> fakePointerController =
7046 std::make_shared<FakePointerController>();
7047 addConfigurationProperty("touch.deviceType", "touchScreen");
7048 prepareDisplay(ui::ROTATION_0);
7049 prepareButtons();
7050 prepareAxes(POSITION);
7051 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
7052 mFakePolicy->setPointerController(fakePointerController);
7053 mFakePolicy->setStylusPointerIconEnabled(false);
Arpit Singha8c236b2023-04-25 13:56:05 +00007054 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Seunghwan Choi356026c2023-02-01 14:37:25 +09007055
7056 processKey(mapper, BTN_TOOL_PEN, 1);
7057 processMove(mapper, 100, 200);
7058 processSync(mapper);
7059 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7060 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007061 WithToolType(ToolType::STYLUS),
Seunghwan Choi356026c2023-02-01 14:37:25 +09007062 WithPointerCoords(0, toDisplayX(100), toDisplayY(200)))));
7063 ASSERT_FALSE(fakePointerController->isPointerShown());
7064}
7065
Ambrus Weisz7b6e16b2022-12-16 17:54:57 +00007066TEST_F(SingleTouchInputMapperTest, WhenDeviceTypeIsChangedToTouchNavigation_updatesDeviceType) {
7067 // Initialize the device without setting device source to touch navigation.
7068 addConfigurationProperty("touch.deviceType", "touchScreen");
7069 prepareDisplay(ui::ROTATION_0);
7070 prepareButtons();
7071 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00007072 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Ambrus Weisz7b6e16b2022-12-16 17:54:57 +00007073
7074 // Ensure that the device is created as a touchscreen, not touch navigation.
7075 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
7076
7077 // Add device type association after the device was created.
7078 mFakePolicy->addDeviceTypeAssociation(DEVICE_LOCATION, "touchNavigation");
7079
7080 // Send update to the mapper.
7081 std::list<NotifyArgs> unused2 =
7082 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00007083 InputReaderConfiguration::Change::DEVICE_TYPE /*changes*/);
Ambrus Weisz7b6e16b2022-12-16 17:54:57 +00007084
7085 // Check whether device type update was successful.
7086 ASSERT_EQ(AINPUT_SOURCE_TOUCH_NAVIGATION, mDevice->getSources());
7087}
7088
Prabir Pradhane1e309a2022-11-29 02:54:27 +00007089TEST_F(SingleTouchInputMapperTest, HoverEventsOutsidePhysicalFrameAreIgnored) {
7090 // Initialize the device without setting device source to touch navigation.
7091 addConfigurationProperty("touch.deviceType", "touchScreen");
7092 prepareDisplay(ui::ROTATION_0);
7093 prepareButtons();
7094 prepareAxes(POSITION);
7095 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
7096
7097 // Set a physical frame in the display viewport.
7098 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
7099 viewport->physicalLeft = 0;
7100 viewport->physicalTop = 0;
7101 viewport->physicalRight = DISPLAY_WIDTH / 2;
7102 viewport->physicalBottom = DISPLAY_HEIGHT / 2;
7103 mFakePolicy->updateViewport(*viewport);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00007104 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhane1e309a2022-11-29 02:54:27 +00007105
Arpit Singha8c236b2023-04-25 13:56:05 +00007106 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhane1e309a2022-11-29 02:54:27 +00007107
7108 // Hovering inside the physical frame produces events.
7109 processKey(mapper, BTN_TOOL_PEN, 1);
7110 processMove(mapper, RAW_X_MIN + 1, RAW_Y_MIN + 1);
7111 processSync(mapper);
7112 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7113 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER)));
7114 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7115 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE)));
7116
7117 // Leaving the physical frame ends the hovering gesture.
7118 processMove(mapper, RAW_X_MAX - 1, RAW_Y_MAX - 1);
7119 processSync(mapper);
7120 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7121 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT)));
7122
7123 // Moving outside the physical frame does not produce events.
7124 processMove(mapper, RAW_X_MAX - 2, RAW_Y_MAX - 2);
7125 processSync(mapper);
7126 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7127
7128 // Re-entering the physical frame produces events.
7129 processMove(mapper, RAW_X_MIN, RAW_Y_MIN);
7130 processSync(mapper);
7131 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7132 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER)));
7133 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7134 WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE)));
7135}
7136
Prabir Pradhan5632d622021-09-06 07:57:20 -07007137// --- TouchDisplayProjectionTest ---
7138
7139class TouchDisplayProjectionTest : public SingleTouchInputMapperTest {
7140public:
7141 // The values inside DisplayViewport are expected to be pre-rotated. This updates the current
7142 // DisplayViewport to pre-rotate the values. The viewport's physical display will be set to the
7143 // rotated equivalent of the given un-rotated physical display bounds.
Prabir Pradhana9df3162022-12-05 23:57:27 +00007144 void configurePhysicalDisplay(ui::Rotation orientation, Rect naturalPhysicalDisplay,
7145 int32_t naturalDisplayWidth = DISPLAY_WIDTH,
7146 int32_t naturalDisplayHeight = DISPLAY_HEIGHT) {
Prabir Pradhan5632d622021-09-06 07:57:20 -07007147 uint32_t inverseRotationFlags;
Prabir Pradhana9df3162022-12-05 23:57:27 +00007148 auto rotatedWidth = naturalDisplayWidth;
7149 auto rotatedHeight = naturalDisplayHeight;
Prabir Pradhan5632d622021-09-06 07:57:20 -07007150 switch (orientation) {
Michael Wrighta9cf4192022-12-01 23:46:39 +00007151 case ui::ROTATION_90:
Prabir Pradhan5632d622021-09-06 07:57:20 -07007152 inverseRotationFlags = ui::Transform::ROT_270;
Prabir Pradhana9df3162022-12-05 23:57:27 +00007153 std::swap(rotatedWidth, rotatedHeight);
Prabir Pradhan5632d622021-09-06 07:57:20 -07007154 break;
Michael Wrighta9cf4192022-12-01 23:46:39 +00007155 case ui::ROTATION_180:
Prabir Pradhan5632d622021-09-06 07:57:20 -07007156 inverseRotationFlags = ui::Transform::ROT_180;
7157 break;
Michael Wrighta9cf4192022-12-01 23:46:39 +00007158 case ui::ROTATION_270:
Prabir Pradhan5632d622021-09-06 07:57:20 -07007159 inverseRotationFlags = ui::Transform::ROT_90;
Prabir Pradhana9df3162022-12-05 23:57:27 +00007160 std::swap(rotatedWidth, rotatedHeight);
Prabir Pradhan5632d622021-09-06 07:57:20 -07007161 break;
Michael Wrighta9cf4192022-12-01 23:46:39 +00007162 case ui::ROTATION_0:
Prabir Pradhan5632d622021-09-06 07:57:20 -07007163 inverseRotationFlags = ui::Transform::ROT_0;
7164 break;
Prabir Pradhan5632d622021-09-06 07:57:20 -07007165 }
7166
Prabir Pradhana9df3162022-12-05 23:57:27 +00007167 const ui::Transform rotation(inverseRotationFlags, rotatedWidth, rotatedHeight);
Prabir Pradhan5632d622021-09-06 07:57:20 -07007168 const Rect rotatedPhysicalDisplay = rotation.transform(naturalPhysicalDisplay);
7169
7170 std::optional<DisplayViewport> internalViewport =
7171 *mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
7172 DisplayViewport& v = *internalViewport;
7173 v.displayId = DISPLAY_ID;
7174 v.orientation = orientation;
7175
7176 v.logicalLeft = 0;
7177 v.logicalTop = 0;
7178 v.logicalRight = 100;
7179 v.logicalBottom = 100;
7180
7181 v.physicalLeft = rotatedPhysicalDisplay.left;
7182 v.physicalTop = rotatedPhysicalDisplay.top;
7183 v.physicalRight = rotatedPhysicalDisplay.right;
7184 v.physicalBottom = rotatedPhysicalDisplay.bottom;
7185
Prabir Pradhana9df3162022-12-05 23:57:27 +00007186 v.deviceWidth = rotatedWidth;
7187 v.deviceHeight = rotatedHeight;
Prabir Pradhan5632d622021-09-06 07:57:20 -07007188
7189 v.isActive = true;
7190 v.uniqueId = UNIQUE_ID;
7191 v.type = ViewportType::INTERNAL;
7192 mFakePolicy->updateViewport(v);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00007193 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhan5632d622021-09-06 07:57:20 -07007194 }
7195
7196 void assertReceivedMove(const Point& point) {
7197 NotifyMotionArgs motionArgs;
7198 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7199 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07007200 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Prabir Pradhan5632d622021-09-06 07:57:20 -07007201 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], point.x, point.y,
7202 1, 0, 0, 0, 0, 0, 0, 0));
7203 }
7204};
7205
7206TEST_F(TouchDisplayProjectionTest, IgnoresTouchesOutsidePhysicalDisplay) {
7207 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007208 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan5632d622021-09-06 07:57:20 -07007209
7210 prepareButtons();
7211 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00007212 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan5632d622021-09-06 07:57:20 -07007213
7214 NotifyMotionArgs motionArgs;
7215
7216 // Configure the DisplayViewport such that the logical display maps to a subsection of
7217 // the display panel called the physical display. Here, the physical display is bounded by the
7218 // points (10, 20) and (70, 160) inside the display space, which is of the size 400 x 800.
7219 static const Rect kPhysicalDisplay{10, 20, 70, 160};
7220 static const std::array<Point, 6> kPointsOutsidePhysicalDisplay{
7221 {{-10, -10}, {0, 0}, {5, 100}, {50, 15}, {75, 100}, {50, 165}}};
7222
Michael Wrighta9cf4192022-12-01 23:46:39 +00007223 for (auto orientation : {ui::ROTATION_0, ui::ROTATION_90, ui::ROTATION_180, ui::ROTATION_270}) {
Prabir Pradhan5632d622021-09-06 07:57:20 -07007224 configurePhysicalDisplay(orientation, kPhysicalDisplay);
7225
7226 // Touches outside the physical display should be ignored, and should not generate any
7227 // events. Ensure touches at the following points that lie outside of the physical display
7228 // area do not generate any events.
7229 for (const auto& point : kPointsOutsidePhysicalDisplay) {
7230 processDown(mapper, toRawX(point.x), toRawY(point.y));
7231 processSync(mapper);
7232 processUp(mapper);
7233 processSync(mapper);
7234 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled())
7235 << "Unexpected event generated for touch outside physical display at point: "
7236 << point.x << ", " << point.y;
7237 }
7238 }
7239}
7240
7241TEST_F(TouchDisplayProjectionTest, EmitsTouchDownAfterEnteringPhysicalDisplay) {
7242 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007243 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan5632d622021-09-06 07:57:20 -07007244
7245 prepareButtons();
7246 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00007247 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan5632d622021-09-06 07:57:20 -07007248
7249 NotifyMotionArgs motionArgs;
7250
7251 // Configure the DisplayViewport such that the logical display maps to a subsection of
7252 // the display panel called the physical display. Here, the physical display is bounded by the
7253 // points (10, 20) and (70, 160) inside the display space, which is of the size 400 x 800.
7254 static const Rect kPhysicalDisplay{10, 20, 70, 160};
7255
Michael Wrighta9cf4192022-12-01 23:46:39 +00007256 for (auto orientation : {ui::ROTATION_0, ui::ROTATION_90, ui::ROTATION_180, ui::ROTATION_270}) {
Prabir Pradhan5632d622021-09-06 07:57:20 -07007257 configurePhysicalDisplay(orientation, kPhysicalDisplay);
7258
7259 // Touches that start outside the physical display should be ignored until it enters the
7260 // physical display bounds, at which point it should generate a down event. Start a touch at
7261 // the point (5, 100), which is outside the physical display bounds.
7262 static const Point kOutsidePoint{5, 100};
7263 processDown(mapper, toRawX(kOutsidePoint.x), toRawY(kOutsidePoint.y));
7264 processSync(mapper);
7265 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7266
7267 // Move the touch into the physical display area. This should generate a pointer down.
7268 processMove(mapper, toRawX(11), toRawY(21));
7269 processSync(mapper);
7270 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7271 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07007272 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Prabir Pradhan5632d622021-09-06 07:57:20 -07007273 ASSERT_NO_FATAL_FAILURE(
7274 assertPointerCoords(motionArgs.pointerCoords[0], 11, 21, 1, 0, 0, 0, 0, 0, 0, 0));
7275
7276 // Move the touch inside the physical display area. This should generate a pointer move.
7277 processMove(mapper, toRawX(69), toRawY(159));
7278 processSync(mapper);
7279 assertReceivedMove({69, 159});
7280
7281 // Move outside the physical display area. Since the pointer is already down, this should
7282 // now continue generating events.
7283 processMove(mapper, toRawX(kOutsidePoint.x), toRawY(kOutsidePoint.y));
7284 processSync(mapper);
7285 assertReceivedMove(kOutsidePoint);
7286
7287 // Release. This should generate a pointer up.
7288 processUp(mapper);
7289 processSync(mapper);
7290 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7291 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7292 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], kOutsidePoint.x,
7293 kOutsidePoint.y, 1, 0, 0, 0, 0, 0, 0, 0));
7294
7295 // Ensure no more events were generated.
7296 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7297 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7298 }
7299}
7300
Prabir Pradhana9df3162022-12-05 23:57:27 +00007301// --- TouchscreenPrecisionTests ---
7302
7303// This test suite is used to ensure that touchscreen devices are scaled and configured correctly
7304// in various orientations and with different display rotations. We configure the touchscreen to
7305// have a higher resolution than that of the display by an integer scale factor in each axis so that
7306// we can enforce that coordinates match precisely as expected.
7307class TouchscreenPrecisionTestsFixture : public TouchDisplayProjectionTest,
7308 public ::testing::WithParamInterface<ui::Rotation> {
7309public:
7310 void SetUp() override {
7311 SingleTouchInputMapperTest::SetUp();
7312
7313 // Prepare the raw axes to have twice the resolution of the display in the X axis and
7314 // four times the resolution of the display in the Y axis.
7315 prepareButtons();
7316 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, PRECISION_RAW_X_MIN, PRECISION_RAW_X_MAX,
Prabir Pradhan46211fb2022-12-17 00:30:39 +00007317 PRECISION_RAW_X_FLAT, PRECISION_RAW_X_FUZZ,
7318 PRECISION_RAW_X_RES);
Prabir Pradhana9df3162022-12-05 23:57:27 +00007319 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, PRECISION_RAW_Y_MIN, PRECISION_RAW_Y_MAX,
Prabir Pradhan46211fb2022-12-17 00:30:39 +00007320 PRECISION_RAW_Y_FLAT, PRECISION_RAW_Y_FUZZ,
7321 PRECISION_RAW_Y_RES);
Prabir Pradhana9df3162022-12-05 23:57:27 +00007322 }
7323
7324 static const int32_t PRECISION_RAW_X_MIN = TouchInputMapperTest::RAW_X_MIN;
7325 static const int32_t PRECISION_RAW_X_MAX = PRECISION_RAW_X_MIN + DISPLAY_WIDTH * 2 - 1;
7326 static const int32_t PRECISION_RAW_Y_MIN = TouchInputMapperTest::RAW_Y_MIN;
7327 static const int32_t PRECISION_RAW_Y_MAX = PRECISION_RAW_Y_MIN + DISPLAY_HEIGHT * 4 - 1;
7328
Prabir Pradhan46211fb2022-12-17 00:30:39 +00007329 static const int32_t PRECISION_RAW_X_RES = 50; // units per millimeter
7330 static const int32_t PRECISION_RAW_Y_RES = 100; // units per millimeter
7331
7332 static const int32_t PRECISION_RAW_X_FLAT = 16;
7333 static const int32_t PRECISION_RAW_Y_FLAT = 32;
7334
7335 static const int32_t PRECISION_RAW_X_FUZZ = 4;
7336 static const int32_t PRECISION_RAW_Y_FUZZ = 8;
7337
Prabir Pradhana9df3162022-12-05 23:57:27 +00007338 static const std::array<Point, 4> kRawCorners;
7339};
7340
7341const std::array<Point, 4> TouchscreenPrecisionTestsFixture::kRawCorners = {{
7342 {PRECISION_RAW_X_MIN, PRECISION_RAW_Y_MIN}, // left-top
7343 {PRECISION_RAW_X_MAX, PRECISION_RAW_Y_MIN}, // right-top
7344 {PRECISION_RAW_X_MAX, PRECISION_RAW_Y_MAX}, // right-bottom
7345 {PRECISION_RAW_X_MIN, PRECISION_RAW_Y_MAX}, // left-bottom
7346}};
7347
7348// Tests for how the touchscreen is oriented relative to the natural orientation of the display.
7349// For example, if a touchscreen is configured with an orientation of 90 degrees, it is a portrait
7350// touchscreen panel that is used on a device whose natural display orientation is in landscape.
7351TEST_P(TouchscreenPrecisionTestsFixture, OrientationPrecision) {
7352 enum class Orientation {
7353 ORIENTATION_0 = ui::toRotationInt(ui::ROTATION_0),
7354 ORIENTATION_90 = ui::toRotationInt(ui::ROTATION_90),
7355 ORIENTATION_180 = ui::toRotationInt(ui::ROTATION_180),
7356 ORIENTATION_270 = ui::toRotationInt(ui::ROTATION_270),
7357 ftl_last = ORIENTATION_270,
7358 };
7359 using Orientation::ORIENTATION_0, Orientation::ORIENTATION_90, Orientation::ORIENTATION_180,
7360 Orientation::ORIENTATION_270;
7361 static const std::map<Orientation, std::array<vec2, 4> /*mappedCorners*/> kMappedCorners = {
7362 {ORIENTATION_0, {{{0, 0}, {479.5, 0}, {479.5, 799.75}, {0, 799.75}}}},
7363 {ORIENTATION_90, {{{0, 479.5}, {0, 0}, {799.75, 0}, {799.75, 479.5}}}},
7364 {ORIENTATION_180, {{{479.5, 799.75}, {0, 799.75}, {0, 0}, {479.5, 0}}}},
7365 {ORIENTATION_270, {{{799.75, 0}, {799.75, 479.5}, {0, 479.5}, {0, 0}}}},
7366 };
7367
7368 const auto touchscreenOrientation = static_cast<Orientation>(ui::toRotationInt(GetParam()));
7369
7370 // Configure the touchscreen as being installed in the one of the four different orientations
7371 // relative to the display.
7372 addConfigurationProperty("touch.deviceType", "touchScreen");
7373 addConfigurationProperty("touch.orientation", ftl::enum_string(touchscreenOrientation).c_str());
7374 prepareDisplay(ui::ROTATION_0);
7375
Arpit Singha8c236b2023-04-25 13:56:05 +00007376 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhana9df3162022-12-05 23:57:27 +00007377
7378 // If the touchscreen is installed in a rotated orientation relative to the display (i.e. in
7379 // orientations of either 90 or 270) this means the display's natural resolution will be
7380 // flipped.
7381 const bool displayRotated =
7382 touchscreenOrientation == ORIENTATION_90 || touchscreenOrientation == ORIENTATION_270;
7383 const int32_t width = displayRotated ? DISPLAY_HEIGHT : DISPLAY_WIDTH;
7384 const int32_t height = displayRotated ? DISPLAY_WIDTH : DISPLAY_HEIGHT;
7385 const Rect physicalFrame{0, 0, width, height};
7386 configurePhysicalDisplay(ui::ROTATION_0, physicalFrame, width, height);
7387
7388 const auto& expectedPoints = kMappedCorners.at(touchscreenOrientation);
7389 const float expectedPrecisionX = displayRotated ? 4 : 2;
7390 const float expectedPrecisionY = displayRotated ? 2 : 4;
7391
7392 // Test all four corners.
7393 for (int i = 0; i < 4; i++) {
7394 const auto& raw = kRawCorners[i];
7395 processDown(mapper, raw.x, raw.y);
7396 processSync(mapper);
7397 const auto& expected = expectedPoints[i];
7398 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7399 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
7400 WithCoords(expected.x, expected.y),
7401 WithPrecision(expectedPrecisionX, expectedPrecisionY))))
7402 << "Failed to process raw point (" << raw.x << ", " << raw.y << ") "
7403 << "with touchscreen orientation "
7404 << ftl::enum_string(touchscreenOrientation).c_str() << ", expected point ("
7405 << expected.x << ", " << expected.y << ").";
7406 processUp(mapper);
7407 processSync(mapper);
7408 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7409 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
7410 WithCoords(expected.x, expected.y))));
7411 }
7412}
7413
Prabir Pradhan82687402022-12-06 01:32:53 +00007414TEST_P(TouchscreenPrecisionTestsFixture, RotationPrecisionWhenOrientationAware) {
7415 static const std::map<ui::Rotation /*rotation*/, std::array<vec2, 4> /*mappedCorners*/>
7416 kMappedCorners = {
7417 {ui::ROTATION_0, {{{0, 0}, {479.5, 0}, {479.5, 799.75}, {0, 799.75}}}},
7418 {ui::ROTATION_90, {{{0.5, 0}, {480, 0}, {480, 799.75}, {0.5, 799.75}}}},
7419 {ui::ROTATION_180, {{{0.5, 0.25}, {480, 0.25}, {480, 800}, {0.5, 800}}}},
7420 {ui::ROTATION_270, {{{0, 0.25}, {479.5, 0.25}, {479.5, 800}, {0, 800}}}},
7421 };
7422
7423 const ui::Rotation displayRotation = GetParam();
7424
7425 addConfigurationProperty("touch.deviceType", "touchScreen");
7426 prepareDisplay(displayRotation);
7427
Arpit Singha8c236b2023-04-25 13:56:05 +00007428 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan82687402022-12-06 01:32:53 +00007429
7430 const auto& expectedPoints = kMappedCorners.at(displayRotation);
7431
7432 // Test all four corners.
7433 for (int i = 0; i < 4; i++) {
7434 const auto& expected = expectedPoints[i];
7435 const auto& raw = kRawCorners[i];
7436 processDown(mapper, raw.x, raw.y);
7437 processSync(mapper);
7438 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7439 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
7440 WithCoords(expected.x, expected.y), WithPrecision(2, 4))))
7441 << "Failed to process raw point (" << raw.x << ", " << raw.y << ") "
7442 << "with display rotation " << ui::toCString(displayRotation)
7443 << ", expected point (" << expected.x << ", " << expected.y << ").";
7444 processUp(mapper);
7445 processSync(mapper);
7446 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7447 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
7448 WithCoords(expected.x, expected.y))));
7449 }
7450}
7451
Prabir Pradhan3e798762022-12-02 21:02:11 +00007452TEST_P(TouchscreenPrecisionTestsFixture, RotationPrecisionOrientationAwareInOri270) {
7453 static const std::map<ui::Rotation /*orientation*/, std::array<vec2, 4> /*mappedCorners*/>
7454 kMappedCorners = {
7455 {ui::ROTATION_0, {{{799.75, 0}, {799.75, 479.5}, {0, 479.5}, {0, 0}}}},
7456 {ui::ROTATION_90, {{{800, 0}, {800, 479.5}, {0.25, 479.5}, {0.25, 0}}}},
7457 {ui::ROTATION_180, {{{800, 0.5}, {800, 480}, {0.25, 480}, {0.25, 0.5}}}},
7458 {ui::ROTATION_270, {{{799.75, 0.5}, {799.75, 480}, {0, 480}, {0, 0.5}}}},
7459 };
7460
7461 const ui::Rotation displayRotation = GetParam();
7462
7463 addConfigurationProperty("touch.deviceType", "touchScreen");
7464 addConfigurationProperty("touch.orientation", "ORIENTATION_270");
7465
Arpit Singha8c236b2023-04-25 13:56:05 +00007466 SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan3e798762022-12-02 21:02:11 +00007467
7468 // Ori 270, so width and height swapped
7469 const Rect physicalFrame{0, 0, DISPLAY_HEIGHT, DISPLAY_WIDTH};
7470 prepareDisplay(displayRotation);
7471 configurePhysicalDisplay(displayRotation, physicalFrame, DISPLAY_HEIGHT, DISPLAY_WIDTH);
7472
7473 const auto& expectedPoints = kMappedCorners.at(displayRotation);
7474
7475 // Test all four corners.
7476 for (int i = 0; i < 4; i++) {
7477 const auto& expected = expectedPoints[i];
7478 const auto& raw = kRawCorners[i];
7479 processDown(mapper, raw.x, raw.y);
7480 processSync(mapper);
7481 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7482 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
7483 WithCoords(expected.x, expected.y), WithPrecision(4, 2))))
7484 << "Failed to process raw point (" << raw.x << ", " << raw.y << ") "
7485 << "with display rotation " << ui::toCString(displayRotation)
7486 << ", expected point (" << expected.x << ", " << expected.y << ").";
7487 processUp(mapper);
7488 processSync(mapper);
7489 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7490 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
7491 WithCoords(expected.x, expected.y))));
7492 }
7493}
7494
Prabir Pradhan46211fb2022-12-17 00:30:39 +00007495TEST_P(TouchscreenPrecisionTestsFixture, MotionRangesAreOrientedInRotatedDisplay) {
7496 const ui::Rotation displayRotation = GetParam();
7497
7498 addConfigurationProperty("touch.deviceType", "touchScreen");
7499 prepareDisplay(displayRotation);
7500
7501 __attribute__((unused)) SingleTouchInputMapper& mapper =
Arpit Singha8c236b2023-04-25 13:56:05 +00007502 constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan46211fb2022-12-17 00:30:39 +00007503
7504 const InputDeviceInfo deviceInfo = mDevice->getDeviceInfo();
7505 // MotionRanges use display pixels as their units
7506 const auto* xRange = deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_X, AINPUT_SOURCE_TOUCHSCREEN);
7507 const auto* yRange = deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_Y, AINPUT_SOURCE_TOUCHSCREEN);
7508
7509 // The MotionRanges should be oriented in the rotated display's coordinate space
7510 const bool displayRotated =
7511 displayRotation == ui::ROTATION_90 || displayRotation == ui::ROTATION_270;
7512
7513 constexpr float MAX_X = 479.5;
7514 constexpr float MAX_Y = 799.75;
7515 EXPECT_EQ(xRange->min, 0.f);
7516 EXPECT_EQ(yRange->min, 0.f);
7517 EXPECT_EQ(xRange->max, displayRotated ? MAX_Y : MAX_X);
7518 EXPECT_EQ(yRange->max, displayRotated ? MAX_X : MAX_Y);
7519
7520 EXPECT_EQ(xRange->flat, 8.f);
7521 EXPECT_EQ(yRange->flat, 8.f);
7522
7523 EXPECT_EQ(xRange->fuzz, 2.f);
7524 EXPECT_EQ(yRange->fuzz, 2.f);
7525
7526 EXPECT_EQ(xRange->resolution, 25.f); // pixels per millimeter
7527 EXPECT_EQ(yRange->resolution, 25.f); // pixels per millimeter
7528}
7529
Prabir Pradhana9df3162022-12-05 23:57:27 +00007530// Run the precision tests for all rotations.
7531INSTANTIATE_TEST_SUITE_P(TouchscreenPrecisionTests, TouchscreenPrecisionTestsFixture,
7532 ::testing::Values(ui::ROTATION_0, ui::ROTATION_90, ui::ROTATION_180,
7533 ui::ROTATION_270),
7534 [](const testing::TestParamInfo<ui::Rotation>& testParamInfo) {
7535 return ftl::enum_string(testParamInfo.param);
7536 });
7537
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007538// --- ExternalStylusFusionTest ---
7539
7540class ExternalStylusFusionTest : public SingleTouchInputMapperTest {
7541public:
7542 SingleTouchInputMapper& initializeInputMapperWithExternalStylus() {
7543 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007544 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007545 prepareButtons();
7546 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00007547 auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007548
7549 mStylusState.when = ARBITRARY_TIME;
7550 mStylusState.pressure = 0.f;
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007551 mStylusState.toolType = ToolType::STYLUS;
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007552 mReader->getContext()->setExternalStylusDevices({mExternalStylusDeviceInfo});
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00007553 configureDevice(InputReaderConfiguration::Change::EXTERNAL_STYLUS_PRESENCE);
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007554 processExternalStylusState(mapper);
7555 return mapper;
7556 }
7557
7558 std::list<NotifyArgs> processExternalStylusState(InputMapper& mapper) {
7559 std::list<NotifyArgs> generatedArgs = mapper.updateExternalStylusState(mStylusState);
7560 for (const NotifyArgs& args : generatedArgs) {
7561 mFakeListener->notify(args);
7562 }
7563 // Loop the reader to flush the input listener queue.
7564 mReader->loopOnce();
7565 return generatedArgs;
7566 }
7567
7568protected:
7569 StylusState mStylusState{};
7570 static constexpr uint32_t EXPECTED_SOURCE =
7571 AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_BLUETOOTH_STYLUS;
7572
7573 void testStartFusedStylusGesture(SingleTouchInputMapper& mapper) {
7574 auto toolTypeSource =
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007575 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::STYLUS));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007576
7577 // The first pointer is withheld.
7578 processDown(mapper, 100, 200);
7579 processSync(mapper);
7580 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7581 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
7582 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
7583
7584 // The external stylus reports pressure. The withheld finger pointer is released as a
7585 // stylus.
7586 mStylusState.pressure = 1.f;
7587 processExternalStylusState(mapper);
7588 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7589 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
7590 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7591
7592 // Subsequent pointer events are not withheld.
7593 processMove(mapper, 101, 201);
7594 processSync(mapper);
7595 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7596 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
7597
7598 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7599 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7600 }
7601
7602 void testSuccessfulFusionGesture(SingleTouchInputMapper& mapper) {
7603 ASSERT_NO_FATAL_FAILURE(testStartFusedStylusGesture(mapper));
7604
7605 // Releasing the touch pointer ends the gesture.
7606 processUp(mapper);
7607 processSync(mapper);
7608 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7609 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(EXPECTED_SOURCE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007610 WithToolType(ToolType::STYLUS))));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007611
7612 mStylusState.pressure = 0.f;
7613 processExternalStylusState(mapper);
7614 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7615 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7616 }
7617
7618 void testUnsuccessfulFusionGesture(SingleTouchInputMapper& mapper) {
7619 auto toolTypeSource =
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007620 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::FINGER));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007621
7622 // The first pointer is withheld when an external stylus is connected,
7623 // and a timeout is requested.
7624 processDown(mapper, 100, 200);
7625 processSync(mapper);
7626 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7627 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
7628 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
7629
7630 // If the timeout expires early, it is requested again.
7631 handleTimeout(mapper, ARBITRARY_TIME + 1);
7632 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
7633 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
7634
7635 // When the timeout expires, the withheld touch is released as a finger pointer.
7636 handleTimeout(mapper, ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT);
7637 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7638 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
7639
7640 // Subsequent pointer events are not withheld.
7641 processMove(mapper, 101, 201);
7642 processSync(mapper);
7643 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7644 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
7645 processUp(mapper);
7646 processSync(mapper);
7647 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7648 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP))));
7649
7650 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7651 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7652 }
7653
7654private:
7655 InputDeviceInfo mExternalStylusDeviceInfo{};
7656};
7657
7658TEST_F(ExternalStylusFusionTest, UsesBluetoothStylusSource) {
7659 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7660 ASSERT_EQ(EXPECTED_SOURCE, mapper.getSources());
7661}
7662
7663TEST_F(ExternalStylusFusionTest, UnsuccessfulFusion) {
7664 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7665 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
7666}
7667
7668TEST_F(ExternalStylusFusionTest, SuccessfulFusion_TouchFirst) {
7669 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7670 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
7671}
7672
7673// Test a successful stylus fusion gesture where the pressure is reported by the external
7674// before the touch is reported by the touchscreen.
7675TEST_F(ExternalStylusFusionTest, SuccessfulFusion_PressureFirst) {
7676 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7677 auto toolTypeSource =
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007678 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::STYLUS));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007679
7680 // The external stylus reports pressure first. It is ignored for now.
7681 mStylusState.pressure = 1.f;
7682 processExternalStylusState(mapper);
7683 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7684 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7685
7686 // When the touch goes down afterwards, it is reported as a stylus pointer.
7687 processDown(mapper, 100, 200);
7688 processSync(mapper);
7689 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7690 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
7691 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7692
7693 processMove(mapper, 101, 201);
7694 processSync(mapper);
7695 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7696 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
7697 processUp(mapper);
7698 processSync(mapper);
7699 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7700 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP))));
7701
7702 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7703 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7704}
7705
7706TEST_F(ExternalStylusFusionTest, FusionIsRepeatedForEachNewGesture) {
7707 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7708
7709 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
7710 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
7711
7712 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
7713 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
7714 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
7715 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
7716}
7717
7718TEST_F(ExternalStylusFusionTest, FusedPointerReportsPressureChanges) {
7719 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7720 auto toolTypeSource =
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007721 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::STYLUS));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007722
7723 mStylusState.pressure = 0.8f;
7724 processExternalStylusState(mapper);
7725 processDown(mapper, 100, 200);
7726 processSync(mapper);
7727 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7728 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
7729 WithPressure(0.8f))));
7730 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7731
7732 // The external stylus reports a pressure change. We wait for some time for a touch event.
7733 mStylusState.pressure = 0.6f;
7734 processExternalStylusState(mapper);
7735 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7736 ASSERT_NO_FATAL_FAILURE(
7737 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7738
7739 // If a touch is reported within the timeout, it reports the updated pressure.
7740 processMove(mapper, 101, 201);
7741 processSync(mapper);
7742 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7743 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7744 WithPressure(0.6f))));
7745 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7746
7747 // There is another pressure change.
7748 mStylusState.pressure = 0.5f;
7749 processExternalStylusState(mapper);
7750 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7751 ASSERT_NO_FATAL_FAILURE(
7752 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7753
7754 // If a touch is not reported within the timeout, a move event is generated to report
7755 // the new pressure.
7756 handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
7757 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7758 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7759 WithPressure(0.5f))));
7760
7761 // If a zero pressure is reported before the touch goes up, the previous pressure value is
7762 // repeated indefinitely.
7763 mStylusState.pressure = 0.0f;
7764 processExternalStylusState(mapper);
7765 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7766 ASSERT_NO_FATAL_FAILURE(
7767 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7768 processMove(mapper, 102, 202);
7769 processSync(mapper);
7770 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7771 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7772 WithPressure(0.5f))));
7773 processMove(mapper, 103, 203);
7774 processSync(mapper);
7775 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7776 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7777 WithPressure(0.5f))));
7778
7779 processUp(mapper);
7780 processSync(mapper);
7781 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7782 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(EXPECTED_SOURCE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007783 WithToolType(ToolType::STYLUS))));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007784
7785 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7786 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7787}
7788
7789TEST_F(ExternalStylusFusionTest, FusedPointerReportsToolTypeChanges) {
7790 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7791 auto source = WithSource(EXPECTED_SOURCE);
7792
7793 mStylusState.pressure = 1.f;
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007794 mStylusState.toolType = ToolType::ERASER;
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007795 processExternalStylusState(mapper);
7796 processDown(mapper, 100, 200);
7797 processSync(mapper);
7798 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7799 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007800 WithToolType(ToolType::ERASER))));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007801 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7802
7803 // The external stylus reports a tool change. We wait for some time for a touch event.
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007804 mStylusState.toolType = ToolType::STYLUS;
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007805 processExternalStylusState(mapper);
7806 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7807 ASSERT_NO_FATAL_FAILURE(
7808 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7809
7810 // If a touch is reported within the timeout, it reports the updated pressure.
7811 processMove(mapper, 101, 201);
7812 processSync(mapper);
7813 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7814 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007815 WithToolType(ToolType::STYLUS))));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007816 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7817
7818 // There is another tool type change.
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007819 mStylusState.toolType = ToolType::FINGER;
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007820 processExternalStylusState(mapper);
7821 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7822 ASSERT_NO_FATAL_FAILURE(
7823 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7824
7825 // If a touch is not reported within the timeout, a move event is generated to report
7826 // the new tool type.
7827 handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
7828 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7829 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007830 WithToolType(ToolType::FINGER))));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007831
7832 processUp(mapper);
7833 processSync(mapper);
7834 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7835 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_UP),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007836 WithToolType(ToolType::FINGER))));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007837
7838 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7839 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7840}
7841
7842TEST_F(ExternalStylusFusionTest, FusedPointerReportsButtons) {
7843 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7844 auto toolTypeSource =
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07007845 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::STYLUS));
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007846
7847 ASSERT_NO_FATAL_FAILURE(testStartFusedStylusGesture(mapper));
7848
7849 // The external stylus reports a button change. We wait for some time for a touch event.
7850 mStylusState.buttons = AMOTION_EVENT_BUTTON_STYLUS_PRIMARY;
7851 processExternalStylusState(mapper);
7852 ASSERT_NO_FATAL_FAILURE(
7853 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7854
7855 // If a touch is reported within the timeout, it reports the updated button state.
7856 processMove(mapper, 101, 201);
7857 processSync(mapper);
7858 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7859 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7860 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
7861 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7862 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
7863 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
7864 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7865
7866 // The button is now released.
7867 mStylusState.buttons = 0;
7868 processExternalStylusState(mapper);
7869 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7870 ASSERT_NO_FATAL_FAILURE(
7871 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7872
7873 // If a touch is not reported within the timeout, a move event is generated to report
7874 // the new button state.
7875 handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007876 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7877 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
7878 WithButtonState(0))));
7879 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan124ea442022-10-28 20:27:44 +00007880 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7881 WithButtonState(0))));
7882
7883 processUp(mapper);
7884 processSync(mapper);
7885 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007886 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
7887
7888 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7889 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7890}
7891
Michael Wrightd02c5b62014-02-10 15:10:22 -08007892// --- MultiTouchInputMapperTest ---
7893
7894class MultiTouchInputMapperTest : public TouchInputMapperTest {
7895protected:
7896 void prepareAxes(int axes);
7897
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007898 void processPosition(MultiTouchInputMapper& mapper, int32_t x, int32_t y);
7899 void processTouchMajor(MultiTouchInputMapper& mapper, int32_t touchMajor);
7900 void processTouchMinor(MultiTouchInputMapper& mapper, int32_t touchMinor);
7901 void processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor);
7902 void processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor);
7903 void processOrientation(MultiTouchInputMapper& mapper, int32_t orientation);
7904 void processPressure(MultiTouchInputMapper& mapper, int32_t pressure);
7905 void processDistance(MultiTouchInputMapper& mapper, int32_t distance);
7906 void processId(MultiTouchInputMapper& mapper, int32_t id);
7907 void processSlot(MultiTouchInputMapper& mapper, int32_t slot);
7908 void processToolType(MultiTouchInputMapper& mapper, int32_t toolType);
7909 void processKey(MultiTouchInputMapper& mapper, int32_t code, int32_t value);
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00007910 void processHidUsage(MultiTouchInputMapper& mapper, int32_t usageCode, int32_t value);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007911 void processMTSync(MultiTouchInputMapper& mapper);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00007912 void processSync(MultiTouchInputMapper& mapper, nsecs_t eventTime = ARBITRARY_TIME,
7913 nsecs_t readTime = READ_TIME);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007914};
7915
7916void MultiTouchInputMapperTest::prepareAxes(int axes) {
7917 if (axes & POSITION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007918 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
7919 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007920 }
7921 if (axes & TOUCH) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007922 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN,
7923 RAW_TOUCH_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007924 if (axes & MINOR) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007925 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN,
7926 RAW_TOUCH_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007927 }
7928 }
7929 if (axes & TOOL) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007930 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
7931 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007932 if (axes & MINOR) {
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08007933 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007934 RAW_TOOL_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007935 }
7936 }
7937 if (axes & ORIENTATION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007938 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_ORIENTATION, RAW_ORIENTATION_MIN,
7939 RAW_ORIENTATION_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007940 }
7941 if (axes & PRESSURE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007942 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_PRESSURE, RAW_PRESSURE_MIN,
7943 RAW_PRESSURE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007944 }
7945 if (axes & DISTANCE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007946 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_DISTANCE, RAW_DISTANCE_MIN,
7947 RAW_DISTANCE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007948 }
7949 if (axes & ID) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007950 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX, 0,
7951 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007952 }
7953 if (axes & SLOT) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007954 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX, 0, 0);
7955 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007956 }
7957 if (axes & TOOL_TYPE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007958 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOOL_TYPE, 0, MT_TOOL_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007959 }
7960}
7961
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007962void MultiTouchInputMapperTest::processPosition(MultiTouchInputMapper& mapper, int32_t x,
7963 int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007964 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_X, x);
7965 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007966}
7967
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007968void MultiTouchInputMapperTest::processTouchMajor(MultiTouchInputMapper& mapper,
7969 int32_t touchMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007970 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, touchMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007971}
7972
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007973void MultiTouchInputMapperTest::processTouchMinor(MultiTouchInputMapper& mapper,
7974 int32_t touchMinor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007975 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, touchMinor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007976}
7977
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007978void MultiTouchInputMapperTest::processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007979 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_WIDTH_MAJOR, toolMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007980}
7981
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007982void MultiTouchInputMapperTest::processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007983 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_WIDTH_MINOR, toolMinor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007984}
7985
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007986void MultiTouchInputMapperTest::processOrientation(MultiTouchInputMapper& mapper,
7987 int32_t orientation) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007988 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_ORIENTATION, orientation);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007989}
7990
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007991void MultiTouchInputMapperTest::processPressure(MultiTouchInputMapper& mapper, int32_t pressure) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007992 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_PRESSURE, pressure);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007993}
7994
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007995void MultiTouchInputMapperTest::processDistance(MultiTouchInputMapper& mapper, int32_t distance) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007996 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_DISTANCE, distance);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007997}
7998
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007999void MultiTouchInputMapperTest::processId(MultiTouchInputMapper& mapper, int32_t id) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008000 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TRACKING_ID, id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008001}
8002
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008003void MultiTouchInputMapperTest::processSlot(MultiTouchInputMapper& mapper, int32_t slot) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008004 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_SLOT, slot);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008005}
8006
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008007void MultiTouchInputMapperTest::processToolType(MultiTouchInputMapper& mapper, int32_t toolType) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008008 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOOL_TYPE, toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008009}
8010
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008011void MultiTouchInputMapperTest::processKey(MultiTouchInputMapper& mapper, int32_t code,
8012 int32_t value) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008013 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008014}
8015
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00008016void MultiTouchInputMapperTest::processHidUsage(MultiTouchInputMapper& mapper, int32_t usageCode,
8017 int32_t value) {
8018 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, usageCode);
8019 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UNKNOWN, value);
8020}
8021
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008022void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008023 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_MT_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008024}
8025
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00008026void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper& mapper, nsecs_t eventTime,
8027 nsecs_t readTime) {
8028 process(mapper, eventTime, readTime, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008029}
8030
Michael Wrightd02c5b62014-02-10 15:10:22 -08008031TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008032 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008033 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008034 prepareAxes(POSITION);
8035 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00008036 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008037
arthurhungdcef2dc2020-08-11 14:47:50 +08008038 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008039
8040 NotifyMotionArgs motionArgs;
8041
8042 // Two fingers down at once.
8043 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
8044 processPosition(mapper, x1, y1);
8045 processMTSync(mapper);
8046 processPosition(mapper, x2, y2);
8047 processMTSync(mapper);
8048 processSync(mapper);
8049
8050 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8051 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8052 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8053 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8054 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
8055 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8056 ASSERT_EQ(0, motionArgs.flags);
8057 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8058 ASSERT_EQ(0, motionArgs.buttonState);
8059 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008060 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008061 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008062 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008063 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8064 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8065 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8066 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8067 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8068
8069 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8070 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8071 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8072 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8073 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008074 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008075 ASSERT_EQ(0, motionArgs.flags);
8076 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8077 ASSERT_EQ(0, motionArgs.buttonState);
8078 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008079 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008080 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008081 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008082 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008083 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008084 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8085 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8086 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8087 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8088 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8089 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8090 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8091
8092 // Move.
8093 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
8094 processPosition(mapper, x1, y1);
8095 processMTSync(mapper);
8096 processPosition(mapper, x2, y2);
8097 processMTSync(mapper);
8098 processSync(mapper);
8099
8100 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8101 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8102 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8103 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8104 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
8105 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8106 ASSERT_EQ(0, motionArgs.flags);
8107 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8108 ASSERT_EQ(0, motionArgs.buttonState);
8109 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008110 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008111 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008112 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008113 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008114 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008115 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8116 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8117 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8118 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8119 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8120 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8121 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8122
8123 // First finger up.
8124 x2 += 15; y2 -= 20;
8125 processPosition(mapper, x2, y2);
8126 processMTSync(mapper);
8127 processSync(mapper);
8128
8129 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8130 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8131 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8132 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8133 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008134 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008135 ASSERT_EQ(0, motionArgs.flags);
8136 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8137 ASSERT_EQ(0, motionArgs.buttonState);
8138 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008139 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008140 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008141 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008142 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008143 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008144 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8145 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8146 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8147 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8148 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8149 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8150 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8151
8152 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8153 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8154 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8155 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8156 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
8157 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8158 ASSERT_EQ(0, motionArgs.flags);
8159 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8160 ASSERT_EQ(0, motionArgs.buttonState);
8161 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008162 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008163 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008164 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008165 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8166 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8167 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8168 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8169 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8170
8171 // Move.
8172 x2 += 20; y2 -= 25;
8173 processPosition(mapper, x2, y2);
8174 processMTSync(mapper);
8175 processSync(mapper);
8176
8177 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8178 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8179 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8180 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8181 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
8182 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8183 ASSERT_EQ(0, motionArgs.flags);
8184 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8185 ASSERT_EQ(0, motionArgs.buttonState);
8186 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008187 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008188 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008189 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008190 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8191 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8192 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8193 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8194 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8195
8196 // New finger down.
8197 int32_t x3 = 700, y3 = 300;
8198 processPosition(mapper, x2, y2);
8199 processMTSync(mapper);
8200 processPosition(mapper, x3, y3);
8201 processMTSync(mapper);
8202 processSync(mapper);
8203
8204 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8205 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8206 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8207 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8208 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008209 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008210 ASSERT_EQ(0, motionArgs.flags);
8211 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8212 ASSERT_EQ(0, motionArgs.buttonState);
8213 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008214 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008215 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008216 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008217 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008218 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008219 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8220 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8221 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8222 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8223 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8224 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8225 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8226
8227 // Second finger up.
8228 x3 += 30; y3 -= 20;
8229 processPosition(mapper, x3, y3);
8230 processMTSync(mapper);
8231 processSync(mapper);
8232
8233 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8234 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8235 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8236 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8237 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008238 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008239 ASSERT_EQ(0, motionArgs.flags);
8240 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8241 ASSERT_EQ(0, motionArgs.buttonState);
8242 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008243 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008244 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008245 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008246 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008247 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008248 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8249 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8250 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8251 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8252 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8253 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8254 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8255
8256 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8257 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8258 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8259 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8260 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
8261 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8262 ASSERT_EQ(0, motionArgs.flags);
8263 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8264 ASSERT_EQ(0, motionArgs.buttonState);
8265 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008266 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008267 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008268 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008269 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8270 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8271 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8272 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8273 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8274
8275 // Last finger up.
8276 processMTSync(mapper);
8277 processSync(mapper);
8278
8279 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8280 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
8281 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
8282 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
8283 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
8284 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8285 ASSERT_EQ(0, motionArgs.flags);
8286 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
8287 ASSERT_EQ(0, motionArgs.buttonState);
8288 ASSERT_EQ(0, motionArgs.edgeFlags);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008289 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008290 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008291 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008292 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8293 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8294 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
8295 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
8296 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
8297
8298 // Should not have sent any more keys or motions.
8299 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
8300 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8301}
8302
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08008303TEST_F(MultiTouchInputMapperTest, AxisResolution_IsPopulated) {
8304 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008305 prepareDisplay(ui::ROTATION_0);
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08008306
8307 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
8308 /*fuzz*/ 0, /*resolution*/ 10);
8309 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
8310 /*fuzz*/ 0, /*resolution*/ 11);
8311 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
8312 /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 12);
8313 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
8314 /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 13);
8315 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
8316 /*flat*/ 0, /*flat*/ 0, /*resolution*/ 14);
8317 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
8318 /*flat*/ 0, /*flat*/ 0, /*resolution*/ 15);
8319
Arpit Singha8c236b2023-04-25 13:56:05 +00008320 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08008321
8322 // X and Y axes
8323 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_X, 10 / X_PRECISION);
8324 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_Y, 11 / Y_PRECISION);
8325 // Touch major and minor
8326 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR, 12 * GEOMETRIC_SCALE);
8327 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR, 13 * GEOMETRIC_SCALE);
8328 // Tool major and minor
8329 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR, 14 * GEOMETRIC_SCALE);
8330 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR, 15 * GEOMETRIC_SCALE);
8331}
8332
8333TEST_F(MultiTouchInputMapperTest, TouchMajorAndMinorAxes_DoNotAppearIfNotSupported) {
8334 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008335 prepareDisplay(ui::ROTATION_0);
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08008336
8337 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
8338 /*fuzz*/ 0, /*resolution*/ 10);
8339 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
8340 /*fuzz*/ 0, /*resolution*/ 11);
8341
8342 // We do not add ABS_MT_TOUCH_MAJOR / MINOR or ABS_MT_WIDTH_MAJOR / MINOR axes
8343
Arpit Singha8c236b2023-04-25 13:56:05 +00008344 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08008345
8346 // Touch major and minor
8347 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR);
8348 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR);
8349 // Tool major and minor
8350 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR);
8351 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR);
8352}
8353
Michael Wrightd02c5b62014-02-10 15:10:22 -08008354TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008355 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008356 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008357 prepareAxes(POSITION | ID);
8358 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00008359 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008360
arthurhungdcef2dc2020-08-11 14:47:50 +08008361 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008362
8363 NotifyMotionArgs motionArgs;
8364
8365 // Two fingers down at once.
8366 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
8367 processPosition(mapper, x1, y1);
8368 processId(mapper, 1);
8369 processMTSync(mapper);
8370 processPosition(mapper, x2, y2);
8371 processId(mapper, 2);
8372 processMTSync(mapper);
8373 processSync(mapper);
8374
8375 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8376 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008377 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008378 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008379 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008380 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8381 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8382
8383 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008384 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008385 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008386 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008387 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008388 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008389 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008390 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8391 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8392 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8393 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8394
8395 // Move.
8396 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
8397 processPosition(mapper, x1, y1);
8398 processId(mapper, 1);
8399 processMTSync(mapper);
8400 processPosition(mapper, x2, y2);
8401 processId(mapper, 2);
8402 processMTSync(mapper);
8403 processSync(mapper);
8404
8405 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8406 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008407 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008408 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008409 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008410 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008411 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008412 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8413 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8414 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8415 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8416
8417 // First finger up.
8418 x2 += 15; y2 -= 20;
8419 processPosition(mapper, x2, y2);
8420 processId(mapper, 2);
8421 processMTSync(mapper);
8422 processSync(mapper);
8423
8424 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008425 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008426 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008427 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008428 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008429 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008430 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008431 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8432 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8433 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8434 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8435
8436 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8437 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008438 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008439 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008440 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008441 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8442 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8443
8444 // Move.
8445 x2 += 20; y2 -= 25;
8446 processPosition(mapper, x2, y2);
8447 processId(mapper, 2);
8448 processMTSync(mapper);
8449 processSync(mapper);
8450
8451 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8452 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008453 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008454 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008455 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008456 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8457 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8458
8459 // New finger down.
8460 int32_t x3 = 700, y3 = 300;
8461 processPosition(mapper, x2, y2);
8462 processId(mapper, 2);
8463 processMTSync(mapper);
8464 processPosition(mapper, x3, y3);
8465 processId(mapper, 3);
8466 processMTSync(mapper);
8467 processSync(mapper);
8468
8469 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008470 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008471 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008472 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008473 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008474 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008475 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008476 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8477 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8478 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8479 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8480
8481 // Second finger up.
8482 x3 += 30; y3 -= 20;
8483 processPosition(mapper, x3, y3);
8484 processId(mapper, 3);
8485 processMTSync(mapper);
8486 processSync(mapper);
8487
8488 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008489 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008490 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008491 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008492 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008493 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008494 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008495 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8496 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8497 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8498 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8499
8500 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8501 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008502 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008503 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008504 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008505 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8506 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8507
8508 // Last finger up.
8509 processMTSync(mapper);
8510 processSync(mapper);
8511
8512 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8513 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008514 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008515 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008516 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008517 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8518 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8519
8520 // Should not have sent any more keys or motions.
8521 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
8522 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8523}
8524
8525TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithSlots) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008526 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008527 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008528 prepareAxes(POSITION | ID | SLOT);
8529 prepareVirtualKeys();
Arpit Singha8c236b2023-04-25 13:56:05 +00008530 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008531
arthurhungdcef2dc2020-08-11 14:47:50 +08008532 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008533
8534 NotifyMotionArgs motionArgs;
8535
8536 // Two fingers down at once.
8537 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
8538 processPosition(mapper, x1, y1);
8539 processId(mapper, 1);
8540 processSlot(mapper, 1);
8541 processPosition(mapper, x2, y2);
8542 processId(mapper, 2);
8543 processSync(mapper);
8544
8545 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8546 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008547 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008548 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008549 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008550 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8551 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8552
8553 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008554 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008555 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008556 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008557 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008558 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008559 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008560 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8561 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8562 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8563 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8564
8565 // Move.
8566 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
8567 processSlot(mapper, 0);
8568 processPosition(mapper, x1, y1);
8569 processSlot(mapper, 1);
8570 processPosition(mapper, x2, y2);
8571 processSync(mapper);
8572
8573 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8574 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008575 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008576 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008577 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008578 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008579 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008580 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8581 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8582 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8583 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8584
8585 // First finger up.
8586 x2 += 15; y2 -= 20;
8587 processSlot(mapper, 0);
8588 processId(mapper, -1);
8589 processSlot(mapper, 1);
8590 processPosition(mapper, x2, y2);
8591 processSync(mapper);
8592
8593 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008594 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008595 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008596 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008597 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008598 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008599 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008600 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8601 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
8602 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8603 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8604
8605 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8606 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008607 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008608 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008609 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008610 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8611 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8612
8613 // Move.
8614 x2 += 20; y2 -= 25;
8615 processPosition(mapper, x2, y2);
8616 processSync(mapper);
8617
8618 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8619 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008620 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008621 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008622 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008623 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8624 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8625
8626 // New finger down.
8627 int32_t x3 = 700, y3 = 300;
8628 processPosition(mapper, x2, y2);
8629 processSlot(mapper, 0);
8630 processId(mapper, 3);
8631 processPosition(mapper, x3, y3);
8632 processSync(mapper);
8633
8634 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008635 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008636 ASSERT_EQ(size_t(2), 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_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008640 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008641 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8642 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8643 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8644 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8645
8646 // Second finger up.
8647 x3 += 30; y3 -= 20;
8648 processSlot(mapper, 1);
8649 processId(mapper, -1);
8650 processSlot(mapper, 0);
8651 processPosition(mapper, x3, y3);
8652 processSync(mapper);
8653
8654 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008655 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008656 ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008657 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008658 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008659 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008660 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008661 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8662 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8663 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
8664 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
8665
8666 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8667 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008668 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008669 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008670 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008671 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8672 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8673
8674 // Last finger up.
8675 processId(mapper, -1);
8676 processSync(mapper);
8677
8678 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8679 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008680 ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008681 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07008682 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008683 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8684 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
8685
8686 // Should not have sent any more keys or motions.
8687 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
8688 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8689}
8690
8691TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008692 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008693 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008694 prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR | DISTANCE);
Arpit Singha8c236b2023-04-25 13:56:05 +00008695 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008696
8697 // These calculations are based on the input device calibration documentation.
8698 int32_t rawX = 100;
8699 int32_t rawY = 200;
8700 int32_t rawTouchMajor = 7;
8701 int32_t rawTouchMinor = 6;
8702 int32_t rawToolMajor = 9;
8703 int32_t rawToolMinor = 8;
8704 int32_t rawPressure = 11;
8705 int32_t rawDistance = 0;
8706 int32_t rawOrientation = 3;
8707 int32_t id = 5;
8708
8709 float x = toDisplayX(rawX);
8710 float y = toDisplayY(rawY);
8711 float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
8712 float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
8713 float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
8714 float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
8715 float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
8716 float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
8717 float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2;
8718 float distance = float(rawDistance);
8719
8720 processPosition(mapper, rawX, rawY);
8721 processTouchMajor(mapper, rawTouchMajor);
8722 processTouchMinor(mapper, rawTouchMinor);
8723 processToolMajor(mapper, rawToolMajor);
8724 processToolMinor(mapper, rawToolMinor);
8725 processPressure(mapper, rawPressure);
8726 processOrientation(mapper, rawOrientation);
8727 processDistance(mapper, rawDistance);
8728 processId(mapper, id);
8729 processMTSync(mapper);
8730 processSync(mapper);
8731
8732 NotifyMotionArgs args;
8733 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8734 ASSERT_EQ(0, args.pointerProperties[0].id);
8735 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8736 x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor,
8737 orientation, distance));
8738}
8739
8740TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008741 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008742 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008743 prepareAxes(POSITION | TOUCH | TOOL | MINOR);
8744 addConfigurationProperty("touch.size.calibration", "geometric");
Arpit Singha8c236b2023-04-25 13:56:05 +00008745 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008746
8747 // These calculations are based on the input device calibration documentation.
8748 int32_t rawX = 100;
8749 int32_t rawY = 200;
8750 int32_t rawTouchMajor = 140;
8751 int32_t rawTouchMinor = 120;
8752 int32_t rawToolMajor = 180;
8753 int32_t rawToolMinor = 160;
8754
8755 float x = toDisplayX(rawX);
8756 float y = toDisplayY(rawY);
8757 float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
8758 float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
8759 float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
8760 float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
8761 float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
8762
8763 processPosition(mapper, rawX, rawY);
8764 processTouchMajor(mapper, rawTouchMajor);
8765 processTouchMinor(mapper, rawTouchMinor);
8766 processToolMajor(mapper, rawToolMajor);
8767 processToolMinor(mapper, rawToolMinor);
8768 processMTSync(mapper);
8769 processSync(mapper);
8770
8771 NotifyMotionArgs args;
8772 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8773 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8774 x, y, 1.0f, size, touchMajor, touchMinor, toolMajor, toolMinor, 0, 0));
8775}
8776
8777TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_SummedLinearCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008778 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008779 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008780 prepareAxes(POSITION | TOUCH | TOOL);
8781 addConfigurationProperty("touch.size.calibration", "diameter");
8782 addConfigurationProperty("touch.size.scale", "10");
8783 addConfigurationProperty("touch.size.bias", "160");
8784 addConfigurationProperty("touch.size.isSummed", "1");
Arpit Singha8c236b2023-04-25 13:56:05 +00008785 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008786
8787 // These calculations are based on the input device calibration documentation.
8788 // Note: We only provide a single common touch/tool value because the device is assumed
8789 // not to emit separate values for each pointer (isSummed = 1).
8790 int32_t rawX = 100;
8791 int32_t rawY = 200;
8792 int32_t rawX2 = 150;
8793 int32_t rawY2 = 250;
8794 int32_t rawTouchMajor = 5;
8795 int32_t rawToolMajor = 8;
8796
8797 float x = toDisplayX(rawX);
8798 float y = toDisplayY(rawY);
8799 float x2 = toDisplayX(rawX2);
8800 float y2 = toDisplayY(rawY2);
8801 float size = float(rawTouchMajor) / 2 / RAW_TOUCH_MAX;
8802 float touch = float(rawTouchMajor) / 2 * 10.0f + 160.0f;
8803 float tool = float(rawToolMajor) / 2 * 10.0f + 160.0f;
8804
8805 processPosition(mapper, rawX, rawY);
8806 processTouchMajor(mapper, rawTouchMajor);
8807 processToolMajor(mapper, rawToolMajor);
8808 processMTSync(mapper);
8809 processPosition(mapper, rawX2, rawY2);
8810 processTouchMajor(mapper, rawTouchMajor);
8811 processToolMajor(mapper, rawToolMajor);
8812 processMTSync(mapper);
8813 processSync(mapper);
8814
8815 NotifyMotionArgs args;
8816 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8817 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
8818
8819 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008820 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07008821 ASSERT_EQ(size_t(2), args.getPointerCount());
Michael Wrightd02c5b62014-02-10 15:10:22 -08008822 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8823 x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
8824 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1],
8825 x2, y2, 1.0f, size, touch, touch, tool, tool, 0, 0));
8826}
8827
8828TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_AreaCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008829 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008830 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008831 prepareAxes(POSITION | TOUCH | TOOL);
8832 addConfigurationProperty("touch.size.calibration", "area");
8833 addConfigurationProperty("touch.size.scale", "43");
8834 addConfigurationProperty("touch.size.bias", "3");
Arpit Singha8c236b2023-04-25 13:56:05 +00008835 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008836
8837 // These calculations are based on the input device calibration documentation.
8838 int32_t rawX = 100;
8839 int32_t rawY = 200;
8840 int32_t rawTouchMajor = 5;
8841 int32_t rawToolMajor = 8;
8842
8843 float x = toDisplayX(rawX);
8844 float y = toDisplayY(rawY);
8845 float size = float(rawTouchMajor) / RAW_TOUCH_MAX;
8846 float touch = sqrtf(rawTouchMajor) * 43.0f + 3.0f;
8847 float tool = sqrtf(rawToolMajor) * 43.0f + 3.0f;
8848
8849 processPosition(mapper, rawX, rawY);
8850 processTouchMajor(mapper, rawTouchMajor);
8851 processToolMajor(mapper, rawToolMajor);
8852 processMTSync(mapper);
8853 processSync(mapper);
8854
8855 NotifyMotionArgs args;
8856 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8857 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8858 x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
8859}
8860
8861TEST_F(MultiTouchInputMapperTest, Process_PressureAxis_AmplitudeCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008862 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008863 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008864 prepareAxes(POSITION | PRESSURE);
8865 addConfigurationProperty("touch.pressure.calibration", "amplitude");
8866 addConfigurationProperty("touch.pressure.scale", "0.01");
Arpit Singha8c236b2023-04-25 13:56:05 +00008867 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008868
Michael Wrightaa449c92017-12-13 21:21:43 +00008869 InputDeviceInfo info;
Harry Cuttsd02ea102023-03-17 18:21:30 +00008870 mapper.populateDeviceInfo(info);
Michael Wrightaa449c92017-12-13 21:21:43 +00008871 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
8872 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TOUCHSCREEN,
8873 0.0f, RAW_PRESSURE_MAX * 0.01, 0.0f, 0.0f));
8874
Michael Wrightd02c5b62014-02-10 15:10:22 -08008875 // These calculations are based on the input device calibration documentation.
8876 int32_t rawX = 100;
8877 int32_t rawY = 200;
8878 int32_t rawPressure = 60;
8879
8880 float x = toDisplayX(rawX);
8881 float y = toDisplayY(rawY);
8882 float pressure = float(rawPressure) * 0.01f;
8883
8884 processPosition(mapper, rawX, rawY);
8885 processPressure(mapper, rawPressure);
8886 processMTSync(mapper);
8887 processSync(mapper);
8888
8889 NotifyMotionArgs args;
8890 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8891 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8892 x, y, pressure, 0, 0, 0, 0, 0, 0, 0));
8893}
8894
8895TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008896 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008897 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008898 prepareAxes(POSITION | ID | SLOT);
Arpit Singha8c236b2023-04-25 13:56:05 +00008899 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008900
8901 NotifyMotionArgs motionArgs;
8902 NotifyKeyArgs keyArgs;
8903
8904 processId(mapper, 1);
8905 processPosition(mapper, 100, 200);
8906 processSync(mapper);
8907 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8908 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8909 ASSERT_EQ(0, motionArgs.buttonState);
8910
8911 // press BTN_LEFT, release BTN_LEFT
8912 processKey(mapper, BTN_LEFT, 1);
8913 processSync(mapper);
8914 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8915 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8916 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
8917
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008918 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8919 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8920 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
8921
Michael Wrightd02c5b62014-02-10 15:10:22 -08008922 processKey(mapper, BTN_LEFT, 0);
8923 processSync(mapper);
8924 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008925 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008926 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008927
8928 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008929 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008930 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008931
8932 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
8933 processKey(mapper, BTN_RIGHT, 1);
8934 processKey(mapper, BTN_MIDDLE, 1);
8935 processSync(mapper);
8936 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8937 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8938 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
8939 motionArgs.buttonState);
8940
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008941 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8942 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8943 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
8944
8945 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8946 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8947 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
8948 motionArgs.buttonState);
8949
Michael Wrightd02c5b62014-02-10 15:10:22 -08008950 processKey(mapper, BTN_RIGHT, 0);
8951 processSync(mapper);
8952 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008953 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008954 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008955
8956 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008957 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008958 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008959
8960 processKey(mapper, BTN_MIDDLE, 0);
8961 processSync(mapper);
8962 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008963 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008964 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008965
8966 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008967 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008968 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008969
8970 // press BTN_BACK, release BTN_BACK
8971 processKey(mapper, BTN_BACK, 1);
8972 processSync(mapper);
8973 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8974 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
8975 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008976
Michael Wrightd02c5b62014-02-10 15:10:22 -08008977 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008978 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008979 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
8980
8981 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8982 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8983 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008984
8985 processKey(mapper, BTN_BACK, 0);
8986 processSync(mapper);
8987 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008988 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008989 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008990
8991 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008992 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008993 ASSERT_EQ(0, motionArgs.buttonState);
8994
Michael Wrightd02c5b62014-02-10 15:10:22 -08008995 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8996 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
8997 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
8998
8999 // press BTN_SIDE, release BTN_SIDE
9000 processKey(mapper, BTN_SIDE, 1);
9001 processSync(mapper);
9002 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
9003 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
9004 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009005
Michael Wrightd02c5b62014-02-10 15:10:22 -08009006 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009007 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009008 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
9009
9010 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9011 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
9012 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009013
9014 processKey(mapper, BTN_SIDE, 0);
9015 processSync(mapper);
9016 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009017 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009018 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009019
9020 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009021 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009022 ASSERT_EQ(0, motionArgs.buttonState);
9023
Michael Wrightd02c5b62014-02-10 15:10:22 -08009024 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
9025 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
9026 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
9027
9028 // press BTN_FORWARD, release BTN_FORWARD
9029 processKey(mapper, BTN_FORWARD, 1);
9030 processSync(mapper);
9031 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
9032 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
9033 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009034
Michael Wrightd02c5b62014-02-10 15:10:22 -08009035 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009036 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009037 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
9038
9039 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9040 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
9041 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009042
9043 processKey(mapper, BTN_FORWARD, 0);
9044 processSync(mapper);
9045 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009046 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009047 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009048
9049 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009050 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009051 ASSERT_EQ(0, motionArgs.buttonState);
9052
Michael Wrightd02c5b62014-02-10 15:10:22 -08009053 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
9054 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
9055 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
9056
9057 // press BTN_EXTRA, release BTN_EXTRA
9058 processKey(mapper, BTN_EXTRA, 1);
9059 processSync(mapper);
9060 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
9061 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
9062 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009063
Michael Wrightd02c5b62014-02-10 15:10:22 -08009064 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009065 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009066 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
9067
9068 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9069 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
9070 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009071
9072 processKey(mapper, BTN_EXTRA, 0);
9073 processSync(mapper);
9074 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009075 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009076 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009077
9078 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009079 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009080 ASSERT_EQ(0, motionArgs.buttonState);
9081
Michael Wrightd02c5b62014-02-10 15:10:22 -08009082 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
9083 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
9084 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
9085
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009086 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
9087
Michael Wrightd02c5b62014-02-10 15:10:22 -08009088 // press BTN_STYLUS, release BTN_STYLUS
9089 processKey(mapper, BTN_STYLUS, 1);
9090 processSync(mapper);
9091 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9092 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009093 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
9094
9095 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9096 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
9097 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009098
9099 processKey(mapper, BTN_STYLUS, 0);
9100 processSync(mapper);
9101 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009102 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009103 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009104
9105 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009106 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009107 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009108
9109 // press BTN_STYLUS2, release BTN_STYLUS2
9110 processKey(mapper, BTN_STYLUS2, 1);
9111 processSync(mapper);
9112 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9113 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009114 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
9115
9116 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9117 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
9118 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009119
9120 processKey(mapper, BTN_STYLUS2, 0);
9121 processSync(mapper);
9122 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009123 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009124 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009125
9126 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08009127 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08009128 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009129
9130 // release touch
9131 processId(mapper, -1);
9132 processSync(mapper);
9133 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9134 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9135 ASSERT_EQ(0, motionArgs.buttonState);
9136}
9137
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00009138TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleMappedStylusButtons) {
9139 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009140 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00009141 prepareAxes(POSITION | ID | SLOT);
Arpit Singha8c236b2023-04-25 13:56:05 +00009142 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00009143
9144 mFakeEventHub->addKey(EVENTHUB_ID, BTN_A, 0, AKEYCODE_STYLUS_BUTTON_PRIMARY, 0);
9145 mFakeEventHub->addKey(EVENTHUB_ID, 0, 0xabcd, AKEYCODE_STYLUS_BUTTON_SECONDARY, 0);
9146
9147 // Touch down.
9148 processId(mapper, 1);
9149 processPosition(mapper, 100, 200);
9150 processSync(mapper);
9151 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9152 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithButtonState(0))));
9153
9154 // Press and release button mapped to the primary stylus button.
9155 processKey(mapper, BTN_A, 1);
9156 processSync(mapper);
9157 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9158 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
9159 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
9160 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9161 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
9162 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
9163
9164 processKey(mapper, BTN_A, 0);
9165 processSync(mapper);
9166 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9167 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithButtonState(0))));
9168 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9169 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
9170
9171 // Press and release the HID usage mapped to the secondary stylus button.
9172 processHidUsage(mapper, 0xabcd, 1);
9173 processSync(mapper);
9174 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9175 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
9176 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY))));
9177 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9178 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
9179 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY))));
9180
9181 processHidUsage(mapper, 0xabcd, 0);
9182 processSync(mapper);
9183 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9184 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithButtonState(0))));
9185 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9186 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
9187
9188 // Release touch.
9189 processId(mapper, -1);
9190 processSync(mapper);
9191 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9192 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
9193}
9194
Michael Wrightd02c5b62014-02-10 15:10:22 -08009195TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08009196 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009197 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009198 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Arpit Singha8c236b2023-04-25 13:56:05 +00009199 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08009200
9201 NotifyMotionArgs motionArgs;
9202
9203 // default tool type is finger
9204 processId(mapper, 1);
9205 processPosition(mapper, 100, 200);
9206 processSync(mapper);
9207 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9208 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009209 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009210
9211 // eraser
9212 processKey(mapper, BTN_TOOL_RUBBER, 1);
9213 processSync(mapper);
9214 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9215 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009216 ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009217
9218 // stylus
9219 processKey(mapper, BTN_TOOL_RUBBER, 0);
9220 processKey(mapper, BTN_TOOL_PEN, 1);
9221 processSync(mapper);
9222 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9223 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009224 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009225
9226 // brush
9227 processKey(mapper, BTN_TOOL_PEN, 0);
9228 processKey(mapper, BTN_TOOL_BRUSH, 1);
9229 processSync(mapper);
9230 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9231 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009232 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009233
9234 // pencil
9235 processKey(mapper, BTN_TOOL_BRUSH, 0);
9236 processKey(mapper, BTN_TOOL_PENCIL, 1);
9237 processSync(mapper);
9238 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9239 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009240 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009241
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08009242 // air-brush
Michael Wrightd02c5b62014-02-10 15:10:22 -08009243 processKey(mapper, BTN_TOOL_PENCIL, 0);
9244 processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
9245 processSync(mapper);
9246 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9247 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009248 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009249
9250 // mouse
9251 processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
9252 processKey(mapper, BTN_TOOL_MOUSE, 1);
9253 processSync(mapper);
9254 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9255 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009256 ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009257
9258 // lens
9259 processKey(mapper, BTN_TOOL_MOUSE, 0);
9260 processKey(mapper, BTN_TOOL_LENS, 1);
9261 processSync(mapper);
9262 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9263 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009264 ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009265
9266 // double-tap
9267 processKey(mapper, BTN_TOOL_LENS, 0);
9268 processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
9269 processSync(mapper);
9270 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9271 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009272 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009273
9274 // triple-tap
9275 processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
9276 processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
9277 processSync(mapper);
9278 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9279 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009280 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009281
9282 // quad-tap
9283 processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
9284 processKey(mapper, BTN_TOOL_QUADTAP, 1);
9285 processSync(mapper);
9286 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9287 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009288 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009289
9290 // finger
9291 processKey(mapper, BTN_TOOL_QUADTAP, 0);
9292 processKey(mapper, BTN_TOOL_FINGER, 1);
9293 processSync(mapper);
9294 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9295 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009296 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009297
9298 // stylus trumps finger
9299 processKey(mapper, BTN_TOOL_PEN, 1);
9300 processSync(mapper);
9301 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9302 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009303 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009304
9305 // eraser trumps stylus
9306 processKey(mapper, BTN_TOOL_RUBBER, 1);
9307 processSync(mapper);
9308 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9309 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009310 ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009311
9312 // mouse trumps eraser
9313 processKey(mapper, BTN_TOOL_MOUSE, 1);
9314 processSync(mapper);
9315 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9316 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009317 ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009318
9319 // MT tool type trumps BTN tool types: MT_TOOL_FINGER
9320 processToolType(mapper, MT_TOOL_FINGER); // this is the first time we send MT_TOOL_TYPE
9321 processSync(mapper);
9322 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9323 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009324 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009325
9326 // MT tool type trumps BTN tool types: MT_TOOL_PEN
9327 processToolType(mapper, MT_TOOL_PEN);
9328 processSync(mapper);
9329 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9330 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009331 ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009332
9333 // back to default tool type
9334 processToolType(mapper, -1); // use a deliberately undefined tool type, for testing
9335 processKey(mapper, BTN_TOOL_MOUSE, 0);
9336 processKey(mapper, BTN_TOOL_RUBBER, 0);
9337 processKey(mapper, BTN_TOOL_PEN, 0);
9338 processKey(mapper, BTN_TOOL_FINGER, 0);
9339 processSync(mapper);
9340 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9341 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07009342 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009343}
9344
9345TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08009346 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009347 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009348 prepareAxes(POSITION | ID | SLOT);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009349 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Arpit Singha8c236b2023-04-25 13:56:05 +00009350 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08009351
9352 NotifyMotionArgs motionArgs;
9353
9354 // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
9355 processId(mapper, 1);
9356 processPosition(mapper, 100, 200);
9357 processSync(mapper);
9358 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9359 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
9360 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9361 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
9362
9363 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9364 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
9365 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9366 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
9367
9368 // move a little
9369 processPosition(mapper, 150, 250);
9370 processSync(mapper);
9371 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9372 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
9373 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9374 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9375
9376 // down when BTN_TOUCH is pressed, pressure defaults to 1
9377 processKey(mapper, BTN_TOUCH, 1);
9378 processSync(mapper);
9379 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9380 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
9381 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9382 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9383
9384 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9385 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9386 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9387 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
9388
9389 // up when BTN_TOUCH is released, hover restored
9390 processKey(mapper, BTN_TOUCH, 0);
9391 processSync(mapper);
9392 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9393 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9394 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9395 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
9396
9397 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9398 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
9399 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9400 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9401
9402 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9403 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
9404 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9405 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9406
9407 // exit hover when pointer goes away
9408 processId(mapper, -1);
9409 processSync(mapper);
9410 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9411 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
9412 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9413 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9414}
9415
9416TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTPressureIsPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08009417 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009418 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08009419 prepareAxes(POSITION | ID | SLOT | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +00009420 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08009421
9422 NotifyMotionArgs motionArgs;
9423
9424 // initially hovering because pressure is 0
9425 processId(mapper, 1);
9426 processPosition(mapper, 100, 200);
9427 processPressure(mapper, 0);
9428 processSync(mapper);
9429 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9430 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
9431 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9432 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
9433
9434 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9435 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
9436 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9437 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
9438
9439 // move a little
9440 processPosition(mapper, 150, 250);
9441 processSync(mapper);
9442 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9443 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
9444 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9445 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9446
9447 // down when pressure becomes non-zero
9448 processPressure(mapper, RAW_PRESSURE_MAX);
9449 processSync(mapper);
9450 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9451 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
9452 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9453 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9454
9455 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9456 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9457 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9458 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
9459
9460 // up when pressure becomes 0, hover restored
9461 processPressure(mapper, 0);
9462 processSync(mapper);
9463 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9464 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9465 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9466 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
9467
9468 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9469 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
9470 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9471 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9472
9473 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9474 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
9475 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9476 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9477
9478 // exit hover when pointer goes away
9479 processId(mapper, -1);
9480 processSync(mapper);
9481 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9482 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
9483 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
9484 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
9485}
9486
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07009487/**
9488 * Set the input device port <--> display port associations, and check that the
9489 * events are routed to the display that matches the display port.
9490 * This can be checked by looking at the displayId of the resulting NotifyMotionArgs.
9491 */
9492TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayPort) {
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07009493 const std::string usb2 = "USB2";
9494 const uint8_t hdmi1 = 0;
9495 const uint8_t hdmi2 = 1;
9496 const std::string secondaryUniqueId = "uniqueId2";
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009497 constexpr ViewportType type = ViewportType::EXTERNAL;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07009498
9499 addConfigurationProperty("touch.deviceType", "touchScreen");
9500 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00009501 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07009502
9503 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
9504 mFakePolicy->addInputPortAssociation(usb2, hdmi2);
9505
9506 // We are intentionally not adding the viewport for display 1 yet. Since the port association
9507 // for this input device is specified, and the matching viewport is not present,
9508 // the input device should be disabled (at the mapper level).
9509
9510 // Add viewport for display 2 on hdmi2
9511 prepareSecondaryDisplay(type, hdmi2);
9512 // Send a touch event
9513 processPosition(mapper, 100, 100);
9514 processSync(mapper);
9515 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9516
9517 // Add viewport for display 1 on hdmi1
Michael Wrighta9cf4192022-12-01 23:46:39 +00009518 prepareDisplay(ui::ROTATION_0, hdmi1);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07009519 // Send a touch event again
9520 processPosition(mapper, 100, 100);
9521 processSync(mapper);
9522
9523 NotifyMotionArgs args;
9524 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9525 ASSERT_EQ(DISPLAY_ID, args.displayId);
9526}
Michael Wrightd02c5b62014-02-10 15:10:22 -08009527
Arthur Hung6d5b4b22022-01-21 07:21:10 +00009528TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayUniqueId) {
9529 addConfigurationProperty("touch.deviceType", "touchScreen");
9530 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00009531 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Arthur Hung6d5b4b22022-01-21 07:21:10 +00009532
9533 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
9534
Michael Wrighta9cf4192022-12-01 23:46:39 +00009535 prepareDisplay(ui::ROTATION_0);
9536 prepareVirtualDisplay(ui::ROTATION_0);
Arthur Hung6d5b4b22022-01-21 07:21:10 +00009537
9538 // Send a touch event
9539 processPosition(mapper, 100, 100);
9540 processSync(mapper);
9541
9542 NotifyMotionArgs args;
9543 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9544 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
9545}
9546
Arthur Hungc7ad2d02018-12-18 17:41:29 +08009547TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
Garfield Tan888a6a42020-01-09 11:39:16 -08009548 // Setup for second display.
Michael Wright17db18e2020-06-26 20:51:44 +01009549 std::shared_ptr<FakePointerController> fakePointerController =
9550 std::make_shared<FakePointerController>();
Garfield Tan888a6a42020-01-09 11:39:16 -08009551 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08009552 fakePointerController->setPosition(100, 200);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009553 mFakePolicy->setPointerController(fakePointerController);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08009554
Garfield Tan888a6a42020-01-09 11:39:16 -08009555 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009556 prepareSecondaryDisplay(ViewportType::EXTERNAL);
Garfield Tan888a6a42020-01-09 11:39:16 -08009557
Michael Wrighta9cf4192022-12-01 23:46:39 +00009558 prepareDisplay(ui::ROTATION_0);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08009559 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00009560 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Arthur Hungc7ad2d02018-12-18 17:41:29 +08009561
Josep del Río2d8c79a2023-01-23 19:33:50 +00009562 // Check source is mouse that would obtain the PointerController.
9563 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Arthur Hungc7ad2d02018-12-18 17:41:29 +08009564
9565 NotifyMotionArgs motionArgs;
9566 processPosition(mapper, 100, 100);
9567 processSync(mapper);
9568
9569 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9570 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
9571 ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
9572}
9573
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00009574/**
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00009575 * Ensure that the readTime is set to the SYN_REPORT value when processing touch events.
9576 */
9577TEST_F(MultiTouchInputMapperTest, Process_SendsReadTime) {
9578 addConfigurationProperty("touch.deviceType", "touchScreen");
9579 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00009580 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00009581
Michael Wrighta9cf4192022-12-01 23:46:39 +00009582 prepareDisplay(ui::ROTATION_0);
Harry Cutts33476232023-01-30 19:57:29 +00009583 process(mapper, 10, /*readTime=*/11, EV_ABS, ABS_MT_TRACKING_ID, 1);
9584 process(mapper, 15, /*readTime=*/16, EV_ABS, ABS_MT_POSITION_X, 100);
9585 process(mapper, 20, /*readTime=*/21, EV_ABS, ABS_MT_POSITION_Y, 100);
9586 process(mapper, 25, /*readTime=*/26, EV_SYN, SYN_REPORT, 0);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00009587
9588 NotifyMotionArgs args;
9589 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9590 ASSERT_EQ(26, args.readTime);
9591
Harry Cutts33476232023-01-30 19:57:29 +00009592 process(mapper, 30, /*readTime=*/31, EV_ABS, ABS_MT_POSITION_X, 110);
9593 process(mapper, 30, /*readTime=*/32, EV_ABS, ABS_MT_POSITION_Y, 220);
9594 process(mapper, 30, /*readTime=*/33, EV_SYN, SYN_REPORT, 0);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00009595
9596 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9597 ASSERT_EQ(33, args.readTime);
9598}
9599
9600/**
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00009601 * When the viewport is not active (isActive=false), the touch mapper should be disabled and the
9602 * events should not be delivered to the listener.
9603 */
9604TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreDropped) {
9605 addConfigurationProperty("touch.deviceType", "touchScreen");
Yuncheol Heo50c19b12022-11-02 20:33:08 -07009606 // Don't set touch.enableForInactiveViewport to verify the default behavior.
Michael Wrighta9cf4192022-12-01 23:46:39 +00009607 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +00009608 /*isActive=*/false, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00009609 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00009610 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00009611 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00009612
9613 NotifyMotionArgs motionArgs;
9614 processPosition(mapper, 100, 100);
9615 processSync(mapper);
9616
9617 mFakeListener->assertNotifyMotionWasNotCalled();
9618}
9619
Yuncheol Heo50c19b12022-11-02 20:33:08 -07009620/**
9621 * When the viewport is not active (isActive=false) and touch.enableForInactiveViewport is true,
9622 * the touch mapper can process the events and the events can be delivered to the listener.
9623 */
9624TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreProcessed) {
9625 addConfigurationProperty("touch.deviceType", "touchScreen");
9626 addConfigurationProperty("touch.enableForInactiveViewport", "1");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009627 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +00009628 /*isActive=*/false, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00009629 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Yuncheol Heo50c19b12022-11-02 20:33:08 -07009630 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00009631 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Yuncheol Heo50c19b12022-11-02 20:33:08 -07009632
9633 NotifyMotionArgs motionArgs;
9634 processPosition(mapper, 100, 100);
9635 processSync(mapper);
9636
9637 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9638 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9639}
9640
Josh Thielene986aed2023-06-01 14:17:30 +00009641/**
9642 * When the viewport is deactivated (isActive transitions from true to false),
9643 * and touch.enableForInactiveViewport is false, touches prior to the transition
9644 * should be cancelled.
9645 */
Garfield Tanc734e4f2021-01-15 20:01:39 -08009646TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_AbortTouches) {
9647 addConfigurationProperty("touch.deviceType", "touchScreen");
Yuncheol Heo50c19b12022-11-02 20:33:08 -07009648 addConfigurationProperty("touch.enableForInactiveViewport", "0");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009649 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Harry Cutts33476232023-01-30 19:57:29 +00009650 /*isActive=*/true, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Garfield Tanc734e4f2021-01-15 20:01:39 -08009651 std::optional<DisplayViewport> optionalDisplayViewport =
9652 mFakePolicy->getDisplayViewportByUniqueId(UNIQUE_ID);
9653 ASSERT_TRUE(optionalDisplayViewport.has_value());
9654 DisplayViewport displayViewport = *optionalDisplayViewport;
9655
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00009656 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Garfield Tanc734e4f2021-01-15 20:01:39 -08009657 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00009658 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Garfield Tanc734e4f2021-01-15 20:01:39 -08009659
9660 // Finger down
9661 int32_t x = 100, y = 100;
9662 processPosition(mapper, x, y);
9663 processSync(mapper);
9664
9665 NotifyMotionArgs motionArgs;
9666 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9667 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9668
9669 // Deactivate display viewport
9670 displayViewport.isActive = false;
9671 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00009672 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Garfield Tanc734e4f2021-01-15 20:01:39 -08009673
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00009674 // The ongoing touch should be canceled immediately
9675 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9676 EXPECT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
9677
9678 // Finger move is ignored
Garfield Tanc734e4f2021-01-15 20:01:39 -08009679 x += 10, y += 10;
9680 processPosition(mapper, x, y);
9681 processSync(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00009682 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
Garfield Tanc734e4f2021-01-15 20:01:39 -08009683
9684 // Reactivate display viewport
9685 displayViewport.isActive = true;
9686 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00009687 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Garfield Tanc734e4f2021-01-15 20:01:39 -08009688
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00009689 // Finger move again starts new gesture
Garfield Tanc734e4f2021-01-15 20:01:39 -08009690 x += 10, y += 10;
9691 processPosition(mapper, x, y);
9692 processSync(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00009693 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9694 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Garfield Tanc734e4f2021-01-15 20:01:39 -08009695}
9696
Josh Thielene986aed2023-06-01 14:17:30 +00009697/**
9698 * When the viewport is deactivated (isActive transitions from true to false),
9699 * and touch.enableForInactiveViewport is true, touches prior to the transition
9700 * should not be cancelled.
9701 */
9702TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_TouchesNotAborted) {
9703 addConfigurationProperty("touch.deviceType", "touchScreen");
9704 addConfigurationProperty("touch.enableForInactiveViewport", "1");
9705 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
9706 /*isActive=*/true, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
9707 std::optional<DisplayViewport> optionalDisplayViewport =
9708 mFakePolicy->getDisplayViewportByUniqueId(UNIQUE_ID);
9709 ASSERT_TRUE(optionalDisplayViewport.has_value());
9710 DisplayViewport displayViewport = *optionalDisplayViewport;
9711
9712 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
9713 prepareAxes(POSITION);
9714 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
9715
9716 // Finger down
9717 int32_t x = 100, y = 100;
9718 processPosition(mapper, x, y);
9719 processSync(mapper);
9720 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9721 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
9722
9723 // Deactivate display viewport
9724 displayViewport.isActive = false;
9725 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
9726 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
9727
9728 // The ongoing touch should not be canceled
9729 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9730
9731 // Finger move is not ignored
9732 x += 10, y += 10;
9733 processPosition(mapper, x, y);
9734 processSync(mapper);
9735 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9736 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
9737
9738 // Reactivate display viewport
9739 displayViewport.isActive = true;
9740 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
9741 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
9742
9743 // Finger move continues and does not start new gesture
9744 x += 10, y += 10;
9745 processPosition(mapper, x, y);
9746 processSync(mapper);
9747 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9748 WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
9749}
9750
Arthur Hung7c645402019-01-25 17:45:42 +08009751TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) {
9752 // Setup the first touch screen device.
Arthur Hung7c645402019-01-25 17:45:42 +08009753 prepareAxes(POSITION | ID | SLOT);
9754 addConfigurationProperty("touch.deviceType", "touchScreen");
Arpit Singha8c236b2023-04-25 13:56:05 +00009755 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Arthur Hung7c645402019-01-25 17:45:42 +08009756
9757 // Create the second touch screen device, and enable multi fingers.
9758 const std::string USB2 = "USB2";
arthurhungdcef2dc2020-08-11 14:47:50 +08009759 const std::string DEVICE_NAME2 = "TOUCHSCREEN2";
Arthur Hung2c9a3342019-07-23 14:18:59 +08009760 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009761 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
arthurhungdcef2dc2020-08-11 14:47:50 +08009762 std::shared_ptr<InputDevice> device2 =
9763 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07009764 ftl::Flags<InputDeviceClass>(0));
arthurhungdcef2dc2020-08-11 14:47:50 +08009765
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009766 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
Harry Cutts33476232023-01-30 19:57:29 +00009767 /*flat=*/0, /*fuzz=*/0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009768 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
Harry Cutts33476232023-01-30 19:57:29 +00009769 /*flat=*/0, /*fuzz=*/0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009770 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX,
Harry Cutts33476232023-01-30 19:57:29 +00009771 /*flat=*/0, /*fuzz=*/0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009772 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX,
Harry Cutts33476232023-01-30 19:57:29 +00009773 /*flat=*/0, /*fuzz=*/0);
9774 mFakeEventHub->setAbsoluteAxisValue(SECOND_EVENTHUB_ID, ABS_MT_SLOT, /*value=*/0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009775 mFakeEventHub->addConfigurationProperty(SECOND_EVENTHUB_ID, String8("touch.deviceType"),
9776 String8("touchScreen"));
Arthur Hung7c645402019-01-25 17:45:42 +08009777
9778 // Setup the second touch screen device.
Arpit Singha8c236b2023-04-25 13:56:05 +00009779 device2->addEmptyEventHubDevice(SECOND_EVENTHUB_ID);
9780 MultiTouchInputMapper& mapper2 = device2->constructAndAddMapper<
9781 MultiTouchInputMapper>(SECOND_EVENTHUB_ID, mFakePolicy->getReaderConfiguration());
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009782 std::list<NotifyArgs> unused =
9783 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00009784 /*changes=*/{});
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009785 unused += device2->reset(ARBITRARY_TIME);
Arthur Hung7c645402019-01-25 17:45:42 +08009786
9787 // Setup PointerController.
Michael Wright17db18e2020-06-26 20:51:44 +01009788 std::shared_ptr<FakePointerController> fakePointerController =
9789 std::make_shared<FakePointerController>();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009790 mFakePolicy->setPointerController(fakePointerController);
Arthur Hung7c645402019-01-25 17:45:42 +08009791
9792 // Setup policy for associated displays and show touches.
9793 const uint8_t hdmi1 = 0;
9794 const uint8_t hdmi2 = 1;
9795 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
9796 mFakePolicy->addInputPortAssociation(USB2, hdmi2);
9797 mFakePolicy->setShowTouches(true);
9798
9799 // Create displays.
Michael Wrighta9cf4192022-12-01 23:46:39 +00009800 prepareDisplay(ui::ROTATION_0, hdmi1);
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009801 prepareSecondaryDisplay(ViewportType::EXTERNAL, hdmi2);
Arthur Hung7c645402019-01-25 17:45:42 +08009802
9803 // Default device will reconfigure above, need additional reconfiguration for another device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009804 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00009805 InputReaderConfiguration::Change::DISPLAY_INFO |
9806 InputReaderConfiguration::Change::SHOW_TOUCHES);
Arthur Hung7c645402019-01-25 17:45:42 +08009807
9808 // Two fingers down at default display.
9809 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
9810 processPosition(mapper, x1, y1);
9811 processId(mapper, 1);
9812 processSlot(mapper, 1);
9813 processPosition(mapper, x2, y2);
9814 processId(mapper, 2);
9815 processSync(mapper);
9816
9817 std::map<int32_t, std::vector<int32_t>>::const_iterator iter =
9818 fakePointerController->getSpots().find(DISPLAY_ID);
9819 ASSERT_TRUE(iter != fakePointerController->getSpots().end());
9820 ASSERT_EQ(size_t(2), iter->second.size());
9821
9822 // Two fingers down at second display.
9823 processPosition(mapper2, x1, y1);
9824 processId(mapper2, 1);
9825 processSlot(mapper2, 1);
9826 processPosition(mapper2, x2, y2);
9827 processId(mapper2, 2);
9828 processSync(mapper2);
9829
9830 iter = fakePointerController->getSpots().find(SECONDARY_DISPLAY_ID);
9831 ASSERT_TRUE(iter != fakePointerController->getSpots().end());
9832 ASSERT_EQ(size_t(2), iter->second.size());
Prabir Pradhan197e0862022-07-01 14:28:00 +00009833
9834 // Disable the show touches configuration and ensure the spots are cleared.
9835 mFakePolicy->setShowTouches(false);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009836 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhan4bf6d452023-04-18 21:26:56 +00009837 InputReaderConfiguration::Change::SHOW_TOUCHES);
Prabir Pradhan197e0862022-07-01 14:28:00 +00009838
9839 ASSERT_TRUE(fakePointerController->getSpots().empty());
Arthur Hung7c645402019-01-25 17:45:42 +08009840}
9841
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009842TEST_F(MultiTouchInputMapperTest, VideoFrames_ReceivedByListener) {
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009843 prepareAxes(POSITION);
9844 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009845 prepareDisplay(ui::ROTATION_0);
Arpit Singha8c236b2023-04-25 13:56:05 +00009846 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009847
9848 NotifyMotionArgs motionArgs;
9849 // Unrotated video frame
9850 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9851 std::vector<TouchVideoFrame> frames{frame};
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009852 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009853 processPosition(mapper, 100, 200);
9854 processSync(mapper);
9855 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9856 ASSERT_EQ(frames, motionArgs.videoFrames);
9857
9858 // Subsequent touch events should not have any videoframes
9859 // This is implemented separately in FakeEventHub,
9860 // but that should match the behaviour of TouchVideoDevice.
9861 processPosition(mapper, 200, 200);
9862 processSync(mapper);
9863 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9864 ASSERT_EQ(std::vector<TouchVideoFrame>(), motionArgs.videoFrames);
9865}
9866
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009867TEST_F(MultiTouchInputMapperTest, VideoFrames_AreNotRotated) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009868 prepareAxes(POSITION);
9869 addConfigurationProperty("touch.deviceType", "touchScreen");
Arpit Singha8c236b2023-04-25 13:56:05 +00009870 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009871 // Unrotated video frame
9872 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9873 NotifyMotionArgs motionArgs;
9874
9875 // Test all 4 orientations
Michael Wrighta9cf4192022-12-01 23:46:39 +00009876 for (ui::Rotation orientation : ftl::enum_range<ui::Rotation>()) {
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009877 SCOPED_TRACE("Orientation " + StringPrintf("%i", orientation));
9878 clearViewports();
9879 prepareDisplay(orientation);
9880 std::vector<TouchVideoFrame> frames{frame};
9881 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
9882 processPosition(mapper, 100, 200);
9883 processSync(mapper);
9884 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9885 ASSERT_EQ(frames, motionArgs.videoFrames);
9886 }
9887}
9888
9889TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_AreRotated) {
9890 prepareAxes(POSITION);
9891 addConfigurationProperty("touch.deviceType", "touchScreen");
9892 // Since InputReader works in the un-rotated coordinate space, only devices that are not
9893 // orientation-aware are affected by display rotation.
9894 addConfigurationProperty("touch.orientationAware", "0");
Arpit Singha8c236b2023-04-25 13:56:05 +00009895 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009896 // Unrotated video frame
9897 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9898 NotifyMotionArgs motionArgs;
9899
9900 // Test all 4 orientations
Michael Wrighta9cf4192022-12-01 23:46:39 +00009901 for (ui::Rotation orientation : ftl::enum_range<ui::Rotation>()) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009902 SCOPED_TRACE("Orientation " + StringPrintf("%i", orientation));
9903 clearViewports();
9904 prepareDisplay(orientation);
9905 std::vector<TouchVideoFrame> frames{frame};
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009906 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009907 processPosition(mapper, 100, 200);
9908 processSync(mapper);
9909 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009910 // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
9911 // compared to the display. This is so that when the window transform (which contains the
9912 // display rotation) is applied later by InputDispatcher, the coordinates end up in the
9913 // window's coordinate space.
9914 frames[0].rotate(getInverseRotation(orientation));
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009915 ASSERT_EQ(frames, motionArgs.videoFrames);
lilinnan687e58f2022-07-19 16:00:50 +08009916
9917 // Release finger.
9918 processSync(mapper);
9919 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009920 }
9921}
9922
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009923TEST_F(MultiTouchInputMapperTest, VideoFrames_MultipleFramesAreNotRotated) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009924 prepareAxes(POSITION);
9925 addConfigurationProperty("touch.deviceType", "touchScreen");
Arpit Singha8c236b2023-04-25 13:56:05 +00009926 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009927 // Unrotated video frames. There's no rule that they must all have the same dimensions,
9928 // so mix these.
9929 TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9930 TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
9931 TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
9932 std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
9933 NotifyMotionArgs motionArgs;
9934
Michael Wrighta9cf4192022-12-01 23:46:39 +00009935 prepareDisplay(ui::ROTATION_90);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009936 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009937 processPosition(mapper, 100, 200);
9938 processSync(mapper);
9939 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009940 ASSERT_EQ(frames, motionArgs.videoFrames);
9941}
9942
9943TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_MultipleFramesAreRotated) {
9944 prepareAxes(POSITION);
9945 addConfigurationProperty("touch.deviceType", "touchScreen");
9946 // Since InputReader works in the un-rotated coordinate space, only devices that are not
9947 // orientation-aware are affected by display rotation.
9948 addConfigurationProperty("touch.orientationAware", "0");
Arpit Singha8c236b2023-04-25 13:56:05 +00009949 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009950 // Unrotated video frames. There's no rule that they must all have the same dimensions,
9951 // so mix these.
9952 TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9953 TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
9954 TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
9955 std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
9956 NotifyMotionArgs motionArgs;
9957
Michael Wrighta9cf4192022-12-01 23:46:39 +00009958 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009959 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
9960 processPosition(mapper, 100, 200);
9961 processSync(mapper);
9962 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9963 std::for_each(frames.begin(), frames.end(), [](TouchVideoFrame& frame) {
9964 // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
9965 // compared to the display. This is so that when the window transform (which contains the
9966 // display rotation) is applied later by InputDispatcher, the coordinates end up in the
9967 // window's coordinate space.
Michael Wrighta9cf4192022-12-01 23:46:39 +00009968 frame.rotate(getInverseRotation(ui::ROTATION_90));
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009969 });
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009970 ASSERT_EQ(frames, motionArgs.videoFrames);
9971}
9972
Arthur Hung9da14732019-09-02 16:16:58 +08009973/**
9974 * If we had defined port associations, but the viewport is not ready, the touch device would be
9975 * expected to be disabled, and it should be enabled after the viewport has found.
9976 */
9977TEST_F(MultiTouchInputMapperTest, Configure_EnabledForAssociatedDisplay) {
Arthur Hung9da14732019-09-02 16:16:58 +08009978 constexpr uint8_t hdmi2 = 1;
9979 const std::string secondaryUniqueId = "uniqueId2";
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009980 constexpr ViewportType type = ViewportType::EXTERNAL;
Arthur Hung9da14732019-09-02 16:16:58 +08009981
9982 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi2);
9983
9984 addConfigurationProperty("touch.deviceType", "touchScreen");
9985 prepareAxes(POSITION);
Arpit Singha8c236b2023-04-25 13:56:05 +00009986 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Arthur Hung9da14732019-09-02 16:16:58 +08009987
9988 ASSERT_EQ(mDevice->isEnabled(), false);
9989
9990 // Add display on hdmi2, the device should be enabled and can receive touch event.
9991 prepareSecondaryDisplay(type, hdmi2);
9992 ASSERT_EQ(mDevice->isEnabled(), true);
9993
9994 // Send a touch event.
9995 processPosition(mapper, 100, 100);
9996 processSync(mapper);
9997
9998 NotifyMotionArgs args;
9999 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10000 ASSERT_EQ(SECONDARY_DISPLAY_ID, args.displayId);
10001}
10002
Arthur Hung421eb1c2020-01-16 00:09:42 +080010003TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleSingleTouch) {
Arthur Hung421eb1c2020-01-16 00:09:42 +080010004 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010005 prepareDisplay(ui::ROTATION_0);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010006 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010007 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Arthur Hung421eb1c2020-01-16 00:09:42 +080010008
10009 NotifyMotionArgs motionArgs;
10010
10011 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
10012 // finger down
10013 processId(mapper, 1);
10014 processPosition(mapper, x1, y1);
10015 processSync(mapper);
10016 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10017 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010018 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010019
10020 // finger move
10021 processId(mapper, 1);
10022 processPosition(mapper, x2, y2);
10023 processSync(mapper);
10024 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10025 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010026 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010027
10028 // finger up.
10029 processId(mapper, -1);
10030 processSync(mapper);
10031 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10032 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010033 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010034
10035 // new finger down
10036 processId(mapper, 1);
10037 processPosition(mapper, x3, y3);
10038 processSync(mapper);
10039 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10040 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010041 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010042}
10043
10044/**
arthurhungcc7f9802020-04-30 17:55:40 +080010045 * Test single touch should be canceled when received the MT_TOOL_PALM event, and the following
10046 * MOVE and UP events should be ignored.
Arthur Hung421eb1c2020-01-16 00:09:42 +080010047 */
arthurhungcc7f9802020-04-30 17:55:40 +080010048TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_SinglePointer) {
Arthur Hung421eb1c2020-01-16 00:09:42 +080010049 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010050 prepareDisplay(ui::ROTATION_0);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010051 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010052 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Arthur Hung421eb1c2020-01-16 00:09:42 +080010053
10054 NotifyMotionArgs motionArgs;
10055
10056 // default tool type is finger
10057 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
arthurhungcc7f9802020-04-30 17:55:40 +080010058 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010059 processPosition(mapper, x1, y1);
10060 processSync(mapper);
10061 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10062 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010063 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010064
10065 // Tool changed to MT_TOOL_PALM expect sending the cancel event.
10066 processToolType(mapper, MT_TOOL_PALM);
10067 processSync(mapper);
10068 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10069 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
10070
10071 // Ignore the following MOVE and UP events if had detect a palm event.
arthurhungcc7f9802020-04-30 17:55:40 +080010072 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010073 processPosition(mapper, x2, y2);
10074 processSync(mapper);
10075 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10076
10077 // finger up.
arthurhungcc7f9802020-04-30 17:55:40 +080010078 processId(mapper, INVALID_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010079 processSync(mapper);
10080 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10081
10082 // new finger down
arthurhungcc7f9802020-04-30 17:55:40 +080010083 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010084 processToolType(mapper, MT_TOOL_FINGER);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010085 processPosition(mapper, x3, y3);
10086 processSync(mapper);
10087 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10088 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010089 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Arthur Hung421eb1c2020-01-16 00:09:42 +080010090}
10091
arthurhungbf89a482020-04-17 17:37:55 +080010092/**
arthurhungcc7f9802020-04-30 17:55:40 +080010093 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event from some finger,
10094 * and the rest active fingers could still be allowed to receive the events
arthurhungbf89a482020-04-17 17:37:55 +080010095 */
arthurhungcc7f9802020-04-30 17:55:40 +080010096TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_TwoPointers) {
arthurhungbf89a482020-04-17 17:37:55 +080010097 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010098 prepareDisplay(ui::ROTATION_0);
arthurhungbf89a482020-04-17 17:37:55 +080010099 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010100 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
arthurhungbf89a482020-04-17 17:37:55 +080010101
10102 NotifyMotionArgs motionArgs;
10103
10104 // default tool type is finger
arthurhungcc7f9802020-04-30 17:55:40 +080010105 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220;
10106 processId(mapper, FIRST_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +080010107 processPosition(mapper, x1, y1);
10108 processSync(mapper);
10109 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10110 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010111 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
arthurhungbf89a482020-04-17 17:37:55 +080010112
10113 // Second finger down.
arthurhungcc7f9802020-04-30 17:55:40 +080010114 processSlot(mapper, SECOND_SLOT);
10115 processId(mapper, SECOND_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +080010116 processPosition(mapper, x2, y2);
arthurhungcc7f9802020-04-30 17:55:40 +080010117 processSync(mapper);
10118 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010119 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010120 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
arthurhungcc7f9802020-04-30 17:55:40 +080010121
10122 // If the tool type of the first finger changes to MT_TOOL_PALM,
10123 // we expect to receive ACTION_POINTER_UP with cancel flag.
10124 processSlot(mapper, FIRST_SLOT);
10125 processId(mapper, FIRST_TRACKING_ID);
10126 processToolType(mapper, MT_TOOL_PALM);
10127 processSync(mapper);
10128 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010129 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +080010130 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
10131
10132 // The following MOVE events of second finger should be processed.
10133 processSlot(mapper, SECOND_SLOT);
10134 processId(mapper, SECOND_TRACKING_ID);
10135 processPosition(mapper, x2 + 1, y2 + 1);
10136 processSync(mapper);
10137 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10138 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010139 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
arthurhungcc7f9802020-04-30 17:55:40 +080010140
10141 // First finger up. It used to be in palm mode, and we already generated ACTION_POINTER_UP for
10142 // it. Second finger receive move.
10143 processSlot(mapper, FIRST_SLOT);
10144 processId(mapper, INVALID_TRACKING_ID);
10145 processSync(mapper);
10146 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10147 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010148 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
arthurhungcc7f9802020-04-30 17:55:40 +080010149
10150 // Second finger keeps moving.
10151 processSlot(mapper, SECOND_SLOT);
10152 processId(mapper, SECOND_TRACKING_ID);
10153 processPosition(mapper, x2 + 2, y2 + 2);
10154 processSync(mapper);
10155 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10156 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010157 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
arthurhungcc7f9802020-04-30 17:55:40 +080010158
10159 // Second finger up.
10160 processId(mapper, INVALID_TRACKING_ID);
10161 processSync(mapper);
10162 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10163 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
10164 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
10165}
10166
10167/**
10168 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event, if only 1 finger
10169 * is active, it should send CANCEL after receiving the MT_TOOL_PALM event.
10170 */
10171TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_ShouldCancelWhenAllTouchIsPalm) {
10172 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010173 prepareDisplay(ui::ROTATION_0);
arthurhungcc7f9802020-04-30 17:55:40 +080010174 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010175 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
arthurhungcc7f9802020-04-30 17:55:40 +080010176
10177 NotifyMotionArgs motionArgs;
10178
10179 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
10180 // First finger down.
10181 processId(mapper, FIRST_TRACKING_ID);
10182 processPosition(mapper, x1, y1);
10183 processSync(mapper);
10184 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10185 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010186 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
arthurhungcc7f9802020-04-30 17:55:40 +080010187
10188 // Second finger down.
10189 processSlot(mapper, SECOND_SLOT);
10190 processId(mapper, SECOND_TRACKING_ID);
10191 processPosition(mapper, x2, y2);
arthurhungbf89a482020-04-17 17:37:55 +080010192 processSync(mapper);
10193 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010194 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010195 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
arthurhungbf89a482020-04-17 17:37:55 +080010196
arthurhungcc7f9802020-04-30 17:55:40 +080010197 // If the tool type of the first finger changes to MT_TOOL_PALM,
10198 // we expect to receive ACTION_POINTER_UP with cancel flag.
10199 processSlot(mapper, FIRST_SLOT);
10200 processId(mapper, FIRST_TRACKING_ID);
10201 processToolType(mapper, MT_TOOL_PALM);
10202 processSync(mapper);
10203 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010204 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +080010205 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
10206
10207 // Second finger keeps moving.
10208 processSlot(mapper, SECOND_SLOT);
10209 processId(mapper, SECOND_TRACKING_ID);
10210 processPosition(mapper, x2 + 1, y2 + 1);
10211 processSync(mapper);
10212 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10213 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10214
10215 // second finger becomes palm, receive cancel due to only 1 finger is active.
10216 processId(mapper, SECOND_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +080010217 processToolType(mapper, MT_TOOL_PALM);
10218 processSync(mapper);
10219 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10220 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
10221
arthurhungcc7f9802020-04-30 17:55:40 +080010222 // third finger down.
10223 processSlot(mapper, THIRD_SLOT);
10224 processId(mapper, THIRD_TRACKING_ID);
10225 processToolType(mapper, MT_TOOL_FINGER);
arthurhungbf89a482020-04-17 17:37:55 +080010226 processPosition(mapper, x3, y3);
10227 processSync(mapper);
arthurhungbf89a482020-04-17 17:37:55 +080010228 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10229 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010230 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010231 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
arthurhungcc7f9802020-04-30 17:55:40 +080010232
10233 // third finger move
10234 processId(mapper, THIRD_TRACKING_ID);
10235 processPosition(mapper, x3 + 1, y3 + 1);
10236 processSync(mapper);
10237 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10238 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10239
10240 // first finger up, third finger receive move.
10241 processSlot(mapper, FIRST_SLOT);
10242 processId(mapper, INVALID_TRACKING_ID);
10243 processSync(mapper);
10244 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10245 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010246 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
arthurhungcc7f9802020-04-30 17:55:40 +080010247
10248 // second finger up, third finger receive move.
10249 processSlot(mapper, SECOND_SLOT);
10250 processId(mapper, INVALID_TRACKING_ID);
10251 processSync(mapper);
10252 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10253 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010254 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
arthurhungcc7f9802020-04-30 17:55:40 +080010255
10256 // third finger up.
10257 processSlot(mapper, THIRD_SLOT);
10258 processId(mapper, INVALID_TRACKING_ID);
10259 processSync(mapper);
10260 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10261 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
10262 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
10263}
10264
10265/**
10266 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event from some finger,
10267 * and the active finger could still be allowed to receive the events
10268 */
10269TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_KeepFirstPointer) {
10270 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010271 prepareDisplay(ui::ROTATION_0);
arthurhungcc7f9802020-04-30 17:55:40 +080010272 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010273 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
arthurhungcc7f9802020-04-30 17:55:40 +080010274
10275 NotifyMotionArgs motionArgs;
10276
10277 // default tool type is finger
10278 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220;
10279 processId(mapper, FIRST_TRACKING_ID);
10280 processPosition(mapper, x1, y1);
10281 processSync(mapper);
10282 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10283 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010284 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
arthurhungcc7f9802020-04-30 17:55:40 +080010285
10286 // Second finger down.
10287 processSlot(mapper, SECOND_SLOT);
10288 processId(mapper, SECOND_TRACKING_ID);
10289 processPosition(mapper, x2, y2);
10290 processSync(mapper);
10291 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010292 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010293 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
arthurhungcc7f9802020-04-30 17:55:40 +080010294
10295 // If the tool type of the second finger changes to MT_TOOL_PALM,
10296 // we expect to receive ACTION_POINTER_UP with cancel flag.
10297 processId(mapper, SECOND_TRACKING_ID);
10298 processToolType(mapper, MT_TOOL_PALM);
10299 processSync(mapper);
10300 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010301 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +080010302 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
10303
10304 // The following MOVE event should be processed.
10305 processSlot(mapper, FIRST_SLOT);
10306 processId(mapper, FIRST_TRACKING_ID);
10307 processPosition(mapper, x1 + 1, y1 + 1);
10308 processSync(mapper);
10309 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10310 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010311 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
arthurhungcc7f9802020-04-30 17:55:40 +080010312
10313 // second finger up.
10314 processSlot(mapper, SECOND_SLOT);
10315 processId(mapper, INVALID_TRACKING_ID);
10316 processSync(mapper);
10317 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10318 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10319
10320 // first finger keep moving
10321 processSlot(mapper, FIRST_SLOT);
10322 processId(mapper, FIRST_TRACKING_ID);
10323 processPosition(mapper, x1 + 2, y1 + 2);
10324 processSync(mapper);
10325 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10326 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10327
10328 // first finger up.
10329 processId(mapper, INVALID_TRACKING_ID);
10330 processSync(mapper);
10331 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10332 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
10333 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
arthurhungbf89a482020-04-17 17:37:55 +080010334}
10335
Arthur Hung9ad18942021-06-19 02:04:46 +000010336/**
10337 * Test multi-touch should sent ACTION_POINTER_UP/ACTION_UP when received the INVALID_TRACKING_ID,
10338 * to prevent the driver side may send unexpected data after set tracking id as INVALID_TRACKING_ID
10339 * cause slot be valid again.
10340 */
10341TEST_F(MultiTouchInputMapperTest, Process_MultiTouch_WithInvalidTrackingId) {
10342 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010343 prepareDisplay(ui::ROTATION_0);
Arthur Hung9ad18942021-06-19 02:04:46 +000010344 prepareAxes(POSITION | ID | SLOT | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010345 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Arthur Hung9ad18942021-06-19 02:04:46 +000010346
10347 NotifyMotionArgs motionArgs;
10348
10349 constexpr int32_t x1 = 100, y1 = 200, x2 = 0, y2 = 0;
10350 // First finger down.
10351 processId(mapper, FIRST_TRACKING_ID);
10352 processPosition(mapper, x1, y1);
10353 processPressure(mapper, RAW_PRESSURE_MAX);
10354 processSync(mapper);
10355 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10356 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010357 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
Arthur Hung9ad18942021-06-19 02:04:46 +000010358
10359 // First finger move.
10360 processId(mapper, FIRST_TRACKING_ID);
10361 processPosition(mapper, x1 + 1, y1 + 1);
10362 processPressure(mapper, RAW_PRESSURE_MAX);
10363 processSync(mapper);
10364 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10365 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010366 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
Arthur Hung9ad18942021-06-19 02:04:46 +000010367
10368 // Second finger down.
10369 processSlot(mapper, SECOND_SLOT);
10370 processId(mapper, SECOND_TRACKING_ID);
10371 processPosition(mapper, x2, y2);
10372 processPressure(mapper, RAW_PRESSURE_MAX);
10373 processSync(mapper);
10374 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010375 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010376 ASSERT_EQ(uint32_t(2), motionArgs.getPointerCount());
Arthur Hung9ad18942021-06-19 02:04:46 +000010377
10378 // second finger up with some unexpected data.
10379 processSlot(mapper, SECOND_SLOT);
10380 processId(mapper, INVALID_TRACKING_ID);
10381 processPosition(mapper, x2, y2);
10382 processSync(mapper);
10383 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010384 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010385 ASSERT_EQ(uint32_t(2), motionArgs.getPointerCount());
Arthur Hung9ad18942021-06-19 02:04:46 +000010386
10387 // first finger up with some unexpected data.
10388 processSlot(mapper, FIRST_SLOT);
10389 processId(mapper, INVALID_TRACKING_ID);
10390 processPosition(mapper, x2, y2);
10391 processPressure(mapper, RAW_PRESSURE_MAX);
10392 processSync(mapper);
10393 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10394 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010395 ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
Arthur Hung9ad18942021-06-19 02:04:46 +000010396}
10397
Prabir Pradhanafabcde2022-09-27 19:32:43 +000010398TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState) {
10399 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010400 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanafabcde2022-09-27 19:32:43 +000010401 prepareAxes(POSITION | ID | SLOT | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010402 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhanafabcde2022-09-27 19:32:43 +000010403
10404 // First finger down.
10405 processId(mapper, FIRST_TRACKING_ID);
10406 processPosition(mapper, 100, 200);
10407 processPressure(mapper, RAW_PRESSURE_MAX);
10408 processSync(mapper);
10409 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10410 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
10411
10412 // Second finger down.
10413 processSlot(mapper, SECOND_SLOT);
10414 processId(mapper, SECOND_TRACKING_ID);
10415 processPosition(mapper, 300, 400);
10416 processPressure(mapper, RAW_PRESSURE_MAX);
10417 processSync(mapper);
10418 ASSERT_NO_FATAL_FAILURE(
10419 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(ACTION_POINTER_1_DOWN)));
10420
10421 // Reset the mapper. When the mapper is reset, we expect the current multi-touch state to be
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +000010422 // preserved. Resetting should cancel the ongoing gesture.
10423 resetMapper(mapper, ARBITRARY_TIME);
10424 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10425 WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
Prabir Pradhanafabcde2022-09-27 19:32:43 +000010426
10427 // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
10428 // the existing touch state to generate a down event.
10429 processPosition(mapper, 301, 302);
10430 processSync(mapper);
10431 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10432 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
10433 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10434 AllOf(WithMotionAction(ACTION_POINTER_1_DOWN), WithPressure(1.f))));
10435
10436 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10437}
10438
10439TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState_NoPointersDown) {
10440 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010441 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanafabcde2022-09-27 19:32:43 +000010442 prepareAxes(POSITION | ID | SLOT | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010443 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhanafabcde2022-09-27 19:32:43 +000010444
10445 // First finger touches down and releases.
10446 processId(mapper, FIRST_TRACKING_ID);
10447 processPosition(mapper, 100, 200);
10448 processPressure(mapper, RAW_PRESSURE_MAX);
10449 processSync(mapper);
10450 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10451 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
10452 processId(mapper, INVALID_TRACKING_ID);
10453 processSync(mapper);
10454 ASSERT_NO_FATAL_FAILURE(
10455 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
10456
10457 // Reset the mapper. When the mapper is reset, we expect it to restore the latest
10458 // raw state where no pointers are down.
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +000010459 resetMapper(mapper, ARBITRARY_TIME);
Prabir Pradhanafabcde2022-09-27 19:32:43 +000010460 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10461
10462 // Send an empty sync frame. Since there are no pointers, no events are generated.
10463 processSync(mapper);
10464 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10465}
10466
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +000010467TEST_F(MultiTouchInputMapperTest, StylusSourceIsAddedDynamicallyFromToolType) {
Prabir Pradhanf9a41282022-10-25 17:15:50 +000010468 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010469 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanf9a41282022-10-25 17:15:50 +000010470 prepareAxes(POSITION | ID | SLOT | PRESSURE | TOOL_TYPE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010471 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +000010472 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
Prabir Pradhanf9a41282022-10-25 17:15:50 +000010473
10474 // Even if the device supports reporting the ABS_MT_TOOL_TYPE axis, which could give it the
10475 // ability to report MT_TOOL_PEN, we do not report the device as coming from a stylus source.
10476 // Due to limitations in the evdev protocol, we cannot say for certain that a device is capable
10477 // of reporting stylus events just because it supports ABS_MT_TOOL_TYPE.
10478 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
10479
10480 // However, if the device ever ends up reporting an event with MT_TOOL_PEN, it should be
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +000010481 // reported with the stylus source.
Prabir Pradhanf9a41282022-10-25 17:15:50 +000010482 processId(mapper, FIRST_TRACKING_ID);
10483 processToolType(mapper, MT_TOOL_PEN);
10484 processPosition(mapper, 100, 200);
10485 processPressure(mapper, RAW_PRESSURE_MAX);
10486 processSync(mapper);
10487 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10488 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
10489 WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010490 WithToolType(ToolType::STYLUS))));
Prabir Pradhanf9a41282022-10-25 17:15:50 +000010491
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +000010492 // Now that we know the device supports styluses, ensure that the device is re-configured with
10493 // the stylus source.
10494 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS, mapper.getSources());
10495 {
10496 const auto& devices = mReader->getInputDevices();
10497 auto deviceInfo =
10498 std::find_if(devices.begin(), devices.end(),
10499 [](const InputDeviceInfo& info) { return info.getId() == DEVICE_ID; });
10500 LOG_ALWAYS_FATAL_IF(deviceInfo == devices.end(), "Cannot find InputDevice");
10501 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS, deviceInfo->getSources());
10502 }
10503
10504 // Ensure the device was not reset to prevent interruptions of any ongoing gestures.
10505 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
10506
Prabir Pradhanf9a41282022-10-25 17:15:50 +000010507 processId(mapper, INVALID_TRACKING_ID);
10508 processSync(mapper);
10509 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10510 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
10511 WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010512 WithToolType(ToolType::STYLUS))));
Prabir Pradhanf9a41282022-10-25 17:15:50 +000010513}
10514
Seunghwan Choi356026c2023-02-01 14:37:25 +090010515TEST_F(MultiTouchInputMapperTest, Process_WhenConfigEnabled_ShouldShowDirectStylusPointer) {
10516 addConfigurationProperty("touch.deviceType", "touchScreen");
10517 prepareDisplay(ui::ROTATION_0);
10518 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE | PRESSURE);
10519 // Add BTN_TOOL_PEN to statically show stylus support, since using ABS_MT_TOOL_TYPE can only
10520 // indicate stylus presence dynamically.
10521 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
10522 std::shared_ptr<FakePointerController> fakePointerController =
10523 std::make_shared<FakePointerController>();
10524 mFakePolicy->setPointerController(fakePointerController);
10525 mFakePolicy->setStylusPointerIconEnabled(true);
Arpit Singha8c236b2023-04-25 13:56:05 +000010526 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Seunghwan Choi356026c2023-02-01 14:37:25 +090010527
10528 processId(mapper, FIRST_TRACKING_ID);
10529 processPressure(mapper, RAW_PRESSURE_MIN);
10530 processPosition(mapper, 100, 200);
10531 processToolType(mapper, MT_TOOL_PEN);
10532 processSync(mapper);
10533 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10534 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010535 WithToolType(ToolType::STYLUS),
Seunghwan Choi356026c2023-02-01 14:37:25 +090010536 WithPointerCoords(0, toDisplayX(100), toDisplayY(200)))));
10537 ASSERT_TRUE(fakePointerController->isPointerShown());
10538 ASSERT_NO_FATAL_FAILURE(
10539 fakePointerController->assertPosition(toDisplayX(100), toDisplayY(200)));
10540}
10541
10542TEST_F(MultiTouchInputMapperTest, Process_WhenConfigDisabled_ShouldNotShowDirectStylusPointer) {
10543 addConfigurationProperty("touch.deviceType", "touchScreen");
10544 prepareDisplay(ui::ROTATION_0);
10545 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE | PRESSURE);
10546 // Add BTN_TOOL_PEN to statically show stylus support, since using ABS_MT_TOOL_TYPE can only
10547 // indicate stylus presence dynamically.
10548 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
10549 std::shared_ptr<FakePointerController> fakePointerController =
10550 std::make_shared<FakePointerController>();
10551 mFakePolicy->setPointerController(fakePointerController);
10552 mFakePolicy->setStylusPointerIconEnabled(false);
Arpit Singha8c236b2023-04-25 13:56:05 +000010553 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Seunghwan Choi356026c2023-02-01 14:37:25 +090010554
10555 processId(mapper, FIRST_TRACKING_ID);
10556 processPressure(mapper, RAW_PRESSURE_MIN);
10557 processPosition(mapper, 100, 200);
10558 processToolType(mapper, MT_TOOL_PEN);
10559 processSync(mapper);
10560 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10561 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010562 WithToolType(ToolType::STYLUS),
Seunghwan Choi356026c2023-02-01 14:37:25 +090010563 WithPointerCoords(0, toDisplayX(100), toDisplayY(200)))));
10564 ASSERT_FALSE(fakePointerController->isPointerShown());
10565}
10566
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080010567// --- MultiTouchInputMapperTest_ExternalDevice ---
10568
10569class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest {
10570protected:
Chris Yea52ade12020-08-27 16:49:20 -070010571 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080010572};
10573
10574/**
10575 * Expect fallback to internal viewport if device is external and external viewport is not present.
10576 */
10577TEST_F(MultiTouchInputMapperTest_ExternalDevice, Viewports_Fallback) {
10578 prepareAxes(POSITION);
10579 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010580 prepareDisplay(ui::ROTATION_0);
Arpit Singha8c236b2023-04-25 13:56:05 +000010581 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080010582
10583 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
10584
10585 NotifyMotionArgs motionArgs;
10586
10587 // Expect the event to be sent to the internal viewport,
10588 // because an external viewport is not present.
10589 processPosition(mapper, 100, 100);
10590 processSync(mapper);
10591 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10592 ASSERT_EQ(ADISPLAY_ID_DEFAULT, motionArgs.displayId);
10593
10594 // Expect the event to be sent to the external viewport if it is present.
Michael Wrightfe3de7d2020-07-02 19:05:30 +010010595 prepareSecondaryDisplay(ViewportType::EXTERNAL);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080010596 processPosition(mapper, 100, 100);
10597 processSync(mapper);
10598 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10599 ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
10600}
Arthur Hung4197f6b2020-03-16 15:39:59 +080010601
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010602TEST_F(MultiTouchInputMapperTest, Process_TouchpadCapture) {
10603 // we need a pointer controller for mouse mode of touchpad (start pointer at 0,0)
10604 std::shared_ptr<FakePointerController> fakePointerController =
10605 std::make_shared<FakePointerController>();
10606 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
10607 fakePointerController->setPosition(0, 0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010608
10609 // prepare device and capture
Michael Wrighta9cf4192022-12-01 23:46:39 +000010610 prepareDisplay(ui::ROTATION_0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010611 prepareAxes(POSITION | ID | SLOT);
10612 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
10613 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
10614 mFakePolicy->setPointerCapture(true);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +000010615 mFakePolicy->setPointerController(fakePointerController);
Arpit Singha8c236b2023-04-25 13:56:05 +000010616 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010617
10618 // captured touchpad should be a touchpad source
10619 NotifyDeviceResetArgs resetArgs;
10620 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
10621 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
10622
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010623 InputDeviceInfo deviceInfo = mDevice->getDeviceInfo();
Chris Yef74dc422020-09-02 22:41:50 -070010624
10625 const InputDeviceInfo::MotionRange* relRangeX =
10626 deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, AINPUT_SOURCE_TOUCHPAD);
10627 ASSERT_NE(relRangeX, nullptr);
10628 ASSERT_EQ(relRangeX->min, -(RAW_X_MAX - RAW_X_MIN));
10629 ASSERT_EQ(relRangeX->max, RAW_X_MAX - RAW_X_MIN);
10630 const InputDeviceInfo::MotionRange* relRangeY =
10631 deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, AINPUT_SOURCE_TOUCHPAD);
10632 ASSERT_NE(relRangeY, nullptr);
10633 ASSERT_EQ(relRangeY->min, -(RAW_Y_MAX - RAW_Y_MIN));
10634 ASSERT_EQ(relRangeY->max, RAW_Y_MAX - RAW_Y_MIN);
10635
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010636 // run captured pointer tests - note that this is unscaled, so input listener events should be
10637 // identical to what the hardware sends (accounting for any
10638 // calibration).
10639 // FINGER 0 DOWN
Chris Ye364fdb52020-08-05 15:07:56 -070010640 processSlot(mapper, 0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010641 processId(mapper, 1);
10642 processPosition(mapper, 100 + RAW_X_MIN, 100 + RAW_Y_MIN);
10643 processKey(mapper, BTN_TOUCH, 1);
10644 processSync(mapper);
10645
10646 // expect coord[0] to contain initial location of touch 0
10647 NotifyMotionArgs args;
10648 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10649 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010650 ASSERT_EQ(1U, args.getPointerCount());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010651 ASSERT_EQ(0, args.pointerProperties[0].id);
10652 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, args.source);
10653 ASSERT_NO_FATAL_FAILURE(
10654 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
10655
10656 // FINGER 1 DOWN
10657 processSlot(mapper, 1);
10658 processId(mapper, 2);
10659 processPosition(mapper, 560 + RAW_X_MIN, 154 + RAW_Y_MIN);
10660 processSync(mapper);
10661
10662 // expect coord[0] to contain previous location, coord[1] to contain new touch 1 location
10663 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080010664 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010665 ASSERT_EQ(2U, args.getPointerCount());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010666 ASSERT_EQ(0, args.pointerProperties[0].id);
10667 ASSERT_EQ(1, args.pointerProperties[1].id);
10668 ASSERT_NO_FATAL_FAILURE(
10669 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
10670 ASSERT_NO_FATAL_FAILURE(
10671 assertPointerCoords(args.pointerCoords[1], 560, 154, 1, 0, 0, 0, 0, 0, 0, 0));
10672
10673 // FINGER 1 MOVE
10674 processPosition(mapper, 540 + RAW_X_MIN, 690 + RAW_Y_MIN);
10675 processSync(mapper);
10676
10677 // expect coord[0] to contain previous location, coord[1] to contain new touch 1 location
10678 // from move
10679 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10680 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
10681 ASSERT_NO_FATAL_FAILURE(
10682 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
10683 ASSERT_NO_FATAL_FAILURE(
10684 assertPointerCoords(args.pointerCoords[1], 540, 690, 1, 0, 0, 0, 0, 0, 0, 0));
10685
10686 // FINGER 0 MOVE
10687 processSlot(mapper, 0);
10688 processPosition(mapper, 50 + RAW_X_MIN, 800 + RAW_Y_MIN);
10689 processSync(mapper);
10690
10691 // expect coord[0] to contain new touch 0 location, coord[1] to contain previous location
10692 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10693 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
10694 ASSERT_NO_FATAL_FAILURE(
10695 assertPointerCoords(args.pointerCoords[0], 50, 800, 1, 0, 0, 0, 0, 0, 0, 0));
10696 ASSERT_NO_FATAL_FAILURE(
10697 assertPointerCoords(args.pointerCoords[1], 540, 690, 1, 0, 0, 0, 0, 0, 0, 0));
10698
10699 // BUTTON DOWN
10700 processKey(mapper, BTN_LEFT, 1);
10701 processSync(mapper);
10702
10703 // touchinputmapper design sends a move before button press
10704 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10705 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
10706 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10707 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
10708
10709 // BUTTON UP
10710 processKey(mapper, BTN_LEFT, 0);
10711 processSync(mapper);
10712
10713 // touchinputmapper design sends a move after button release
10714 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10715 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
10716 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10717 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
10718
10719 // FINGER 0 UP
10720 processId(mapper, -1);
10721 processSync(mapper);
10722 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10723 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | 0x0000, args.action);
10724
10725 // FINGER 1 MOVE
10726 processSlot(mapper, 1);
10727 processPosition(mapper, 320 + RAW_X_MIN, 900 + RAW_Y_MIN);
10728 processSync(mapper);
10729
10730 // expect coord[0] to contain new location of touch 1, and properties[0].id to contain 1
10731 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10732 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010733 ASSERT_EQ(1U, args.getPointerCount());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010734 ASSERT_EQ(1, args.pointerProperties[0].id);
10735 ASSERT_NO_FATAL_FAILURE(
10736 assertPointerCoords(args.pointerCoords[0], 320, 900, 1, 0, 0, 0, 0, 0, 0, 0));
10737
10738 // FINGER 1 UP
10739 processId(mapper, -1);
10740 processKey(mapper, BTN_TOUCH, 0);
10741 processSync(mapper);
10742 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10743 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
10744
Josep del Río2d8c79a2023-01-23 19:33:50 +000010745 // non captured touchpad should be a mouse source
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010746 mFakePolicy->setPointerCapture(false);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +000010747 configureDevice(InputReaderConfiguration::Change::POINTER_CAPTURE);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010748 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Josep del Río2d8c79a2023-01-23 19:33:50 +000010749 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010750}
10751
10752TEST_F(MultiTouchInputMapperTest, Process_UnCapturedTouchpadPointer) {
10753 std::shared_ptr<FakePointerController> fakePointerController =
10754 std::make_shared<FakePointerController>();
10755 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
10756 fakePointerController->setPosition(0, 0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010757
10758 // prepare device and capture
Michael Wrighta9cf4192022-12-01 23:46:39 +000010759 prepareDisplay(ui::ROTATION_0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010760 prepareAxes(POSITION | ID | SLOT);
10761 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
10762 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +000010763 mFakePolicy->setPointerController(fakePointerController);
Arpit Singha8c236b2023-04-25 13:56:05 +000010764 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010765 // run uncaptured pointer tests - pushes out generic events
10766 // FINGER 0 DOWN
10767 processId(mapper, 3);
10768 processPosition(mapper, 100, 100);
10769 processKey(mapper, BTN_TOUCH, 1);
10770 processSync(mapper);
10771
10772 // start at (100,100), cursor should be at (0,0) * scale
10773 NotifyMotionArgs args;
10774 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10775 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
10776 ASSERT_NO_FATAL_FAILURE(
10777 assertPointerCoords(args.pointerCoords[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
10778
10779 // FINGER 0 MOVE
10780 processPosition(mapper, 200, 200);
10781 processSync(mapper);
10782
10783 // compute scaling to help with touch position checking
10784 float rawDiagonal = hypotf(RAW_X_MAX - RAW_X_MIN, RAW_Y_MAX - RAW_Y_MIN);
10785 float displayDiagonal = hypotf(DISPLAY_WIDTH, DISPLAY_HEIGHT);
10786 float scale =
10787 mFakePolicy->getPointerGestureMovementSpeedRatio() * displayDiagonal / rawDiagonal;
10788
10789 // translate from (100,100) -> (200,200), cursor should have changed to (100,100) * scale)
10790 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10791 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
10792 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 100 * scale, 100 * scale, 0,
10793 0, 0, 0, 0, 0, 0, 0));
LiZhihong758eb562022-11-03 15:28:29 +080010794
10795 // BUTTON DOWN
10796 processKey(mapper, BTN_LEFT, 1);
10797 processSync(mapper);
10798
10799 // touchinputmapper design sends a move before button press
10800 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10801 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
10802 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10803 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
10804
10805 // BUTTON UP
10806 processKey(mapper, BTN_LEFT, 0);
10807 processSync(mapper);
10808
10809 // touchinputmapper design sends a move after button release
10810 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10811 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
10812 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10813 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010814}
10815
10816TEST_F(MultiTouchInputMapperTest, WhenCapturedAndNotCaptured_GetSources) {
10817 std::shared_ptr<FakePointerController> fakePointerController =
10818 std::make_shared<FakePointerController>();
10819
Michael Wrighta9cf4192022-12-01 23:46:39 +000010820 prepareDisplay(ui::ROTATION_0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010821 prepareAxes(POSITION | ID | SLOT);
10822 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +000010823 mFakePolicy->setPointerController(fakePointerController);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010824 mFakePolicy->setPointerCapture(false);
Arpit Singha8c236b2023-04-25 13:56:05 +000010825 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010826
Josep del Río2d8c79a2023-01-23 19:33:50 +000010827 // uncaptured touchpad should be a pointer device
10828 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010829
Josep del Río2d8c79a2023-01-23 19:33:50 +000010830 // captured touchpad should be a touchpad device
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010831 mFakePolicy->setPointerCapture(true);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +000010832 configureDevice(InputReaderConfiguration::Change::POINTER_CAPTURE);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010833 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
10834}
10835
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +000010836// --- BluetoothMultiTouchInputMapperTest ---
10837
10838class BluetoothMultiTouchInputMapperTest : public MultiTouchInputMapperTest {
10839protected:
10840 void SetUp() override {
10841 InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL, BUS_BLUETOOTH);
10842 }
10843};
10844
10845TEST_F(BluetoothMultiTouchInputMapperTest, TimestampSmoothening) {
10846 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010847 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +000010848 prepareAxes(POSITION | ID | SLOT | PRESSURE);
Arpit Singha8c236b2023-04-25 13:56:05 +000010849 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +000010850
10851 nsecs_t kernelEventTime = ARBITRARY_TIME;
10852 nsecs_t expectedEventTime = ARBITRARY_TIME;
10853 // Touch down.
10854 processId(mapper, FIRST_TRACKING_ID);
10855 processPosition(mapper, 100, 200);
10856 processPressure(mapper, RAW_PRESSURE_MAX);
10857 processSync(mapper, ARBITRARY_TIME);
10858 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10859 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithEventTime(ARBITRARY_TIME))));
10860
10861 // Process several events that come in quick succession, according to their timestamps.
10862 for (int i = 0; i < 3; i++) {
10863 constexpr static nsecs_t delta = ms2ns(1);
10864 static_assert(delta < MIN_BLUETOOTH_TIMESTAMP_DELTA);
10865 kernelEventTime += delta;
10866 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
10867
10868 processPosition(mapper, 101 + i, 201 + i);
10869 processSync(mapper, kernelEventTime);
10870 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10871 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
10872 WithEventTime(expectedEventTime))));
10873 }
10874
10875 // Release the touch.
10876 processId(mapper, INVALID_TRACKING_ID);
10877 processPressure(mapper, RAW_PRESSURE_MIN);
10878 processSync(mapper, ARBITRARY_TIME + ms2ns(50));
10879 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10880 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
10881 WithEventTime(ARBITRARY_TIME + ms2ns(50)))));
10882}
10883
10884// --- MultiTouchPointerModeTest ---
10885
HQ Liue6983c72022-04-19 22:14:56 +000010886class MultiTouchPointerModeTest : public MultiTouchInputMapperTest {
10887protected:
10888 float mPointerMovementScale;
10889 float mPointerXZoomScale;
10890 void preparePointerMode(int xAxisResolution, int yAxisResolution) {
10891 addConfigurationProperty("touch.deviceType", "pointer");
10892 std::shared_ptr<FakePointerController> fakePointerController =
10893 std::make_shared<FakePointerController>();
10894 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
10895 fakePointerController->setPosition(0, 0);
Michael Wrighta9cf4192022-12-01 23:46:39 +000010896 prepareDisplay(ui::ROTATION_0);
HQ Liue6983c72022-04-19 22:14:56 +000010897
10898 prepareAxes(POSITION);
10899 prepareAbsoluteAxisResolution(xAxisResolution, yAxisResolution);
10900 // In order to enable swipe and freeform gesture in pointer mode, pointer capture
10901 // needs to be disabled, and the pointer gesture needs to be enabled.
10902 mFakePolicy->setPointerCapture(false);
10903 mFakePolicy->setPointerGestureEnabled(true);
10904 mFakePolicy->setPointerController(fakePointerController);
10905
10906 float rawDiagonal = hypotf(RAW_X_MAX - RAW_X_MIN, RAW_Y_MAX - RAW_Y_MIN);
10907 float displayDiagonal = hypotf(DISPLAY_WIDTH, DISPLAY_HEIGHT);
10908 mPointerMovementScale =
10909 mFakePolicy->getPointerGestureMovementSpeedRatio() * displayDiagonal / rawDiagonal;
10910 mPointerXZoomScale =
10911 mFakePolicy->getPointerGestureZoomSpeedRatio() * displayDiagonal / rawDiagonal;
10912 }
10913
10914 void prepareAbsoluteAxisResolution(int xAxisResolution, int yAxisResolution) {
10915 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
10916 /*flat*/ 0,
10917 /*fuzz*/ 0, /*resolution*/ xAxisResolution);
10918 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
10919 /*flat*/ 0,
10920 /*fuzz*/ 0, /*resolution*/ yAxisResolution);
10921 }
10922};
10923
10924/**
10925 * Two fingers down on a pointer mode touch pad. The width
10926 * of the two finger is larger than 1/4 of the touch pack diagnal length. However, it
10927 * is smaller than the fixed min physical length 30mm. Two fingers' distance must
10928 * be greater than the both value to be freeform gesture, so that after two
10929 * fingers start to move downwards, the gesture should be swipe.
10930 */
10931TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthSwipe) {
10932 // The min freeform gesture width is 25units/mm x 30mm = 750
10933 // which is greater than fraction of the diagnal length of the touchpad (349).
10934 // Thus, MaxSwipWidth is 750.
Harry Cutts33476232023-01-30 19:57:29 +000010935 preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
Arpit Singha8c236b2023-04-25 13:56:05 +000010936 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
HQ Liue6983c72022-04-19 22:14:56 +000010937 NotifyMotionArgs motionArgs;
10938
10939 // Two fingers down at once.
10940 // The two fingers are 450 units apart, expects the current gesture to be PRESS
10941 // Pointer's initial position is used the [0,0] coordinate.
10942 int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125;
10943
10944 processId(mapper, FIRST_TRACKING_ID);
10945 processPosition(mapper, x1, y1);
10946 processMTSync(mapper);
10947 processId(mapper, SECOND_TRACKING_ID);
10948 processPosition(mapper, x2, y2);
10949 processMTSync(mapper);
10950 processSync(mapper);
10951
10952 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010953 ASSERT_EQ(1U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000010954 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010955 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010956 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010957 ASSERT_NO_FATAL_FAILURE(
10958 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
10959
10960 // It should be recognized as a SWIPE gesture when two fingers start to move down,
10961 // that there should be 1 pointer.
10962 int32_t movingDistance = 200;
10963 y1 += movingDistance;
10964 y2 += movingDistance;
10965
10966 processId(mapper, FIRST_TRACKING_ID);
10967 processPosition(mapper, x1, y1);
10968 processMTSync(mapper);
10969 processId(mapper, SECOND_TRACKING_ID);
10970 processPosition(mapper, x2, y2);
10971 processMTSync(mapper);
10972 processSync(mapper);
10973
10974 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070010975 ASSERT_EQ(1U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000010976 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070010977 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010978 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010979 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
10980 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
10981 0, 0, 0, 0));
10982}
10983
10984/**
10985 * Two fingers down on a pointer mode touch pad. The width of the two finger is larger
10986 * than the minimum freeform gesture width, 30mm. However, it is smaller than 1/4 of
10987 * the touch pack diagnal length. Two fingers' distance must be greater than the both
10988 * value to be freeform gesture, so that after two fingers start to move downwards,
10989 * the gesture should be swipe.
10990 */
10991TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthLowResolutionSwipe) {
10992 // The min freeform gesture width is 5units/mm x 30mm = 150
10993 // which is greater than fraction of the diagnal length of the touchpad (349).
10994 // Thus, MaxSwipWidth is the fraction of the diagnal length, 349.
Harry Cutts33476232023-01-30 19:57:29 +000010995 preparePointerMode(/*xResolution=*/5, /*yResolution=*/5);
Arpit Singha8c236b2023-04-25 13:56:05 +000010996 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
HQ Liue6983c72022-04-19 22:14:56 +000010997 NotifyMotionArgs motionArgs;
10998
10999 // Two fingers down at once.
11000 // The two fingers are 250 units apart, expects the current gesture to be PRESS
11001 // Pointer's initial position is used the [0,0] coordinate.
11002 int32_t x1 = 100, y1 = 125, x2 = 350, y2 = 125;
11003
11004 processId(mapper, FIRST_TRACKING_ID);
11005 processPosition(mapper, x1, y1);
11006 processMTSync(mapper);
11007 processId(mapper, SECOND_TRACKING_ID);
11008 processPosition(mapper, x2, y2);
11009 processMTSync(mapper);
11010 processSync(mapper);
11011
11012 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011013 ASSERT_EQ(1U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011014 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011015 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000011016 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000011017 ASSERT_NO_FATAL_FAILURE(
11018 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
11019
11020 // It should be recognized as a SWIPE gesture when two fingers start to move down,
11021 // and there should be 1 pointer.
11022 int32_t movingDistance = 200;
11023 y1 += movingDistance;
11024 y2 += movingDistance;
11025
11026 processId(mapper, FIRST_TRACKING_ID);
11027 processPosition(mapper, x1, y1);
11028 processMTSync(mapper);
11029 processId(mapper, SECOND_TRACKING_ID);
11030 processPosition(mapper, x2, y2);
11031 processMTSync(mapper);
11032 processSync(mapper);
11033
11034 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011035 ASSERT_EQ(1U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011036 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011037 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000011038 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000011039 // New coordinate is the scaled relative coordinate from the initial coordinate.
11040 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
11041 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
11042 0, 0, 0, 0));
11043}
11044
11045/**
11046 * Touch the touch pad with two fingers with a distance wider than the minimum freeform
11047 * gesture width and 1/4 of the diagnal length of the touchpad. Expect to receive
11048 * freeform gestures after two fingers start to move downwards.
11049 */
11050TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) {
Harry Cutts33476232023-01-30 19:57:29 +000011051 preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
Arpit Singha8c236b2023-04-25 13:56:05 +000011052 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
HQ Liue6983c72022-04-19 22:14:56 +000011053
11054 NotifyMotionArgs motionArgs;
11055
11056 // Two fingers down at once. Wider than the max swipe width.
11057 // The gesture is expected to be PRESS, then transformed to FREEFORM
11058 int32_t x1 = 100, y1 = 125, x2 = 900, y2 = 125;
11059
11060 processId(mapper, FIRST_TRACKING_ID);
11061 processPosition(mapper, x1, y1);
11062 processMTSync(mapper);
11063 processId(mapper, SECOND_TRACKING_ID);
11064 processPosition(mapper, x2, y2);
11065 processMTSync(mapper);
11066 processSync(mapper);
11067
11068 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011069 ASSERT_EQ(1U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011070 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011071 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000011072 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000011073 // One pointer for PRESS, and its coordinate is used as the origin for pointer coordinates.
11074 ASSERT_NO_FATAL_FAILURE(
11075 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
11076
11077 int32_t movingDistance = 200;
11078
11079 // Move two fingers down, expect a cancel event because gesture is changing to freeform,
11080 // then two down events for two pointers.
11081 y1 += movingDistance;
11082 y2 += movingDistance;
11083
11084 processId(mapper, FIRST_TRACKING_ID);
11085 processPosition(mapper, x1, y1);
11086 processMTSync(mapper);
11087 processId(mapper, SECOND_TRACKING_ID);
11088 processPosition(mapper, x2, y2);
11089 processMTSync(mapper);
11090 processSync(mapper);
11091
11092 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
11093 // The previous PRESS gesture is cancelled, because it is transformed to freeform
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011094 ASSERT_EQ(1U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011095 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
11096 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011097 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011098 ASSERT_EQ(1U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011099 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
11100 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011101 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000011102 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011103 ASSERT_EQ(2U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011104 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN, motionArgs.action & AMOTION_EVENT_ACTION_MASK);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011105 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000011106 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000011107 // Two pointers' scaled relative coordinates from their initial centroid.
11108 // Initial y coordinates are 0 as y1 and y2 have the same value.
11109 float cookedX1 = (x1 - x2) / 2 * mPointerXZoomScale;
11110 float cookedX2 = (x2 - x1) / 2 * mPointerXZoomScale;
11111 // When pointers move, the new coordinates equal to the initial coordinates plus
11112 // scaled moving distance.
11113 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
11114 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
11115 0, 0, 0, 0));
11116 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], cookedX2,
11117 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
11118 0, 0, 0, 0));
11119
11120 // Move two fingers down again, expect one MOVE motion event.
11121 y1 += movingDistance;
11122 y2 += movingDistance;
11123
11124 processId(mapper, FIRST_TRACKING_ID);
11125 processPosition(mapper, x1, y1);
11126 processMTSync(mapper);
11127 processId(mapper, SECOND_TRACKING_ID);
11128 processPosition(mapper, x2, y2);
11129 processMTSync(mapper);
11130 processSync(mapper);
11131
11132 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011133 ASSERT_EQ(2U, motionArgs.getPointerCount());
HQ Liue6983c72022-04-19 22:14:56 +000011134 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011135 ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000011136 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000011137 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
11138 movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
11139 0, 0, 0, 0, 0));
11140 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], cookedX2,
11141 movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
11142 0, 0, 0, 0, 0));
11143}
11144
Harry Cutts39b7ca22022-10-05 15:55:48 +000011145TEST_F(MultiTouchPointerModeTest, TwoFingerSwipeOffsets) {
Harry Cutts33476232023-01-30 19:57:29 +000011146 preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
Arpit Singha8c236b2023-04-25 13:56:05 +000011147 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Harry Cutts39b7ca22022-10-05 15:55:48 +000011148 NotifyMotionArgs motionArgs;
11149
11150 // Place two fingers down.
11151 int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125;
11152
11153 processId(mapper, FIRST_TRACKING_ID);
11154 processPosition(mapper, x1, y1);
11155 processMTSync(mapper);
11156 processId(mapper, SECOND_TRACKING_ID);
11157 processPosition(mapper, x2, y2);
11158 processMTSync(mapper);
11159 processSync(mapper);
11160
11161 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011162 ASSERT_EQ(1U, motionArgs.getPointerCount());
Harry Cutts39b7ca22022-10-05 15:55:48 +000011163 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
11164 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
11165 ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET));
11166 ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET));
11167
11168 // Move the two fingers down and to the left.
11169 int32_t movingDistance = 200;
11170 x1 -= movingDistance;
11171 y1 += movingDistance;
11172 x2 -= movingDistance;
11173 y2 += movingDistance;
11174
11175 processId(mapper, FIRST_TRACKING_ID);
11176 processPosition(mapper, x1, y1);
11177 processMTSync(mapper);
11178 processId(mapper, SECOND_TRACKING_ID);
11179 processPosition(mapper, x2, y2);
11180 processMTSync(mapper);
11181 processSync(mapper);
11182
11183 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -070011184 ASSERT_EQ(1U, motionArgs.getPointerCount());
Harry Cutts39b7ca22022-10-05 15:55:48 +000011185 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
11186 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
11187 ASSERT_LT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET), 0);
11188 ASSERT_GT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET), 0);
11189}
11190
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011191TEST_F(MultiTouchPointerModeTest, WhenViewportActiveStatusChanged_PointerGestureIsReset) {
Harry Cutts33476232023-01-30 19:57:29 +000011192 preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011193 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
Arpit Singha8c236b2023-04-25 13:56:05 +000011194 MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011195 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
11196
11197 // Start a stylus gesture.
11198 processKey(mapper, BTN_TOOL_PEN, 1);
11199 processId(mapper, FIRST_TRACKING_ID);
11200 processPosition(mapper, 100, 200);
11201 processSync(mapper);
11202 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11203 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
11204 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011205 WithToolType(ToolType::STYLUS))));
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011206 // TODO(b/257078296): Pointer mode generates extra event.
11207 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11208 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
11209 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011210 WithToolType(ToolType::STYLUS))));
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011211 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
11212
11213 // Make the viewport inactive. This will put the device in disabled mode, and the ongoing stylus
11214 // gesture should be disabled.
11215 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
11216 viewport->isActive = false;
11217 mFakePolicy->updateViewport(*viewport);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +000011218 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011219 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11220 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
11221 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011222 WithToolType(ToolType::STYLUS))));
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011223 // TODO(b/257078296): Pointer mode generates extra event.
11224 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
11225 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
11226 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070011227 WithToolType(ToolType::STYLUS))));
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000011228 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
11229}
11230
Arthur Hung6d5b4b22022-01-21 07:21:10 +000011231// --- JoystickInputMapperTest ---
11232
11233class JoystickInputMapperTest : public InputMapperTest {
11234protected:
11235 static const int32_t RAW_X_MIN;
11236 static const int32_t RAW_X_MAX;
11237 static const int32_t RAW_Y_MIN;
11238 static const int32_t RAW_Y_MAX;
11239
11240 void SetUp() override {
11241 InputMapperTest::SetUp(InputDeviceClass::JOYSTICK | InputDeviceClass::EXTERNAL);
11242 }
11243 void prepareAxes() {
11244 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
11245 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
11246 }
11247
11248 void processAxis(JoystickInputMapper& mapper, int32_t axis, int32_t value) {
11249 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, axis, value);
11250 }
11251
11252 void processSync(JoystickInputMapper& mapper) {
11253 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
11254 }
11255
Michael Wrighta9cf4192022-12-01 23:46:39 +000011256 void prepareVirtualDisplay(ui::Rotation orientation) {
Arthur Hung6d5b4b22022-01-21 07:21:10 +000011257 setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH,
11258 VIRTUAL_DISPLAY_HEIGHT, orientation, VIRTUAL_DISPLAY_UNIQUE_ID,
11259 NO_PORT, ViewportType::VIRTUAL);
11260 }
11261};
11262
11263const int32_t JoystickInputMapperTest::RAW_X_MIN = -32767;
11264const int32_t JoystickInputMapperTest::RAW_X_MAX = 32767;
11265const int32_t JoystickInputMapperTest::RAW_Y_MIN = -32767;
11266const int32_t JoystickInputMapperTest::RAW_Y_MAX = 32767;
11267
11268TEST_F(JoystickInputMapperTest, Configure_AssignsDisplayUniqueId) {
11269 prepareAxes();
Arpit Singhae876352023-04-26 14:16:50 +000011270 JoystickInputMapper& mapper = constructAndAddMapper<JoystickInputMapper>();
Arthur Hung6d5b4b22022-01-21 07:21:10 +000011271
11272 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
11273
Michael Wrighta9cf4192022-12-01 23:46:39 +000011274 prepareVirtualDisplay(ui::ROTATION_0);
Arthur Hung6d5b4b22022-01-21 07:21:10 +000011275
11276 // Send an axis event
11277 processAxis(mapper, ABS_X, 100);
11278 processSync(mapper);
11279
11280 NotifyMotionArgs args;
11281 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11282 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
11283
11284 // Send another axis event
11285 processAxis(mapper, ABS_Y, 100);
11286 processSync(mapper);
11287
11288 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
11289 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
11290}
11291
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011292// --- PeripheralControllerTest ---
Chris Yee2b1e5c2021-03-10 22:45:12 -080011293
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011294class PeripheralControllerTest : public testing::Test {
Chris Yee2b1e5c2021-03-10 22:45:12 -080011295protected:
11296 static const char* DEVICE_NAME;
11297 static const char* DEVICE_LOCATION;
11298 static const int32_t DEVICE_ID;
11299 static const int32_t DEVICE_GENERATION;
11300 static const int32_t DEVICE_CONTROLLER_NUMBER;
Dominik Laskowski2f01d772022-03-23 16:01:29 -070011301 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
Chris Yee2b1e5c2021-03-10 22:45:12 -080011302 static const int32_t EVENTHUB_ID;
11303
11304 std::shared_ptr<FakeEventHub> mFakeEventHub;
11305 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -070011306 std::unique_ptr<TestInputListener> mFakeListener;
Chris Yee2b1e5c2021-03-10 22:45:12 -080011307 std::unique_ptr<InstrumentedInputReader> mReader;
11308 std::shared_ptr<InputDevice> mDevice;
11309
Dominik Laskowski2f01d772022-03-23 16:01:29 -070011310 virtual void SetUp(ftl::Flags<InputDeviceClass> classes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -080011311 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070011312 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -070011313 mFakeListener = std::make_unique<TestInputListener>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080011314 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -070011315 *mFakeListener);
Chris Yee2b1e5c2021-03-10 22:45:12 -080011316 mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes);
11317 }
11318
11319 void SetUp() override { SetUp(DEVICE_CLASSES); }
11320
11321 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -070011322 mFakeListener.reset();
Chris Yee2b1e5c2021-03-10 22:45:12 -080011323 mFakePolicy.clear();
11324 }
11325
Chris Yee2b1e5c2021-03-10 22:45:12 -080011326 std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
11327 const std::string& location, int32_t eventHubId,
Dominik Laskowski2f01d772022-03-23 16:01:29 -070011328 ftl::Flags<InputDeviceClass> classes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -080011329 InputDeviceIdentifier identifier;
11330 identifier.name = name;
11331 identifier.location = location;
11332 std::shared_ptr<InputDevice> device =
11333 std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
11334 identifier);
11335 mReader->pushNextDevice(device);
11336 mFakeEventHub->addDevice(eventHubId, name, classes);
11337 mReader->loopOnce();
11338 return device;
11339 }
11340
11341 template <class T, typename... Args>
11342 T& addControllerAndConfigure(Args... args) {
11343 T& controller = mDevice->addController<T>(EVENTHUB_ID, args...);
11344
11345 return controller;
11346 }
11347};
11348
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011349const char* PeripheralControllerTest::DEVICE_NAME = "device";
11350const char* PeripheralControllerTest::DEVICE_LOCATION = "BLUETOOTH";
11351const int32_t PeripheralControllerTest::DEVICE_ID = END_RESERVED_ID + 1000;
11352const int32_t PeripheralControllerTest::DEVICE_GENERATION = 2;
11353const int32_t PeripheralControllerTest::DEVICE_CONTROLLER_NUMBER = 0;
Dominik Laskowski2f01d772022-03-23 16:01:29 -070011354const ftl::Flags<InputDeviceClass> PeripheralControllerTest::DEVICE_CLASSES =
11355 ftl::Flags<InputDeviceClass>(0); // not needed for current tests
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011356const int32_t PeripheralControllerTest::EVENTHUB_ID = 1;
Chris Yee2b1e5c2021-03-10 22:45:12 -080011357
11358// --- BatteryControllerTest ---
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011359class BatteryControllerTest : public PeripheralControllerTest {
Chris Yee2b1e5c2021-03-10 22:45:12 -080011360protected:
11361 void SetUp() override {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011362 PeripheralControllerTest::SetUp(DEVICE_CLASSES | InputDeviceClass::BATTERY);
Chris Yee2b1e5c2021-03-10 22:45:12 -080011363 }
11364};
11365
11366TEST_F(BatteryControllerTest, GetBatteryCapacity) {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011367 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080011368
Harry Cuttsa5b71292022-11-28 12:56:17 +000011369 ASSERT_TRUE(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY));
11370 ASSERT_EQ(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY).value_or(-1),
11371 FakeEventHub::BATTERY_CAPACITY);
Chris Yee2b1e5c2021-03-10 22:45:12 -080011372}
11373
11374TEST_F(BatteryControllerTest, GetBatteryStatus) {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011375 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080011376
Harry Cuttsa5b71292022-11-28 12:56:17 +000011377 ASSERT_TRUE(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY));
11378 ASSERT_EQ(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY).value_or(-1),
11379 FakeEventHub::BATTERY_STATUS);
Chris Yee2b1e5c2021-03-10 22:45:12 -080011380}
11381
11382// --- LightControllerTest ---
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011383class LightControllerTest : public PeripheralControllerTest {
Chris Yee2b1e5c2021-03-10 22:45:12 -080011384protected:
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011385 void SetUp() override {
11386 PeripheralControllerTest::SetUp(DEVICE_CLASSES | InputDeviceClass::LIGHT);
11387 }
Chris Yee2b1e5c2021-03-10 22:45:12 -080011388};
11389
Chris Ye85758332021-05-16 23:05:17 -070011390TEST_F(LightControllerTest, MonoLight) {
11391 RawLightInfo infoMono = {.id = 1,
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000011392 .name = "mono_light",
Chris Ye85758332021-05-16 23:05:17 -070011393 .maxBrightness = 255,
11394 .flags = InputLightClass::BRIGHTNESS,
11395 .path = ""};
11396 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
Chris Yee2b1e5c2021-03-10 22:45:12 -080011397
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011398 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080011399 InputDeviceInfo info;
11400 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000011401 std::vector<InputDeviceLightInfo> lights = info.getLights();
11402 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000011403 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
11404 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
11405
11406 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_BRIGHTNESS));
11407 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
11408}
11409
11410TEST_F(LightControllerTest, MonoKeyboardBacklight) {
11411 RawLightInfo infoMono = {.id = 1,
11412 .name = "mono_keyboard_backlight",
11413 .maxBrightness = 255,
11414 .flags = InputLightClass::BRIGHTNESS |
11415 InputLightClass::KEYBOARD_BACKLIGHT,
11416 .path = ""};
11417 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
11418
11419 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
11420 InputDeviceInfo info;
11421 controller.populateDeviceInfo(&info);
11422 std::vector<InputDeviceLightInfo> lights = info.getLights();
11423 ASSERT_EQ(1U, lights.size());
11424 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
11425 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
Chris Yee2b1e5c2021-03-10 22:45:12 -080011426
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000011427 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_BRIGHTNESS));
11428 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
Chris Yee2b1e5c2021-03-10 22:45:12 -080011429}
11430
Vaibhav Devmurari16c24192023-05-04 15:20:12 +000011431TEST_F(LightControllerTest, Ignore_MonoLight_WithPreferredBacklightLevels) {
11432 RawLightInfo infoMono = {.id = 1,
11433 .name = "mono_light",
11434 .maxBrightness = 255,
11435 .flags = InputLightClass::BRIGHTNESS,
11436 .path = ""};
11437 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
11438 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "keyboard.backlight.brightnessLevels",
11439 "0,100,200");
11440
11441 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
11442 std::list<NotifyArgs> unused =
11443 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
11444 /*changes=*/{});
11445
11446 InputDeviceInfo info;
11447 controller.populateDeviceInfo(&info);
11448 std::vector<InputDeviceLightInfo> lights = info.getLights();
11449 ASSERT_EQ(1U, lights.size());
11450 ASSERT_EQ(0U, lights[0].preferredBrightnessLevels.size());
11451}
11452
11453TEST_F(LightControllerTest, KeyboardBacklight_WithNoPreferredBacklightLevels) {
11454 RawLightInfo infoMono = {.id = 1,
11455 .name = "mono_keyboard_backlight",
11456 .maxBrightness = 255,
11457 .flags = InputLightClass::BRIGHTNESS |
11458 InputLightClass::KEYBOARD_BACKLIGHT,
11459 .path = ""};
11460 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
11461
11462 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
11463 std::list<NotifyArgs> unused =
11464 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
11465 /*changes=*/{});
11466
11467 InputDeviceInfo info;
11468 controller.populateDeviceInfo(&info);
11469 std::vector<InputDeviceLightInfo> lights = info.getLights();
11470 ASSERT_EQ(1U, lights.size());
11471 ASSERT_EQ(0U, lights[0].preferredBrightnessLevels.size());
11472}
11473
11474TEST_F(LightControllerTest, KeyboardBacklight_WithPreferredBacklightLevels) {
11475 RawLightInfo infoMono = {.id = 1,
11476 .name = "mono_keyboard_backlight",
11477 .maxBrightness = 255,
11478 .flags = InputLightClass::BRIGHTNESS |
11479 InputLightClass::KEYBOARD_BACKLIGHT,
11480 .path = ""};
11481 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
11482 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "keyboard.backlight.brightnessLevels",
11483 "0,100,200");
11484
11485 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
11486 std::list<NotifyArgs> unused =
11487 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
11488 /*changes=*/{});
11489
11490 InputDeviceInfo info;
11491 controller.populateDeviceInfo(&info);
11492 std::vector<InputDeviceLightInfo> lights = info.getLights();
11493 ASSERT_EQ(1U, lights.size());
11494 ASSERT_EQ(3U, lights[0].preferredBrightnessLevels.size());
11495 std::set<BrightnessLevel>::iterator it = lights[0].preferredBrightnessLevels.begin();
11496 ASSERT_EQ(BrightnessLevel(0), *it);
11497 std::advance(it, 1);
11498 ASSERT_EQ(BrightnessLevel(100), *it);
11499 std::advance(it, 1);
11500 ASSERT_EQ(BrightnessLevel(200), *it);
11501}
11502
11503TEST_F(LightControllerTest, KeyboardBacklight_WithWrongPreferredBacklightLevels) {
11504 RawLightInfo infoMono = {.id = 1,
11505 .name = "mono_keyboard_backlight",
11506 .maxBrightness = 255,
11507 .flags = InputLightClass::BRIGHTNESS |
11508 InputLightClass::KEYBOARD_BACKLIGHT,
11509 .path = ""};
11510 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
11511 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "keyboard.backlight.brightnessLevels",
11512 "0,100,200,300,400,500");
11513
11514 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
11515 std::list<NotifyArgs> unused =
11516 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
11517 /*changes=*/{});
11518
11519 InputDeviceInfo info;
11520 controller.populateDeviceInfo(&info);
11521 std::vector<InputDeviceLightInfo> lights = info.getLights();
11522 ASSERT_EQ(1U, lights.size());
11523 ASSERT_EQ(0U, lights[0].preferredBrightnessLevels.size());
11524}
11525
Chris Yee2b1e5c2021-03-10 22:45:12 -080011526TEST_F(LightControllerTest, RGBLight) {
11527 RawLightInfo infoRed = {.id = 1,
11528 .name = "red",
11529 .maxBrightness = 255,
11530 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED,
11531 .path = ""};
11532 RawLightInfo infoGreen = {.id = 2,
11533 .name = "green",
11534 .maxBrightness = 255,
11535 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN,
11536 .path = ""};
11537 RawLightInfo infoBlue = {.id = 3,
11538 .name = "blue",
11539 .maxBrightness = 255,
11540 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE,
11541 .path = ""};
11542 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
11543 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
11544 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
11545
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011546 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080011547 InputDeviceInfo info;
11548 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000011549 std::vector<InputDeviceLightInfo> lights = info.getLights();
11550 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000011551 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
11552 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
11553 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
11554
11555 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
11556 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
11557}
11558
11559TEST_F(LightControllerTest, CorrectRGBKeyboardBacklight) {
11560 RawLightInfo infoRed = {.id = 1,
11561 .name = "red_keyboard_backlight",
11562 .maxBrightness = 255,
11563 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED |
11564 InputLightClass::KEYBOARD_BACKLIGHT,
11565 .path = ""};
11566 RawLightInfo infoGreen = {.id = 2,
11567 .name = "green_keyboard_backlight",
11568 .maxBrightness = 255,
11569 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN |
11570 InputLightClass::KEYBOARD_BACKLIGHT,
11571 .path = ""};
11572 RawLightInfo infoBlue = {.id = 3,
11573 .name = "blue_keyboard_backlight",
11574 .maxBrightness = 255,
11575 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE |
11576 InputLightClass::KEYBOARD_BACKLIGHT,
11577 .path = ""};
11578 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
11579 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
11580 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
11581
11582 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
11583 InputDeviceInfo info;
11584 controller.populateDeviceInfo(&info);
11585 std::vector<InputDeviceLightInfo> lights = info.getLights();
11586 ASSERT_EQ(1U, lights.size());
11587 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
11588 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
11589 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
11590
11591 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
11592 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
11593}
11594
11595TEST_F(LightControllerTest, IncorrectRGBKeyboardBacklight) {
11596 RawLightInfo infoRed = {.id = 1,
11597 .name = "red",
11598 .maxBrightness = 255,
11599 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED,
11600 .path = ""};
11601 RawLightInfo infoGreen = {.id = 2,
11602 .name = "green",
11603 .maxBrightness = 255,
11604 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN,
11605 .path = ""};
11606 RawLightInfo infoBlue = {.id = 3,
11607 .name = "blue",
11608 .maxBrightness = 255,
11609 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE,
11610 .path = ""};
11611 RawLightInfo infoGlobal = {.id = 3,
11612 .name = "global_keyboard_backlight",
11613 .maxBrightness = 255,
11614 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GLOBAL |
11615 InputLightClass::KEYBOARD_BACKLIGHT,
11616 .path = ""};
11617 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
11618 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
11619 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
11620 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoGlobal));
11621
11622 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
11623 InputDeviceInfo info;
11624 controller.populateDeviceInfo(&info);
11625 std::vector<InputDeviceLightInfo> lights = info.getLights();
11626 ASSERT_EQ(1U, lights.size());
11627 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
11628 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
11629 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080011630
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000011631 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
11632 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
Chris Yee2b1e5c2021-03-10 22:45:12 -080011633}
11634
11635TEST_F(LightControllerTest, MultiColorRGBLight) {
11636 RawLightInfo infoColor = {.id = 1,
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000011637 .name = "multi_color",
Chris Yee2b1e5c2021-03-10 22:45:12 -080011638 .maxBrightness = 255,
11639 .flags = InputLightClass::BRIGHTNESS |
11640 InputLightClass::MULTI_INTENSITY |
11641 InputLightClass::MULTI_INDEX,
11642 .path = ""};
11643
11644 mFakeEventHub->addRawLightInfo(infoColor.id, std::move(infoColor));
11645
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011646 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080011647 InputDeviceInfo info;
11648 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000011649 std::vector<InputDeviceLightInfo> lights = info.getLights();
11650 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000011651 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
11652 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
11653 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
11654
11655 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
11656 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
11657}
11658
11659TEST_F(LightControllerTest, MultiColorRGBKeyboardBacklight) {
11660 RawLightInfo infoColor = {.id = 1,
11661 .name = "multi_color_keyboard_backlight",
11662 .maxBrightness = 255,
11663 .flags = InputLightClass::BRIGHTNESS |
11664 InputLightClass::MULTI_INTENSITY |
11665 InputLightClass::MULTI_INDEX |
11666 InputLightClass::KEYBOARD_BACKLIGHT,
11667 .path = ""};
11668
11669 mFakeEventHub->addRawLightInfo(infoColor.id, std::move(infoColor));
11670
11671 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
11672 InputDeviceInfo info;
11673 controller.populateDeviceInfo(&info);
11674 std::vector<InputDeviceLightInfo> lights = info.getLights();
11675 ASSERT_EQ(1U, lights.size());
11676 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
11677 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
11678 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080011679
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000011680 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
11681 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
Chris Yee2b1e5c2021-03-10 22:45:12 -080011682}
11683
11684TEST_F(LightControllerTest, PlayerIdLight) {
11685 RawLightInfo info1 = {.id = 1,
11686 .name = "player1",
11687 .maxBrightness = 255,
11688 .flags = InputLightClass::BRIGHTNESS,
11689 .path = ""};
11690 RawLightInfo info2 = {.id = 2,
11691 .name = "player2",
11692 .maxBrightness = 255,
11693 .flags = InputLightClass::BRIGHTNESS,
11694 .path = ""};
11695 RawLightInfo info3 = {.id = 3,
11696 .name = "player3",
11697 .maxBrightness = 255,
11698 .flags = InputLightClass::BRIGHTNESS,
11699 .path = ""};
11700 RawLightInfo info4 = {.id = 4,
11701 .name = "player4",
11702 .maxBrightness = 255,
11703 .flags = InputLightClass::BRIGHTNESS,
11704 .path = ""};
11705 mFakeEventHub->addRawLightInfo(info1.id, std::move(info1));
11706 mFakeEventHub->addRawLightInfo(info2.id, std::move(info2));
11707 mFakeEventHub->addRawLightInfo(info3.id, std::move(info3));
11708 mFakeEventHub->addRawLightInfo(info4.id, std::move(info4));
11709
Chris Ye1dd2e5c2021-04-04 23:12:41 -070011710 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080011711 InputDeviceInfo info;
11712 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000011713 std::vector<InputDeviceLightInfo> lights = info.getLights();
11714 ASSERT_EQ(1U, lights.size());
11715 ASSERT_EQ(InputDeviceLightType::PLAYER_ID, lights[0].type);
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000011716 ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
11717 ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080011718
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000011719 ASSERT_FALSE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
11720 ASSERT_TRUE(controller.setLightPlayerId(lights[0].id, LIGHT_PLAYER_ID));
11721 ASSERT_EQ(controller.getLightPlayerId(lights[0].id).value_or(-1), LIGHT_PLAYER_ID);
Chris Yee2b1e5c2021-03-10 22:45:12 -080011722}
11723
Michael Wrightd02c5b62014-02-10 15:10:22 -080011724} // namespace android