blob: 58f1e1e035d79bacffb9ab5df30c9fadd8d0faa8 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dominik Laskowski2f01d772022-03-23 16:01:29 -070017#include <cinttypes>
18#include <memory>
19
Prabir Pradhan2770d242019-09-02 18:07:11 -070020#include <CursorInputMapper.h>
21#include <InputDevice.h>
22#include <InputMapper.h>
23#include <InputReader.h>
Prabir Pradhan1aed8582019-12-30 11:46:51 -080024#include <InputReaderBase.h>
25#include <InputReaderFactory.h>
Arthur Hung6d5b4b22022-01-21 07:21:10 +000026#include <JoystickInputMapper.h>
Prabir Pradhan2770d242019-09-02 18:07:11 -070027#include <KeyboardInputMapper.h>
28#include <MultiTouchInputMapper.h>
Chris Ye1dd2e5c2021-04-04 23:12:41 -070029#include <PeripheralController.h>
Chris Yef59a2f42020-10-16 12:55:26 -070030#include <SensorInputMapper.h>
Prabir Pradhan2770d242019-09-02 18:07:11 -070031#include <SingleTouchInputMapper.h>
32#include <SwitchInputMapper.h>
33#include <TestInputListener.h>
Prabir Pradhan739dca42022-09-09 20:12:01 +000034#include <TestInputListenerMatchers.h>
Prabir Pradhan2770d242019-09-02 18:07:11 -070035#include <TouchInputMapper.h>
Prabir Pradhan1aed8582019-12-30 11:46:51 -080036#include <UinputDevice.h>
Chris Ye87143712020-11-10 05:05:58 +000037#include <VibratorInputMapper.h>
Prabir Pradhan2574dfa2019-10-16 16:35:07 -070038#include <android-base/thread_annotations.h>
Michael Wrighta9cf4192022-12-01 23:46:39 +000039#include <ftl/enum.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080040#include <gtest/gtest.h>
chaviw3277faf2021-05-19 16:45:23 -050041#include <gui/constants.h>
Michael Wrighta9cf4192022-12-01 23:46:39 +000042#include <ui/Rotation.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080043
Siarhei Vishniakou21e96e62022-10-27 10:23:37 -070044#include <thread>
Harry Cuttsa5b71292022-11-28 12:56:17 +000045#include "FakeEventHub.h"
Harry Cutts6b5fbc52022-11-28 16:37:43 +000046#include "FakeInputReaderPolicy.h"
Harry Cuttsb57f1702022-11-28 15:34:22 +000047#include "FakePointerController.h"
Harry Cutts144ff542022-11-28 17:41:06 +000048#include "InstrumentedInputReader.h"
Harry Cuttsa5b71292022-11-28 12:56:17 +000049#include "TestConstants.h"
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +000050#include "android/hardware/input/InputDeviceCountryCode.h"
Michael Wrightdde67b82020-10-27 16:09:22 +000051#include "input/DisplayViewport.h"
52#include "input/Input.h"
Michael Wright17db18e2020-06-26 20:51:44 +010053
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +000054using android::hardware::input::InputDeviceCountryCode;
55
Michael Wrightd02c5b62014-02-10 15:10:22 -080056namespace android {
57
Dominik Laskowski2f01d772022-03-23 16:01:29 -070058using namespace ftl::flag_operators;
Prabir Pradhan739dca42022-09-09 20:12:01 +000059using testing::AllOf;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -070060using std::chrono_literals::operator""ms;
61
Michael Wrightd02c5b62014-02-10 15:10:22 -080062// Arbitrary display properties.
arthurhungcc7f9802020-04-30 17:55:40 +080063static constexpr int32_t DISPLAY_ID = 0;
Prabir Pradhanc13ff082022-09-08 22:03:30 +000064static const std::string DISPLAY_UNIQUE_ID = "local:1";
arthurhungcc7f9802020-04-30 17:55:40 +080065static constexpr int32_t SECONDARY_DISPLAY_ID = DISPLAY_ID + 1;
Prabir Pradhanc13ff082022-09-08 22:03:30 +000066static const std::string SECONDARY_DISPLAY_UNIQUE_ID = "local:2";
arthurhungcc7f9802020-04-30 17:55:40 +080067static constexpr int32_t DISPLAY_WIDTH = 480;
68static constexpr int32_t DISPLAY_HEIGHT = 800;
69static constexpr int32_t VIRTUAL_DISPLAY_ID = 1;
70static constexpr int32_t VIRTUAL_DISPLAY_WIDTH = 400;
71static constexpr int32_t VIRTUAL_DISPLAY_HEIGHT = 500;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -070072static const char* VIRTUAL_DISPLAY_UNIQUE_ID = "virtual:1";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -070073static constexpr std::optional<uint8_t> NO_PORT = std::nullopt; // no physical port is specified
Michael Wrightd02c5b62014-02-10 15:10:22 -080074
arthurhungcc7f9802020-04-30 17:55:40 +080075static constexpr int32_t FIRST_SLOT = 0;
76static constexpr int32_t SECOND_SLOT = 1;
77static constexpr int32_t THIRD_SLOT = 2;
78static constexpr int32_t INVALID_TRACKING_ID = -1;
79static constexpr int32_t FIRST_TRACKING_ID = 0;
80static constexpr int32_t SECOND_TRACKING_ID = 1;
81static constexpr int32_t THIRD_TRACKING_ID = 2;
Chris Ye3fdbfef2021-01-06 18:45:18 -080082static constexpr int32_t LIGHT_BRIGHTNESS = 0x55000000;
83static constexpr int32_t LIGHT_COLOR = 0x7F448866;
84static constexpr int32_t LIGHT_PLAYER_ID = 2;
arthurhungcc7f9802020-04-30 17:55:40 +080085
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080086static constexpr int32_t ACTION_POINTER_0_DOWN =
87 AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
88static constexpr int32_t ACTION_POINTER_0_UP =
89 AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
90static constexpr int32_t ACTION_POINTER_1_DOWN =
91 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
92static constexpr int32_t ACTION_POINTER_1_UP =
93 AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
94
Michael Wrightd02c5b62014-02-10 15:10:22 -080095// Error tolerance for floating point assertions.
96static const float EPSILON = 0.001f;
97
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +000098// Minimum timestamp separation between subsequent input events from a Bluetooth device.
99static constexpr nsecs_t MIN_BLUETOOTH_TIMESTAMP_DELTA = ms2ns(4);
100// Maximum smoothing time delta so that we don't generate events too far into the future.
101constexpr static nsecs_t MAX_BLUETOOTH_SMOOTHING_DELTA = ms2ns(32);
102
Michael Wrightd02c5b62014-02-10 15:10:22 -0800103template<typename T>
104static inline T min(T a, T b) {
105 return a < b ? a : b;
106}
107
108static inline float avg(float x, float y) {
109 return (x + y) / 2;
110}
111
Chris Ye3fdbfef2021-01-06 18:45:18 -0800112// Mapping for light color name and the light color
113const std::unordered_map<std::string, LightColor> LIGHT_COLORS = {{"red", LightColor::RED},
114 {"green", LightColor::GREEN},
115 {"blue", LightColor::BLUE}};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800116
Michael Wrighta9cf4192022-12-01 23:46:39 +0000117static ui::Rotation getInverseRotation(ui::Rotation orientation) {
Prabir Pradhanc14266f2021-05-12 15:56:24 -0700118 switch (orientation) {
Michael Wrighta9cf4192022-12-01 23:46:39 +0000119 case ui::ROTATION_90:
120 return ui::ROTATION_270;
121 case ui::ROTATION_270:
122 return ui::ROTATION_90;
Prabir Pradhanc14266f2021-05-12 15:56:24 -0700123 default:
124 return orientation;
125 }
126}
127
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800128static void assertAxisResolution(MultiTouchInputMapper& mapper, int axis, float resolution) {
129 InputDeviceInfo info;
130 mapper.populateDeviceInfo(&info);
131
132 const InputDeviceInfo::MotionRange* motionRange =
133 info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
134 ASSERT_NEAR(motionRange->resolution, resolution, EPSILON);
135}
136
137static void assertAxisNotPresent(MultiTouchInputMapper& mapper, int axis) {
138 InputDeviceInfo info;
139 mapper.populateDeviceInfo(&info);
140
141 const InputDeviceInfo::MotionRange* motionRange =
142 info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
143 ASSERT_EQ(nullptr, motionRange);
144}
145
Siarhei Vishniakou21e96e62022-10-27 10:23:37 -0700146[[maybe_unused]] static void dumpReader(InputReader& reader) {
147 std::string dump;
148 reader.dump(dump);
149 std::istringstream iss(dump);
150 for (std::string line; std::getline(iss, line);) {
151 ALOGE("%s", line.c_str());
152 std::this_thread::sleep_for(std::chrono::milliseconds(1));
153 }
154}
155
Michael Wrightd02c5b62014-02-10 15:10:22 -0800156// --- FakeInputMapper ---
157
158class FakeInputMapper : public InputMapper {
159 uint32_t mSources;
160 int32_t mKeyboardType;
161 int32_t mMetaState;
162 KeyedVector<int32_t, int32_t> mKeyCodeStates;
163 KeyedVector<int32_t, int32_t> mScanCodeStates;
164 KeyedVector<int32_t, int32_t> mSwitchStates;
Philip Junker4af3b3d2021-12-14 10:36:55 +0100165 // fake mapping which would normally come from keyCharacterMap
166 std::unordered_map<int32_t, int32_t> mKeyCodeMapping;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800167 std::vector<int32_t> mSupportedKeyCodes;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800168
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700169 std::mutex mLock;
170 std::condition_variable mStateChangedCondition;
171 bool mConfigureWasCalled GUARDED_BY(mLock);
172 bool mResetWasCalled GUARDED_BY(mLock);
173 bool mProcessWasCalled GUARDED_BY(mLock);
174 RawEvent mLastEvent GUARDED_BY(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800175
Arthur Hungc23540e2018-11-29 20:42:11 +0800176 std::optional<DisplayViewport> mViewport;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800177public:
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800178 FakeInputMapper(InputDeviceContext& deviceContext, uint32_t sources)
179 : InputMapper(deviceContext),
180 mSources(sources),
181 mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
Michael Wrightd02c5b62014-02-10 15:10:22 -0800182 mMetaState(0),
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800183 mConfigureWasCalled(false),
184 mResetWasCalled(false),
185 mProcessWasCalled(false) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800186
Chris Yea52ade12020-08-27 16:49:20 -0700187 virtual ~FakeInputMapper() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800188
189 void setKeyboardType(int32_t keyboardType) {
190 mKeyboardType = keyboardType;
191 }
192
193 void setMetaState(int32_t metaState) {
194 mMetaState = metaState;
195 }
196
197 void assertConfigureWasCalled() {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700198 std::unique_lock<std::mutex> lock(mLock);
199 base::ScopedLockAssertion assumeLocked(mLock);
200 const bool configureCalled =
201 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
202 return mConfigureWasCalled;
203 });
204 if (!configureCalled) {
205 FAIL() << "Expected configure() to have been called.";
206 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800207 mConfigureWasCalled = false;
208 }
209
210 void assertResetWasCalled() {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700211 std::unique_lock<std::mutex> lock(mLock);
212 base::ScopedLockAssertion assumeLocked(mLock);
213 const bool resetCalled =
214 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
215 return mResetWasCalled;
216 });
217 if (!resetCalled) {
218 FAIL() << "Expected reset() to have been called.";
219 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800220 mResetWasCalled = false;
221 }
222
Yi Kong9b14ac62018-07-17 13:48:38 -0700223 void assertProcessWasCalled(RawEvent* outLastEvent = nullptr) {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700224 std::unique_lock<std::mutex> lock(mLock);
225 base::ScopedLockAssertion assumeLocked(mLock);
226 const bool processCalled =
227 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
228 return mProcessWasCalled;
229 });
230 if (!processCalled) {
231 FAIL() << "Expected process() to have been called.";
232 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800233 if (outLastEvent) {
234 *outLastEvent = mLastEvent;
235 }
236 mProcessWasCalled = false;
237 }
238
239 void setKeyCodeState(int32_t keyCode, int32_t state) {
240 mKeyCodeStates.replaceValueFor(keyCode, state);
241 }
242
243 void setScanCodeState(int32_t scanCode, int32_t state) {
244 mScanCodeStates.replaceValueFor(scanCode, state);
245 }
246
247 void setSwitchState(int32_t switchCode, int32_t state) {
248 mSwitchStates.replaceValueFor(switchCode, state);
249 }
250
251 void addSupportedKeyCode(int32_t keyCode) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800252 mSupportedKeyCodes.push_back(keyCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800253 }
254
Philip Junker4af3b3d2021-12-14 10:36:55 +0100255 void addKeyCodeMapping(int32_t fromKeyCode, int32_t toKeyCode) {
256 mKeyCodeMapping.insert_or_assign(fromKeyCode, toKeyCode);
257 }
258
Michael Wrightd02c5b62014-02-10 15:10:22 -0800259private:
Philip Junker4af3b3d2021-12-14 10:36:55 +0100260 uint32_t getSources() const override { return mSources; }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800261
Chris Yea52ade12020-08-27 16:49:20 -0700262 void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800263 InputMapper::populateDeviceInfo(deviceInfo);
264
265 if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) {
266 deviceInfo->setKeyboardType(mKeyboardType);
267 }
268 }
269
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700270 std::list<NotifyArgs> configure(nsecs_t, const InputReaderConfiguration* config,
271 uint32_t changes) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700272 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800273 mConfigureWasCalled = true;
Arthur Hungc23540e2018-11-29 20:42:11 +0800274
275 // Find the associated viewport if exist.
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800276 const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
Arthur Hungc23540e2018-11-29 20:42:11 +0800277 if (displayPort && (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
278 mViewport = config->getDisplayViewportByPort(*displayPort);
279 }
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700280
281 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700282 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800283 }
284
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700285 std::list<NotifyArgs> reset(nsecs_t) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700286 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800287 mResetWasCalled = true;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700288 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700289 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800290 }
291
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700292 std::list<NotifyArgs> process(const RawEvent* rawEvent) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700293 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800294 mLastEvent = *rawEvent;
295 mProcessWasCalled = true;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700296 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700297 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800298 }
299
Chris Yea52ade12020-08-27 16:49:20 -0700300 int32_t getKeyCodeState(uint32_t, int32_t keyCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800301 ssize_t index = mKeyCodeStates.indexOfKey(keyCode);
302 return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
303 }
304
Philip Junker4af3b3d2021-12-14 10:36:55 +0100305 int32_t getKeyCodeForKeyLocation(int32_t locationKeyCode) const override {
306 auto it = mKeyCodeMapping.find(locationKeyCode);
307 return it != mKeyCodeMapping.end() ? it->second : locationKeyCode;
308 }
309
Chris Yea52ade12020-08-27 16:49:20 -0700310 int32_t getScanCodeState(uint32_t, int32_t scanCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800311 ssize_t index = mScanCodeStates.indexOfKey(scanCode);
312 return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
313 }
314
Chris Yea52ade12020-08-27 16:49:20 -0700315 int32_t getSwitchState(uint32_t, int32_t switchCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800316 ssize_t index = mSwitchStates.indexOfKey(switchCode);
317 return index >= 0 ? mSwitchStates.valueAt(index) : AKEY_STATE_UNKNOWN;
318 }
319
Chris Yea52ade12020-08-27 16:49:20 -0700320 // Return true if the device has non-empty key layout.
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700321 bool markSupportedKeyCodes(uint32_t, const std::vector<int32_t>& keyCodes,
Chris Yea52ade12020-08-27 16:49:20 -0700322 uint8_t* outFlags) override {
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700323 for (size_t i = 0; i < keyCodes.size(); i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800324 for (size_t j = 0; j < mSupportedKeyCodes.size(); j++) {
325 if (keyCodes[i] == mSupportedKeyCodes[j]) {
326 outFlags[i] = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800327 }
328 }
329 }
Chris Yea52ade12020-08-27 16:49:20 -0700330 bool result = mSupportedKeyCodes.size() > 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800331 return result;
332 }
333
334 virtual int32_t getMetaState() {
335 return mMetaState;
336 }
337
338 virtual void fadePointer() {
339 }
Arthur Hungc23540e2018-11-29 20:42:11 +0800340
341 virtual std::optional<int32_t> getAssociatedDisplay() {
342 if (mViewport) {
343 return std::make_optional(mViewport->displayId);
344 }
345 return std::nullopt;
346 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800347};
348
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700349// --- InputReaderPolicyTest ---
350class InputReaderPolicyTest : public testing::Test {
Siarhei Vishniakoucd7ac1e2018-10-15 13:39:50 -0700351protected:
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700352 sp<FakeInputReaderPolicy> mFakePolicy;
353
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700354 void SetUp() override { mFakePolicy = sp<FakeInputReaderPolicy>::make(); }
Chris Yea52ade12020-08-27 16:49:20 -0700355 void TearDown() override { mFakePolicy.clear(); }
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700356};
357
358/**
359 * Check that empty set of viewports is an acceptable configuration.
360 * Also try to get internal viewport two different ways - by type and by uniqueId.
361 *
362 * There will be confusion if two viewports with empty uniqueId and identical type are present.
363 * Such configuration is not currently allowed.
364 */
365TEST_F(InputReaderPolicyTest, Viewports_GetCleared) {
Siarhei Vishniakoucd7ac1e2018-10-15 13:39:50 -0700366 static const std::string uniqueId = "local:0";
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700367
368 // We didn't add any viewports yet, so there shouldn't be any.
369 std::optional<DisplayViewport> internalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100370 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700371 ASSERT_FALSE(internalViewport);
372
373 // Add an internal viewport, then clear it
Michael Wrighta9cf4192022-12-01 23:46:39 +0000374 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
375 true /*isActive*/, uniqueId, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700376
377 // Check matching by uniqueId
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700378 internalViewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700379 ASSERT_TRUE(internalViewport);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100380 ASSERT_EQ(ViewportType::INTERNAL, internalViewport->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700381
382 // Check matching by viewport type
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100383 internalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700384 ASSERT_TRUE(internalViewport);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700385 ASSERT_EQ(uniqueId, internalViewport->uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700386
387 mFakePolicy->clearViewports();
388 // Make sure nothing is found after clear
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700389 internalViewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700390 ASSERT_FALSE(internalViewport);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100391 internalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700392 ASSERT_FALSE(internalViewport);
393}
394
395TEST_F(InputReaderPolicyTest, Viewports_GetByType) {
396 const std::string internalUniqueId = "local:0";
397 const std::string externalUniqueId = "local:1";
398 const std::string virtualUniqueId1 = "virtual:2";
399 const std::string virtualUniqueId2 = "virtual:3";
400 constexpr int32_t virtualDisplayId1 = 2;
401 constexpr int32_t virtualDisplayId2 = 3;
402
403 // Add an internal viewport
Michael Wrighta9cf4192022-12-01 23:46:39 +0000404 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
405 true /*isActive*/, internalUniqueId, NO_PORT,
406 ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700407 // Add an external viewport
Michael Wrighta9cf4192022-12-01 23:46:39 +0000408 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
409 true /*isActive*/, externalUniqueId, NO_PORT,
410 ViewportType::EXTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700411 // Add an virtual viewport
412 mFakePolicy->addDisplayViewport(virtualDisplayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000413 ui::ROTATION_0, true /*isActive*/, virtualUniqueId1, NO_PORT,
414 ViewportType::VIRTUAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700415 // Add another virtual viewport
416 mFakePolicy->addDisplayViewport(virtualDisplayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000417 ui::ROTATION_0, true /*isActive*/, virtualUniqueId2, NO_PORT,
418 ViewportType::VIRTUAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700419
420 // Check matching by type for internal
421 std::optional<DisplayViewport> internalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100422 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700423 ASSERT_TRUE(internalViewport);
424 ASSERT_EQ(internalUniqueId, internalViewport->uniqueId);
425
426 // Check matching by type for external
427 std::optional<DisplayViewport> externalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100428 mFakePolicy->getDisplayViewportByType(ViewportType::EXTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700429 ASSERT_TRUE(externalViewport);
430 ASSERT_EQ(externalUniqueId, externalViewport->uniqueId);
431
432 // Check matching by uniqueId for virtual viewport #1
433 std::optional<DisplayViewport> virtualViewport1 =
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700434 mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId1);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700435 ASSERT_TRUE(virtualViewport1);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100436 ASSERT_EQ(ViewportType::VIRTUAL, virtualViewport1->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700437 ASSERT_EQ(virtualUniqueId1, virtualViewport1->uniqueId);
438 ASSERT_EQ(virtualDisplayId1, virtualViewport1->displayId);
439
440 // Check matching by uniqueId for virtual viewport #2
441 std::optional<DisplayViewport> virtualViewport2 =
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700442 mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId2);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700443 ASSERT_TRUE(virtualViewport2);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100444 ASSERT_EQ(ViewportType::VIRTUAL, virtualViewport2->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700445 ASSERT_EQ(virtualUniqueId2, virtualViewport2->uniqueId);
446 ASSERT_EQ(virtualDisplayId2, virtualViewport2->displayId);
447}
448
449
450/**
451 * We can have 2 viewports of the same kind. We can distinguish them by uniqueId, and confirm
452 * that lookup works by checking display id.
453 * Check that 2 viewports of each kind is possible, for all existing viewport types.
454 */
455TEST_F(InputReaderPolicyTest, Viewports_TwoOfSameType) {
456 const std::string uniqueId1 = "uniqueId1";
457 const std::string uniqueId2 = "uniqueId2";
458 constexpr int32_t displayId1 = 2;
459 constexpr int32_t displayId2 = 3;
460
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100461 std::vector<ViewportType> types = {ViewportType::INTERNAL, ViewportType::EXTERNAL,
462 ViewportType::VIRTUAL};
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700463 for (const ViewportType& type : types) {
464 mFakePolicy->clearViewports();
465 // Add a viewport
Michael Wrighta9cf4192022-12-01 23:46:39 +0000466 mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
467 true /*isActive*/, uniqueId1, NO_PORT, type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700468 // Add another viewport
Michael Wrighta9cf4192022-12-01 23:46:39 +0000469 mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
470 true /*isActive*/, uniqueId2, NO_PORT, type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700471
472 // Check that correct display viewport was returned by comparing the display IDs.
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700473 std::optional<DisplayViewport> viewport1 =
474 mFakePolicy->getDisplayViewportByUniqueId(uniqueId1);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700475 ASSERT_TRUE(viewport1);
476 ASSERT_EQ(displayId1, viewport1->displayId);
477 ASSERT_EQ(type, viewport1->type);
478
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700479 std::optional<DisplayViewport> viewport2 =
480 mFakePolicy->getDisplayViewportByUniqueId(uniqueId2);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700481 ASSERT_TRUE(viewport2);
482 ASSERT_EQ(displayId2, viewport2->displayId);
483 ASSERT_EQ(type, viewport2->type);
484
485 // When there are multiple viewports of the same kind, and uniqueId is not specified
486 // in the call to getDisplayViewport, then that situation is not supported.
487 // The viewports can be stored in any order, so we cannot rely on the order, since that
488 // is just implementation detail.
489 // However, we can check that it still returns *a* viewport, we just cannot assert
490 // which one specifically is returned.
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700491 std::optional<DisplayViewport> someViewport = mFakePolicy->getDisplayViewportByType(type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700492 ASSERT_TRUE(someViewport);
493 }
494}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800495
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700496/**
Michael Wrightdde67b82020-10-27 16:09:22 +0000497 * When we have multiple internal displays make sure we always return the default display when
498 * querying by type.
499 */
500TEST_F(InputReaderPolicyTest, Viewports_ByTypeReturnsDefaultForInternal) {
501 const std::string uniqueId1 = "uniqueId1";
502 const std::string uniqueId2 = "uniqueId2";
503 constexpr int32_t nonDefaultDisplayId = 2;
504 static_assert(nonDefaultDisplayId != ADISPLAY_ID_DEFAULT,
505 "Test display ID should not be ADISPLAY_ID_DEFAULT");
506
507 // Add the default display first and ensure it gets returned.
508 mFakePolicy->clearViewports();
509 mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000510 ui::ROTATION_0, true /*isActive*/, uniqueId1, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000511 ViewportType::INTERNAL);
512 mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000513 ui::ROTATION_0, true /*isActive*/, uniqueId2, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000514 ViewportType::INTERNAL);
515
516 std::optional<DisplayViewport> viewport =
517 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
518 ASSERT_TRUE(viewport);
519 ASSERT_EQ(ADISPLAY_ID_DEFAULT, viewport->displayId);
520 ASSERT_EQ(ViewportType::INTERNAL, viewport->type);
521
522 // Add the default display second to make sure order doesn't matter.
523 mFakePolicy->clearViewports();
524 mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000525 ui::ROTATION_0, true /*isActive*/, uniqueId2, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000526 ViewportType::INTERNAL);
527 mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000528 ui::ROTATION_0, true /*isActive*/, uniqueId1, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000529 ViewportType::INTERNAL);
530
531 viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
532 ASSERT_TRUE(viewport);
533 ASSERT_EQ(ADISPLAY_ID_DEFAULT, viewport->displayId);
534 ASSERT_EQ(ViewportType::INTERNAL, viewport->type);
535}
536
537/**
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700538 * Check getDisplayViewportByPort
539 */
540TEST_F(InputReaderPolicyTest, Viewports_GetByPort) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100541 constexpr ViewportType type = ViewportType::EXTERNAL;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700542 const std::string uniqueId1 = "uniqueId1";
543 const std::string uniqueId2 = "uniqueId2";
544 constexpr int32_t displayId1 = 1;
545 constexpr int32_t displayId2 = 2;
546 const uint8_t hdmi1 = 0;
547 const uint8_t hdmi2 = 1;
548 const uint8_t hdmi3 = 2;
549
550 mFakePolicy->clearViewports();
551 // Add a viewport that's associated with some display port that's not of interest.
Michael Wrighta9cf4192022-12-01 23:46:39 +0000552 mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
553 true /*isActive*/, uniqueId1, hdmi3, type);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700554 // Add another viewport, connected to HDMI1 port
Michael Wrighta9cf4192022-12-01 23:46:39 +0000555 mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
556 true /*isActive*/, uniqueId2, hdmi1, type);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700557
558 // Check that correct display viewport was returned by comparing the display ports.
559 std::optional<DisplayViewport> hdmi1Viewport = mFakePolicy->getDisplayViewportByPort(hdmi1);
560 ASSERT_TRUE(hdmi1Viewport);
561 ASSERT_EQ(displayId2, hdmi1Viewport->displayId);
562 ASSERT_EQ(uniqueId2, hdmi1Viewport->uniqueId);
563
564 // Check that we can still get the same viewport using the uniqueId
565 hdmi1Viewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId2);
566 ASSERT_TRUE(hdmi1Viewport);
567 ASSERT_EQ(displayId2, hdmi1Viewport->displayId);
568 ASSERT_EQ(uniqueId2, hdmi1Viewport->uniqueId);
569 ASSERT_EQ(type, hdmi1Viewport->type);
570
571 // Check that we cannot find a port with "HDMI2", because we never added one
572 std::optional<DisplayViewport> hdmi2Viewport = mFakePolicy->getDisplayViewportByPort(hdmi2);
573 ASSERT_FALSE(hdmi2Viewport);
574}
575
Michael Wrightd02c5b62014-02-10 15:10:22 -0800576// --- InputReaderTest ---
577
578class InputReaderTest : public testing::Test {
579protected:
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700580 std::unique_ptr<TestInputListener> mFakeListener;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800581 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -0700582 std::shared_ptr<FakeEventHub> mFakeEventHub;
Prabir Pradhan28efc192019-11-05 01:10:04 +0000583 std::unique_ptr<InstrumentedInputReader> mReader;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800584
Chris Yea52ade12020-08-27 16:49:20 -0700585 void SetUp() override {
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -0700586 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700587 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700588 mFakeListener = std::make_unique<TestInputListener>();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800589
Prabir Pradhan28efc192019-11-05 01:10:04 +0000590 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700591 *mFakeListener);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800592 }
593
Chris Yea52ade12020-08-27 16:49:20 -0700594 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700595 mFakeListener.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800596 mFakePolicy.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800597 }
598
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700599 void addDevice(int32_t eventHubId, const std::string& name,
600 ftl::Flags<InputDeviceClass> classes, const PropertyMap* configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800601 mFakeEventHub->addDevice(eventHubId, name, classes);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800602
603 if (configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800604 mFakeEventHub->addConfigurationMap(eventHubId, configuration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800605 }
606 mFakeEventHub->finishDeviceScan();
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000607 mReader->loopOnce();
608 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700609 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
610 ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800611 }
612
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800613 void disableDevice(int32_t deviceId) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700614 mFakePolicy->addDisabledDevice(deviceId);
Prabir Pradhan28efc192019-11-05 01:10:04 +0000615 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_ENABLED_STATE);
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700616 }
617
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800618 void enableDevice(int32_t deviceId) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700619 mFakePolicy->removeDisabledDevice(deviceId);
Prabir Pradhan28efc192019-11-05 01:10:04 +0000620 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_ENABLED_STATE);
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700621 }
622
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800623 FakeInputMapper& addDeviceWithFakeInputMapper(int32_t deviceId, int32_t eventHubId,
Chris Ye1b0c7342020-07-28 21:57:03 -0700624 const std::string& name,
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700625 ftl::Flags<InputDeviceClass> classes,
626 uint32_t sources,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800627 const PropertyMap* configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800628 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, name);
629 FakeInputMapper& mapper = device->addMapper<FakeInputMapper>(eventHubId, sources);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800630 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800631 addDevice(eventHubId, name, classes, configuration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800632 return mapper;
633 }
634};
635
Chris Ye98d3f532020-10-01 21:48:59 -0700636TEST_F(InputReaderTest, PolicyGetInputDevices) {
637 ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr));
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700638 ASSERT_NO_FATAL_FAILURE(addDevice(2, "ignored", ftl::Flags<InputDeviceClass>(0),
Chris Ye98d3f532020-10-01 21:48:59 -0700639 nullptr)); // no classes so device will be ignored
Michael Wrightd02c5b62014-02-10 15:10:22 -0800640
641 // Should also have received a notification describing the new input devices.
Chris Ye98d3f532020-10-01 21:48:59 -0700642 const std::vector<InputDeviceInfo>& inputDevices = mFakePolicy->getInputDevices();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800643 ASSERT_EQ(1U, inputDevices.size());
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800644 ASSERT_EQ(END_RESERVED_ID + 1, inputDevices[0].getId());
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100645 ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800646 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
647 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
Siarhei Vishniakou1983a712021-06-04 19:27:09 +0000648 ASSERT_EQ(0U, inputDevices[0].getMotionRanges().size());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800649}
650
Chris Yee7310032020-09-22 15:36:28 -0700651TEST_F(InputReaderTest, GetMergedInputDevices) {
652 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
653 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
654 // Add two subdevices to device
655 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
656 // Must add at least one mapper or the device will be ignored!
657 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
658 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
659
660 // Push same device instance for next device to be added, so they'll have same identifier.
661 mReader->pushNextDevice(device);
662 mReader->pushNextDevice(device);
663 ASSERT_NO_FATAL_FAILURE(
664 addDevice(eventHubIds[0], "fake1", InputDeviceClass::KEYBOARD, nullptr));
665 ASSERT_NO_FATAL_FAILURE(
666 addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
667
668 // Two devices will be merged to one input device as they have same identifier
Siarhei Vishniakou1983a712021-06-04 19:27:09 +0000669 ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
Chris Yee7310032020-09-22 15:36:28 -0700670}
671
Chris Yee14523a2020-12-19 13:46:00 -0800672TEST_F(InputReaderTest, GetMergedInputDevicesEnabled) {
673 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
674 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
675 // Add two subdevices to device
676 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
677 // Must add at least one mapper or the device will be ignored!
678 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
679 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
680
681 // Push same device instance for next device to be added, so they'll have same identifier.
682 mReader->pushNextDevice(device);
683 mReader->pushNextDevice(device);
684 // Sensor device is initially disabled
685 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1",
686 InputDeviceClass::KEYBOARD | InputDeviceClass::SENSOR,
687 nullptr));
688 // Device is disabled because the only sub device is a sensor device and disabled initially.
689 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
690 ASSERT_FALSE(device->isEnabled());
691 ASSERT_NO_FATAL_FAILURE(
692 addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
693 // The merged device is enabled if any sub device is enabled
694 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
695 ASSERT_TRUE(device->isEnabled());
696}
697
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700698TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800699 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700700 constexpr ftl::Flags<InputDeviceClass> deviceClass(InputDeviceClass::KEYBOARD);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800701 constexpr int32_t eventHubId = 1;
702 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700703 // Must add at least one mapper or the device will be ignored!
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800704 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800705 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800706 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700707
Yi Kong9b14ac62018-07-17 13:48:38 -0700708 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700709
710 NotifyDeviceResetArgs resetArgs;
711 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700712 ASSERT_EQ(deviceId, resetArgs.deviceId);
713
714 ASSERT_EQ(device->isEnabled(), true);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800715 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000716 mReader->loopOnce();
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700717
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700718 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700719 ASSERT_EQ(deviceId, resetArgs.deviceId);
720 ASSERT_EQ(device->isEnabled(), false);
721
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800722 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000723 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700724 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
725 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasNotCalled());
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700726 ASSERT_EQ(device->isEnabled(), false);
727
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800728 enableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000729 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700730 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700731 ASSERT_EQ(deviceId, resetArgs.deviceId);
732 ASSERT_EQ(device->isEnabled(), true);
733}
734
Michael Wrightd02c5b62014-02-10 15:10:22 -0800735TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
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;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800739 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800740 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800741 AINPUT_SOURCE_KEYBOARD, nullptr);
742 mapper.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800743
744 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(0,
745 AINPUT_SOURCE_ANY, AKEYCODE_A))
746 << "Should return unknown when the device id is >= 0 but unknown.";
747
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800748 ASSERT_EQ(AKEY_STATE_UNKNOWN,
749 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
750 << "Should return unknown when the device id is valid but the sources are not "
751 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800752
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800753 ASSERT_EQ(AKEY_STATE_DOWN,
754 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
755 AKEYCODE_A))
756 << "Should return value provided by mapper when device id is valid and the device "
757 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800758
759 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(-1,
760 AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
761 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
762
763 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(-1,
764 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
765 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
766}
767
Philip Junker4af3b3d2021-12-14 10:36:55 +0100768TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_ForwardsRequestsToMappers) {
769 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
770 constexpr int32_t eventHubId = 1;
771 FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "keyboard",
772 InputDeviceClass::KEYBOARD,
773 AINPUT_SOURCE_KEYBOARD, nullptr);
774 mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
775
776 ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(0, AKEYCODE_Y))
777 << "Should return unknown when the device with the specified id is not found.";
778
779 ASSERT_EQ(AKEYCODE_Z, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
780 << "Should return correct mapping when device id is valid and mapping exists.";
781
782 ASSERT_EQ(AKEYCODE_A, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_A))
783 << "Should return the location key code when device id is valid and there's no "
784 "mapping.";
785}
786
787TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_NoKeyboardMapper) {
788 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
789 constexpr int32_t eventHubId = 1;
790 FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "joystick",
791 InputDeviceClass::JOYSTICK,
792 AINPUT_SOURCE_GAMEPAD, nullptr);
793 mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
794
795 ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
796 << "Should return unknown when the device id is valid but there is no keyboard mapper";
797}
798
Michael Wrightd02c5b62014-02-10 15:10:22 -0800799TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800800 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700801 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800802 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800803 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800804 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800805 AINPUT_SOURCE_KEYBOARD, nullptr);
806 mapper.setScanCodeState(KEY_A, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800807
808 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(0,
809 AINPUT_SOURCE_ANY, KEY_A))
810 << "Should return unknown when the device id is >= 0 but unknown.";
811
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800812 ASSERT_EQ(AKEY_STATE_UNKNOWN,
813 mReader->getScanCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, KEY_A))
814 << "Should return unknown when the device id is valid but the sources are not "
815 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800816
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800817 ASSERT_EQ(AKEY_STATE_DOWN,
818 mReader->getScanCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
819 KEY_A))
820 << "Should return value provided by mapper when device id is valid and the device "
821 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800822
823 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(-1,
824 AINPUT_SOURCE_TRACKBALL, KEY_A))
825 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
826
827 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(-1,
828 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
829 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
830}
831
832TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800833 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700834 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800835 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800836 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800837 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800838 AINPUT_SOURCE_KEYBOARD, nullptr);
839 mapper.setSwitchState(SW_LID, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800840
841 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(0,
842 AINPUT_SOURCE_ANY, SW_LID))
843 << "Should return unknown when the device id is >= 0 but unknown.";
844
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800845 ASSERT_EQ(AKEY_STATE_UNKNOWN,
846 mReader->getSwitchState(deviceId, AINPUT_SOURCE_TRACKBALL, SW_LID))
847 << "Should return unknown when the device id is valid but the sources are not "
848 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800849
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800850 ASSERT_EQ(AKEY_STATE_DOWN,
851 mReader->getSwitchState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
852 SW_LID))
853 << "Should return value provided by mapper when device id is valid and the device "
854 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800855
856 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(-1,
857 AINPUT_SOURCE_TRACKBALL, SW_LID))
858 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
859
860 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(-1,
861 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
862 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
863}
864
865TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800866 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700867 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800868 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800869 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800870 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800871 AINPUT_SOURCE_KEYBOARD, nullptr);
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100872
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800873 mapper.addSupportedKeyCode(AKEYCODE_A);
874 mapper.addSupportedKeyCode(AKEYCODE_B);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800875
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700876 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800877 uint8_t flags[4] = { 0, 0, 0, 1 };
878
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700879 ASSERT_FALSE(mReader->hasKeys(0, AINPUT_SOURCE_ANY, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800880 << "Should return false when device id is >= 0 but unknown.";
881 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
882
883 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700884 ASSERT_FALSE(mReader->hasKeys(deviceId, AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800885 << "Should return false when device id is valid but the sources are not supported by "
886 "the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800887 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
888
889 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700890 ASSERT_TRUE(mReader->hasKeys(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800891 keyCodes, flags))
892 << "Should return value provided by mapper when device id is valid and the device "
893 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800894 ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
895
896 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700897 ASSERT_FALSE(mReader->hasKeys(-1, AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
898 << "Should return false when the device id is < 0 but the sources are not supported by "
899 "any device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800900 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
901
902 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700903 ASSERT_TRUE(
904 mReader->hasKeys(-1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
905 << "Should return value provided by mapper when device id is < 0 and one of the "
906 "devices supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800907 ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
908}
909
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000910TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800911 constexpr int32_t eventHubId = 1;
Chris Ye1b0c7342020-07-28 21:57:03 -0700912 addDevice(eventHubId, "ignored", InputDeviceClass::KEYBOARD, nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800913
914 NotifyConfigurationChangedArgs args;
915
916 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(&args));
917 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
918}
919
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000920TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800921 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700922 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000923 constexpr nsecs_t when = 0;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800924 constexpr int32_t eventHubId = 1;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000925 constexpr nsecs_t readTime = 2;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800926 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800927 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800928 AINPUT_SOURCE_KEYBOARD, nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800929
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000930 mFakeEventHub->enqueueEvent(when, readTime, eventHubId, EV_KEY, KEY_A, 1);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000931 mReader->loopOnce();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800932 ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
933
934 RawEvent event;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800935 ASSERT_NO_FATAL_FAILURE(mapper.assertProcessWasCalled(&event));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000936 ASSERT_EQ(when, event.when);
937 ASSERT_EQ(readTime, event.readTime);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800938 ASSERT_EQ(eventHubId, event.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800939 ASSERT_EQ(EV_KEY, event.type);
940 ASSERT_EQ(KEY_A, event.code);
941 ASSERT_EQ(1, event.value);
942}
943
Garfield Tan1c7bc862020-01-28 13:24:04 -0800944TEST_F(InputReaderTest, DeviceReset_RandomId) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800945 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700946 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800947 constexpr int32_t eventHubId = 1;
948 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
Prabir Pradhan42611e02018-11-27 14:04:02 -0800949 // Must add at least one mapper or the device will be ignored!
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800950 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800951 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800952 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Prabir Pradhan42611e02018-11-27 14:04:02 -0800953
954 NotifyDeviceResetArgs resetArgs;
955 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800956 int32_t prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -0800957
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800958 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000959 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700960 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -0800961 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800962 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -0800963
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800964 enableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000965 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700966 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -0800967 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800968 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -0800969
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800970 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000971 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700972 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -0800973 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800974 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -0800975}
976
Garfield Tan1c7bc862020-01-28 13:24:04 -0800977TEST_F(InputReaderTest, DeviceReset_GenerateIdWithInputReaderSource) {
978 constexpr int32_t deviceId = 1;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700979 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Garfield Tan1c7bc862020-01-28 13:24:04 -0800980 constexpr int32_t eventHubId = 1;
981 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
982 // Must add at least one mapper or the device will be ignored!
983 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800984 mReader->pushNextDevice(device);
Garfield Tan1c7bc862020-01-28 13:24:04 -0800985 ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr));
986
987 NotifyDeviceResetArgs resetArgs;
988 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
989 ASSERT_EQ(IdGenerator::Source::INPUT_READER, IdGenerator::getSource(resetArgs.id));
990}
991
Arthur Hungc23540e2018-11-29 20:42:11 +0800992TEST_F(InputReaderTest, Device_CanDispatchToDisplay) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800993 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700994 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800995 constexpr int32_t eventHubId = 1;
Arthur Hungc23540e2018-11-29 20:42:11 +0800996 const char* DEVICE_LOCATION = "USB1";
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800997 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
998 FakeInputMapper& mapper =
999 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_TOUCHSCREEN);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001000 mReader->pushNextDevice(device);
Arthur Hungc23540e2018-11-29 20:42:11 +08001001
1002 const uint8_t hdmi1 = 1;
1003
1004 // Associated touch screen with second display.
1005 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
1006
1007 // Add default and second display.
Prabir Pradhan28efc192019-11-05 01:10:04 +00001008 mFakePolicy->clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00001009 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
1010 true /*isActive*/, "local:0", NO_PORT, ViewportType::INTERNAL);
Arthur Hungc23540e2018-11-29 20:42:11 +08001011 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +00001012 ui::ROTATION_0, true /*isActive*/, "local:1", hdmi1,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001013 ViewportType::EXTERNAL);
Arthur Hungc23540e2018-11-29 20:42:11 +08001014 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001015 mReader->loopOnce();
Prabir Pradhan28efc192019-11-05 01:10:04 +00001016
1017 // Add the device, and make sure all of the callbacks are triggered.
1018 // The device is added after the input port associations are processed since
1019 // we do not yet support dynamic device-to-display associations.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001020 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001021 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled());
Prabir Pradhan28efc192019-11-05 01:10:04 +00001022 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001023 ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
Arthur Hungc23540e2018-11-29 20:42:11 +08001024
Arthur Hung2c9a3342019-07-23 14:18:59 +08001025 // Device should only dispatch to the specified display.
Arthur Hungc23540e2018-11-29 20:42:11 +08001026 ASSERT_EQ(deviceId, device->getId());
1027 ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, DISPLAY_ID));
1028 ASSERT_TRUE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
Arthur Hung2c9a3342019-07-23 14:18:59 +08001029
1030 // Can't dispatch event from a disabled device.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001031 disableDevice(deviceId);
Prabir Pradhan28efc192019-11-05 01:10:04 +00001032 mReader->loopOnce();
Arthur Hung2c9a3342019-07-23 14:18:59 +08001033 ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
Arthur Hungc23540e2018-11-29 20:42:11 +08001034}
1035
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001036TEST_F(InputReaderTest, WhenEnabledChanges_AllSubdevicesAreUpdated) {
1037 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001038 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001039 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
1040 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1041 // Must add at least one mapper or the device will be ignored!
1042 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
1043 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
1044 mReader->pushNextDevice(device);
1045 mReader->pushNextDevice(device);
1046 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
1047 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
1048
1049 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
1050
1051 NotifyDeviceResetArgs resetArgs;
1052 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1053 ASSERT_EQ(deviceId, resetArgs.deviceId);
1054 ASSERT_TRUE(device->isEnabled());
1055 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1056 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1057
1058 disableDevice(deviceId);
1059 mReader->loopOnce();
1060
1061 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1062 ASSERT_EQ(deviceId, resetArgs.deviceId);
1063 ASSERT_FALSE(device->isEnabled());
1064 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1065 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1066
1067 enableDevice(deviceId);
1068 mReader->loopOnce();
1069
1070 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1071 ASSERT_EQ(deviceId, resetArgs.deviceId);
1072 ASSERT_TRUE(device->isEnabled());
1073 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1074 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1075}
1076
1077TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToSubdeviceMappers) {
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 // Add two subdevices to device
1082 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1083 FakeInputMapper& mapperDevice1 =
1084 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
1085 FakeInputMapper& mapperDevice2 =
1086 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
1087 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 mapperDevice1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
1093 mapperDevice2.setKeyCodeState(AKEYCODE_B, AKEY_STATE_DOWN);
1094
1095 ASSERT_EQ(AKEY_STATE_DOWN,
1096 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_A));
1097 ASSERT_EQ(AKEY_STATE_DOWN,
1098 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_B));
1099 ASSERT_EQ(AKEY_STATE_UNKNOWN,
1100 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_C));
1101}
1102
Prabir Pradhan7e186182020-11-10 13:56:45 -08001103TEST_F(InputReaderTest, ChangingPointerCaptureNotifiesInputListener) {
1104 NotifyPointerCaptureChangedArgs args;
1105
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001106 auto request = mFakePolicy->setPointerCapture(true);
Prabir Pradhan7e186182020-11-10 13:56:45 -08001107 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
1108 mReader->loopOnce();
1109 mFakeListener->assertNotifyCaptureWasCalled(&args);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001110 ASSERT_TRUE(args.request.enable) << "Pointer Capture should be enabled.";
1111 ASSERT_EQ(args.request, request) << "Pointer Capture sequence number should match.";
Prabir Pradhan7e186182020-11-10 13:56:45 -08001112
1113 mFakePolicy->setPointerCapture(false);
1114 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
1115 mReader->loopOnce();
1116 mFakeListener->assertNotifyCaptureWasCalled(&args);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001117 ASSERT_FALSE(args.request.enable) << "Pointer Capture should be disabled.";
Prabir Pradhan7e186182020-11-10 13:56:45 -08001118
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001119 // Verify that the Pointer Capture state is not updated when the configuration value
Prabir Pradhan7e186182020-11-10 13:56:45 -08001120 // does not change.
1121 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
1122 mReader->loopOnce();
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001123 mFakeListener->assertNotifyCaptureWasNotCalled();
Prabir Pradhan7e186182020-11-10 13:56:45 -08001124}
1125
Chris Ye87143712020-11-10 05:05:58 +00001126class FakeVibratorInputMapper : public FakeInputMapper {
1127public:
1128 FakeVibratorInputMapper(InputDeviceContext& deviceContext, uint32_t sources)
1129 : FakeInputMapper(deviceContext, sources) {}
1130
1131 std::vector<int32_t> getVibratorIds() override { return getDeviceContext().getVibratorIds(); }
1132};
1133
1134TEST_F(InputReaderTest, VibratorGetVibratorIds) {
1135 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001136 ftl::Flags<InputDeviceClass> deviceClass =
1137 InputDeviceClass::KEYBOARD | InputDeviceClass::VIBRATOR;
Chris Ye87143712020-11-10 05:05:58 +00001138 constexpr int32_t eventHubId = 1;
1139 const char* DEVICE_LOCATION = "BLUETOOTH";
1140 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1141 FakeVibratorInputMapper& mapper =
1142 device->addMapper<FakeVibratorInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
1143 mReader->pushNextDevice(device);
1144
1145 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1146 ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
1147
1148 ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
1149 ASSERT_EQ(mReader->getVibratorIds(deviceId).size(), 2U);
1150}
1151
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001152// --- FakePeripheralController ---
Kim Low03ea0352020-11-06 12:45:07 -08001153
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001154class FakePeripheralController : public PeripheralControllerInterface {
Chris Yee2b1e5c2021-03-10 22:45:12 -08001155public:
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001156 FakePeripheralController(InputDeviceContext& deviceContext) : mDeviceContext(deviceContext) {}
Chris Yee2b1e5c2021-03-10 22:45:12 -08001157
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001158 ~FakePeripheralController() override {}
Chris Yee2b1e5c2021-03-10 22:45:12 -08001159
Andy Chenf9f1a022022-08-29 20:07:10 -04001160 int32_t getEventHubId() const { return getDeviceContext().getEventHubId(); }
1161
Chris Yee2b1e5c2021-03-10 22:45:12 -08001162 void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {}
1163
1164 void dump(std::string& dump) override {}
1165
1166 std::optional<int32_t> getBatteryCapacity(int32_t batteryId) override {
1167 return getDeviceContext().getBatteryCapacity(batteryId);
Kim Low03ea0352020-11-06 12:45:07 -08001168 }
1169
Chris Yee2b1e5c2021-03-10 22:45:12 -08001170 std::optional<int32_t> getBatteryStatus(int32_t batteryId) override {
1171 return getDeviceContext().getBatteryStatus(batteryId);
Kim Low03ea0352020-11-06 12:45:07 -08001172 }
Chris Ye3fdbfef2021-01-06 18:45:18 -08001173
1174 bool setLightColor(int32_t lightId, int32_t color) override {
1175 getDeviceContext().setLightBrightness(lightId, color >> 24);
1176 return true;
1177 }
1178
1179 std::optional<int32_t> getLightColor(int32_t lightId) override {
1180 std::optional<int32_t> result = getDeviceContext().getLightBrightness(lightId);
1181 if (!result.has_value()) {
1182 return std::nullopt;
1183 }
1184 return result.value() << 24;
1185 }
Chris Yee2b1e5c2021-03-10 22:45:12 -08001186
1187 bool setLightPlayerId(int32_t lightId, int32_t playerId) override { return true; }
1188
1189 std::optional<int32_t> getLightPlayerId(int32_t lightId) override { return std::nullopt; }
1190
1191private:
1192 InputDeviceContext& mDeviceContext;
1193 inline int32_t getDeviceId() { return mDeviceContext.getId(); }
1194 inline InputDeviceContext& getDeviceContext() { return mDeviceContext; }
Andy Chenf9f1a022022-08-29 20:07:10 -04001195 inline InputDeviceContext& getDeviceContext() const { return mDeviceContext; }
Chris Ye3fdbfef2021-01-06 18:45:18 -08001196};
1197
Chris Yee2b1e5c2021-03-10 22:45:12 -08001198TEST_F(InputReaderTest, BatteryGetCapacity) {
1199 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001200 ftl::Flags<InputDeviceClass> deviceClass =
1201 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
Chris Yee2b1e5c2021-03-10 22:45:12 -08001202 constexpr int32_t eventHubId = 1;
1203 const char* DEVICE_LOCATION = "BLUETOOTH";
1204 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001205 FakePeripheralController& controller =
1206 device->addController<FakePeripheralController>(eventHubId);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001207 mReader->pushNextDevice(device);
1208
1209 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1210
Harry Cuttsa5b71292022-11-28 12:56:17 +00001211 ASSERT_EQ(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY),
1212 FakeEventHub::BATTERY_CAPACITY);
1213 ASSERT_EQ(mReader->getBatteryCapacity(deviceId), FakeEventHub::BATTERY_CAPACITY);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001214}
1215
1216TEST_F(InputReaderTest, BatteryGetStatus) {
1217 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001218 ftl::Flags<InputDeviceClass> deviceClass =
1219 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
Chris Yee2b1e5c2021-03-10 22:45:12 -08001220 constexpr int32_t eventHubId = 1;
1221 const char* DEVICE_LOCATION = "BLUETOOTH";
1222 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001223 FakePeripheralController& controller =
1224 device->addController<FakePeripheralController>(eventHubId);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001225 mReader->pushNextDevice(device);
1226
1227 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1228
Harry Cuttsa5b71292022-11-28 12:56:17 +00001229 ASSERT_EQ(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY),
1230 FakeEventHub::BATTERY_STATUS);
1231 ASSERT_EQ(mReader->getBatteryStatus(deviceId), FakeEventHub::BATTERY_STATUS);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001232}
1233
Prabir Pradhane287ecd2022-09-07 21:18:05 +00001234TEST_F(InputReaderTest, BatteryGetDevicePath) {
1235 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1236 ftl::Flags<InputDeviceClass> deviceClass =
1237 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
1238 constexpr int32_t eventHubId = 1;
1239 const char* DEVICE_LOCATION = "BLUETOOTH";
1240 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1241 device->addController<FakePeripheralController>(eventHubId);
1242 mReader->pushNextDevice(device);
1243
1244 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1245
Harry Cuttsa5b71292022-11-28 12:56:17 +00001246 ASSERT_EQ(mReader->getBatteryDevicePath(deviceId), FakeEventHub::BATTERY_DEVPATH);
Prabir Pradhane287ecd2022-09-07 21:18:05 +00001247}
1248
Chris Ye3fdbfef2021-01-06 18:45:18 -08001249TEST_F(InputReaderTest, LightGetColor) {
1250 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001251 ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD | InputDeviceClass::LIGHT;
Chris Ye3fdbfef2021-01-06 18:45:18 -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 Ye3fdbfef2021-01-06 18:45:18 -08001257 mReader->pushNextDevice(device);
1258 RawLightInfo info = {.id = 1,
1259 .name = "Mono",
1260 .maxBrightness = 255,
1261 .flags = InputLightClass::BRIGHTNESS,
1262 .path = ""};
1263 mFakeEventHub->addRawLightInfo(1 /* rawId */, std::move(info));
1264 mFakeEventHub->fakeLightBrightness(1 /* rawId */, 0x55);
1265
1266 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Chris Ye3fdbfef2021-01-06 18:45:18 -08001267
Chris Yee2b1e5c2021-03-10 22:45:12 -08001268 ASSERT_TRUE(controller.setLightColor(1 /* lightId */, LIGHT_BRIGHTNESS));
1269 ASSERT_EQ(controller.getLightColor(1 /* lightId */), LIGHT_BRIGHTNESS);
Chris Ye3fdbfef2021-01-06 18:45:18 -08001270 ASSERT_TRUE(mReader->setLightColor(deviceId, 1 /* lightId */, LIGHT_BRIGHTNESS));
1271 ASSERT_EQ(mReader->getLightColor(deviceId, 1 /* lightId */), LIGHT_BRIGHTNESS);
1272}
1273
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001274// --- InputReaderIntegrationTest ---
1275
1276// These tests create and interact with the InputReader only through its interface.
1277// The InputReader is started during SetUp(), which starts its processing in its own
1278// thread. The tests use linux uinput to emulate input devices.
1279// NOTE: Interacting with the physical device while these tests are running may cause
1280// the tests to fail.
1281class InputReaderIntegrationTest : public testing::Test {
1282protected:
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001283 std::unique_ptr<TestInputListener> mTestListener;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001284 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001285 std::unique_ptr<InputReaderInterface> mReader;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001286
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00001287 std::shared_ptr<FakePointerController> mFakePointerController;
1288
Chris Yea52ade12020-08-27 16:49:20 -07001289 void SetUp() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001290#if !defined(__ANDROID__)
1291 GTEST_SKIP();
1292#endif
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07001293 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00001294 mFakePointerController = std::make_shared<FakePointerController>();
1295 mFakePolicy->setPointerController(mFakePointerController);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001296 mTestListener = std::make_unique<TestInputListener>(2000ms /*eventHappenedTimeout*/,
1297 30ms /*eventDidNotHappenTimeout*/);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001298
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001299 mReader = std::make_unique<InputReader>(std::make_shared<EventHub>(), mFakePolicy,
1300 *mTestListener);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001301 ASSERT_EQ(mReader->start(), OK);
1302
1303 // Since this test is run on a real device, all the input devices connected
1304 // to the test device will show up in mReader. We wait for those input devices to
1305 // show up before beginning the tests.
1306 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1307 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1308 }
1309
Chris Yea52ade12020-08-27 16:49:20 -07001310 void TearDown() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001311#if !defined(__ANDROID__)
1312 return;
1313#endif
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001314 ASSERT_EQ(mReader->stop(), OK);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001315 mReader.reset();
1316 mTestListener.reset();
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001317 mFakePolicy.clear();
1318 }
Prabir Pradhanda20b172022-09-26 17:01:18 +00001319
1320 std::optional<InputDeviceInfo> findDeviceByName(const std::string& name) {
1321 const std::vector<InputDeviceInfo> inputDevices = mFakePolicy->getInputDevices();
1322 const auto& it = std::find_if(inputDevices.begin(), inputDevices.end(),
1323 [&name](const InputDeviceInfo& info) {
1324 return info.getIdentifier().name == name;
1325 });
1326 return it != inputDevices.end() ? std::make_optional(*it) : std::nullopt;
1327 }
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001328};
1329
1330TEST_F(InputReaderIntegrationTest, TestInvalidDevice) {
1331 // An invalid input device that is only used for this test.
1332 class InvalidUinputDevice : public UinputDevice {
1333 public:
Prabir Pradhanb7d434e2022-10-14 22:41:38 +00001334 InvalidUinputDevice() : UinputDevice("Invalid Device", 99 /*productId*/) {}
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001335
1336 private:
1337 void configureDevice(int fd, uinput_user_dev* device) override {}
1338 };
1339
1340 const size_t numDevices = mFakePolicy->getInputDevices().size();
1341
1342 // UinputDevice does not set any event or key bits, so InputReader should not
1343 // consider it as a valid device.
1344 std::unique_ptr<UinputDevice> invalidDevice = createUinputDevice<InvalidUinputDevice>();
1345 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
1346 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
1347 ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
1348
1349 invalidDevice.reset();
1350 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
1351 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
1352 ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
1353}
1354
1355TEST_F(InputReaderIntegrationTest, AddNewDevice) {
1356 const size_t initialNumDevices = mFakePolicy->getInputDevices().size();
1357
1358 std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
1359 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1360 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1361 ASSERT_EQ(initialNumDevices + 1, mFakePolicy->getInputDevices().size());
1362
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001363 const auto device = findDeviceByName(keyboard->getName());
1364 ASSERT_TRUE(device.has_value());
1365 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, device->getKeyboardType());
1366 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources());
1367 ASSERT_EQ(0U, device->getMotionRanges().size());
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001368
1369 keyboard.reset();
1370 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1371 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1372 ASSERT_EQ(initialNumDevices, mFakePolicy->getInputDevices().size());
1373}
1374
1375TEST_F(InputReaderIntegrationTest, SendsEventsToInputListener) {
1376 std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
1377 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1378
1379 NotifyConfigurationChangedArgs configChangedArgs;
1380 ASSERT_NO_FATAL_FAILURE(
1381 mTestListener->assertNotifyConfigurationChangedWasCalled(&configChangedArgs));
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001382 int32_t prevId = configChangedArgs.id;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001383 nsecs_t prevTimestamp = configChangedArgs.eventTime;
1384
1385 NotifyKeyArgs keyArgs;
1386 keyboard->pressAndReleaseHomeKey();
1387 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
1388 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
Garfield Tan1c7bc862020-01-28 13:24:04 -08001389 ASSERT_NE(prevId, keyArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001390 prevId = keyArgs.id;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001391 ASSERT_LE(prevTimestamp, keyArgs.eventTime);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001392 ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001393 prevTimestamp = keyArgs.eventTime;
1394
1395 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
1396 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
Garfield Tan1c7bc862020-01-28 13:24:04 -08001397 ASSERT_NE(prevId, keyArgs.id);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001398 ASSERT_LE(prevTimestamp, keyArgs.eventTime);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001399 ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001400}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001401
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001402TEST_F(InputReaderIntegrationTest, ExternalStylusesButtons) {
1403 std::unique_ptr<UinputExternalStylus> stylus = createUinputDevice<UinputExternalStylus>();
1404 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1405
1406 const auto device = findDeviceByName(stylus->getName());
1407 ASSERT_TRUE(device.has_value());
1408
Prabir Pradhana3621852022-10-14 18:57:23 +00001409 // An external stylus with buttons should also be recognized as a keyboard.
1410 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_STYLUS, device->getSources())
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001411 << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
1412 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, device->getKeyboardType());
1413
1414 const auto DOWN =
1415 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD));
1416 const auto UP = AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD));
1417
1418 stylus->pressAndReleaseKey(BTN_STYLUS);
1419 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1420 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1421 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1422 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1423
1424 stylus->pressAndReleaseKey(BTN_STYLUS2);
1425 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1426 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_SECONDARY))));
1427 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1428 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_SECONDARY))));
1429
1430 stylus->pressAndReleaseKey(BTN_STYLUS3);
1431 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1432 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
1433 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1434 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
1435}
1436
Siarhei Vishniakoua0d2b802020-05-13 14:00:31 -07001437/**
1438 * The Steam controller sends BTN_GEAR_DOWN and BTN_GEAR_UP for the two "paddle" buttons
1439 * on the back. In this test, we make sure that BTN_GEAR_DOWN / BTN_WHEEL and BTN_GEAR_UP
1440 * are passed to the listener.
1441 */
1442static_assert(BTN_GEAR_DOWN == BTN_WHEEL);
1443TEST_F(InputReaderIntegrationTest, SendsGearDownAndUpToInputListener) {
1444 std::unique_ptr<UinputSteamController> controller = createUinputDevice<UinputSteamController>();
1445 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1446 NotifyKeyArgs keyArgs;
1447
1448 controller->pressAndReleaseKey(BTN_GEAR_DOWN);
1449 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
1450 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
1451 ASSERT_EQ(BTN_GEAR_DOWN, keyArgs.scanCode);
1452
1453 controller->pressAndReleaseKey(BTN_GEAR_UP);
1454 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
1455 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
1456 ASSERT_EQ(BTN_GEAR_UP, keyArgs.scanCode);
1457}
1458
Prabir Pradhan484d55a2022-10-14 23:17:16 +00001459// --- TouchIntegrationTest ---
1460
Arthur Hungaab25622020-01-16 11:22:11 +08001461class TouchIntegrationTest : public InputReaderIntegrationTest {
1462protected:
Arthur Hungaab25622020-01-16 11:22:11 +08001463 const std::string UNIQUE_ID = "local:0";
1464
Chris Yea52ade12020-08-27 16:49:20 -07001465 void SetUp() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001466#if !defined(__ANDROID__)
1467 GTEST_SKIP();
1468#endif
Arthur Hungaab25622020-01-16 11:22:11 +08001469 InputReaderIntegrationTest::SetUp();
1470 // At least add an internal display.
Michael Wrighta9cf4192022-12-01 23:46:39 +00001471 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
1472 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Arthur Hungaab25622020-01-16 11:22:11 +08001473
1474 mDevice = createUinputDevice<UinputTouchScreen>(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT));
1475 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1476 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
Prabir Pradhanda20b172022-09-26 17:01:18 +00001477 const auto info = findDeviceByName(mDevice->getName());
1478 ASSERT_TRUE(info);
1479 mDeviceInfo = *info;
Arthur Hungaab25622020-01-16 11:22:11 +08001480 }
1481
1482 void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
Michael Wrighta9cf4192022-12-01 23:46:39 +00001483 ui::Rotation orientation, const std::string& uniqueId,
Arthur Hungaab25622020-01-16 11:22:11 +08001484 std::optional<uint8_t> physicalPort,
1485 ViewportType viewportType) {
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001486 mFakePolicy->addDisplayViewport(displayId, width, height, orientation, true /*isActive*/,
1487 uniqueId, physicalPort, viewportType);
Arthur Hungaab25622020-01-16 11:22:11 +08001488 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
1489 }
1490
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001491 void assertReceivedMotion(int32_t action, const std::vector<Point>& points) {
1492 NotifyMotionArgs args;
1493 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1494 EXPECT_EQ(action, args.action);
1495 ASSERT_EQ(points.size(), args.pointerCount);
1496 for (size_t i = 0; i < args.pointerCount; i++) {
1497 EXPECT_EQ(points[i].x, args.pointerCoords[i].getX());
1498 EXPECT_EQ(points[i].y, args.pointerCoords[i].getY());
1499 }
1500 }
1501
Arthur Hungaab25622020-01-16 11:22:11 +08001502 std::unique_ptr<UinputTouchScreen> mDevice;
Prabir Pradhanda20b172022-09-26 17:01:18 +00001503 InputDeviceInfo mDeviceInfo;
Arthur Hungaab25622020-01-16 11:22:11 +08001504};
1505
Prabir Pradhanf9a41282022-10-25 17:15:50 +00001506TEST_F(TouchIntegrationTest, MultiTouchDeviceSource) {
1507 // The UinputTouchScreen is an MT device that supports MT_TOOL_TYPE and also supports stylus
1508 // buttons. It should show up as a touchscreen, stylus, and keyboard (for reporting button
1509 // presses).
1510 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD,
1511 mDeviceInfo.getSources());
1512}
1513
Arthur Hungaab25622020-01-16 11:22:11 +08001514TEST_F(TouchIntegrationTest, InputEvent_ProcessSingleTouch) {
1515 NotifyMotionArgs args;
1516 const Point centerPoint = mDevice->getCenterPoint();
1517
1518 // ACTION_DOWN
Arthur Hung9ad18942021-06-19 02:04:46 +00001519 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001520 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001521 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001522 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1523 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1524
1525 // ACTION_MOVE
1526 mDevice->sendMove(centerPoint + Point(1, 1));
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001527 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001528 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1529 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1530
1531 // ACTION_UP
1532 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001533 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001534 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1535 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
1536}
1537
1538TEST_F(TouchIntegrationTest, InputEvent_ProcessMultiTouch) {
1539 NotifyMotionArgs args;
1540 const Point centerPoint = mDevice->getCenterPoint();
1541
1542 // ACTION_DOWN
Arthur Hung9ad18942021-06-19 02:04:46 +00001543 mDevice->sendSlot(FIRST_SLOT);
1544 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001545 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001546 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001547 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1548 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1549
1550 // ACTION_POINTER_DOWN (Second slot)
1551 const Point secondPoint = centerPoint + Point(100, 100);
1552 mDevice->sendSlot(SECOND_SLOT);
1553 mDevice->sendTrackingId(SECOND_TRACKING_ID);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001554 mDevice->sendDown(secondPoint);
1555 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001556 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001557 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001558
1559 // ACTION_MOVE (Second slot)
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001560 mDevice->sendMove(secondPoint + Point(1, 1));
1561 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001562 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1563 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1564
1565 // ACTION_POINTER_UP (Second slot)
arthurhungcc7f9802020-04-30 17:55:40 +08001566 mDevice->sendPointerUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001567 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001568 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001569 ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001570
1571 // ACTION_UP
1572 mDevice->sendSlot(FIRST_SLOT);
1573 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001574 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001575 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1576 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
1577}
1578
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001579/**
1580 * What happens when a pointer goes up while another pointer moves in the same frame? Are POINTER_UP
1581 * events guaranteed to contain the same data as a preceding MOVE, or can they contain different
1582 * data?
1583 * In this test, we try to send a change in coordinates in Pointer 0 in the same frame as the
1584 * liftoff of Pointer 1. We check that POINTER_UP event is generated first, and the MOVE event
1585 * for Pointer 0 only is generated after.
1586 * Suppose we are only interested in learning the movement of Pointer 0. If we only observe MOVE
1587 * events, we will not miss any information.
1588 * Even though the Pointer 1 up event contains updated Pointer 0 coordinates, there is another MOVE
1589 * event generated afterwards that contains the newest movement of pointer 0.
1590 * This is important for palm rejection. If there is a subsequent InputListener stage that detects
1591 * palms, and wants to cancel Pointer 1, then it is safe to simply drop POINTER_1_UP event without
1592 * losing information about non-palm pointers.
1593 */
1594TEST_F(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerUp) {
1595 NotifyMotionArgs args;
1596 const Point centerPoint = mDevice->getCenterPoint();
1597
1598 // ACTION_DOWN
1599 mDevice->sendSlot(FIRST_SLOT);
1600 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1601 mDevice->sendDown(centerPoint);
1602 mDevice->sendSync();
1603 assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
1604
1605 // ACTION_POINTER_DOWN (Second slot)
1606 const Point secondPoint = centerPoint + Point(100, 100);
1607 mDevice->sendSlot(SECOND_SLOT);
1608 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1609 mDevice->sendDown(secondPoint);
1610 mDevice->sendSync();
1611 assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
1612
1613 // ACTION_MOVE (First slot)
1614 mDevice->sendSlot(FIRST_SLOT);
1615 mDevice->sendMove(centerPoint + Point(5, 5));
1616 // ACTION_POINTER_UP (Second slot)
1617 mDevice->sendSlot(SECOND_SLOT);
1618 mDevice->sendPointerUp();
1619 // Send a single sync for the above 2 pointer updates
1620 mDevice->sendSync();
1621
1622 // First, we should get POINTER_UP for the second pointer
1623 assertReceivedMotion(ACTION_POINTER_1_UP,
1624 {/*first pointer */ centerPoint + Point(5, 5),
1625 /*second pointer*/ secondPoint});
1626
1627 // Next, the MOVE event for the first pointer
1628 assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
1629}
1630
1631/**
1632 * Similar scenario as above. The difference is that when the second pointer goes up, it will first
1633 * move, and then it will go up, all in the same frame.
1634 * In this scenario, the movement of the second pointer just prior to liftoff is ignored, and never
1635 * gets sent to the listener.
1636 */
1637TEST_F(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerMoveAndUp) {
1638 NotifyMotionArgs args;
1639 const Point centerPoint = mDevice->getCenterPoint();
1640
1641 // ACTION_DOWN
1642 mDevice->sendSlot(FIRST_SLOT);
1643 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1644 mDevice->sendDown(centerPoint);
1645 mDevice->sendSync();
1646 assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
1647
1648 // ACTION_POINTER_DOWN (Second slot)
1649 const Point secondPoint = centerPoint + Point(100, 100);
1650 mDevice->sendSlot(SECOND_SLOT);
1651 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1652 mDevice->sendDown(secondPoint);
1653 mDevice->sendSync();
1654 assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
1655
1656 // ACTION_MOVE (First slot)
1657 mDevice->sendSlot(FIRST_SLOT);
1658 mDevice->sendMove(centerPoint + Point(5, 5));
1659 // ACTION_POINTER_UP (Second slot)
1660 mDevice->sendSlot(SECOND_SLOT);
1661 mDevice->sendMove(secondPoint + Point(6, 6));
1662 mDevice->sendPointerUp();
1663 // Send a single sync for the above 2 pointer updates
1664 mDevice->sendSync();
1665
1666 // First, we should get POINTER_UP for the second pointer
1667 // The movement of the second pointer during the liftoff frame is ignored.
1668 // The coordinates 'secondPoint + Point(6, 6)' are never sent to the listener.
1669 assertReceivedMotion(ACTION_POINTER_1_UP,
1670 {/*first pointer */ centerPoint + Point(5, 5),
1671 /*second pointer*/ secondPoint});
1672
1673 // Next, the MOVE event for the first pointer
1674 assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
1675}
1676
Arthur Hungaab25622020-01-16 11:22:11 +08001677TEST_F(TouchIntegrationTest, InputEvent_ProcessPalm) {
1678 NotifyMotionArgs args;
1679 const Point centerPoint = mDevice->getCenterPoint();
1680
1681 // ACTION_DOWN
arthurhungcc7f9802020-04-30 17:55:40 +08001682 mDevice->sendSlot(FIRST_SLOT);
1683 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001684 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001685 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001686 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1687 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1688
arthurhungcc7f9802020-04-30 17:55:40 +08001689 // ACTION_POINTER_DOWN (second slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001690 const Point secondPoint = centerPoint + Point(100, 100);
1691 mDevice->sendSlot(SECOND_SLOT);
1692 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1693 mDevice->sendDown(secondPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001694 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001695 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001696 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001697
arthurhungcc7f9802020-04-30 17:55:40 +08001698 // ACTION_MOVE (second slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001699 mDevice->sendMove(secondPoint + Point(1, 1));
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001700 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001701 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1702 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1703
arthurhungcc7f9802020-04-30 17:55:40 +08001704 // Send MT_TOOL_PALM (second slot), which indicates that the touch IC has determined this to be
1705 // a palm event.
1706 // Expect to receive the ACTION_POINTER_UP with cancel flag.
Arthur Hungaab25622020-01-16 11:22:11 +08001707 mDevice->sendToolType(MT_TOOL_PALM);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001708 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001709 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001710 ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
arthurhungcc7f9802020-04-30 17:55:40 +08001711 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, args.flags);
Arthur Hungaab25622020-01-16 11:22:11 +08001712
arthurhungcc7f9802020-04-30 17:55:40 +08001713 // Send up to second slot, expect first slot send moving.
1714 mDevice->sendPointerUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001715 mDevice->sendSync();
arthurhungcc7f9802020-04-30 17:55:40 +08001716 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1717 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001718
arthurhungcc7f9802020-04-30 17:55:40 +08001719 // Send ACTION_UP (first slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001720 mDevice->sendSlot(FIRST_SLOT);
1721 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001722 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001723
arthurhungcc7f9802020-04-30 17:55:40 +08001724 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1725 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001726}
1727
Prabir Pradhanda20b172022-09-26 17:01:18 +00001728TEST_F(TouchIntegrationTest, NotifiesPolicyWhenStylusGestureStarted) {
1729 const Point centerPoint = mDevice->getCenterPoint();
1730
1731 // Send down with the pen tool selected. The policy should be notified of the stylus presence.
1732 mDevice->sendSlot(FIRST_SLOT);
1733 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1734 mDevice->sendToolType(MT_TOOL_PEN);
1735 mDevice->sendDown(centerPoint);
1736 mDevice->sendSync();
1737 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1738 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1739 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
1740
1741 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
1742
1743 // Release the stylus touch.
1744 mDevice->sendUp();
1745 mDevice->sendSync();
1746 ASSERT_NO_FATAL_FAILURE(
1747 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
1748
1749 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
1750
1751 // Touch down with the finger, without the pen tool selected. The policy is not notified.
1752 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1753 mDevice->sendToolType(MT_TOOL_FINGER);
1754 mDevice->sendDown(centerPoint);
1755 mDevice->sendSync();
1756 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1757 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1758 WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))));
1759
1760 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
1761
1762 mDevice->sendUp();
1763 mDevice->sendSync();
1764 ASSERT_NO_FATAL_FAILURE(
1765 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
1766
1767 // Send a move event with the stylus tool without BTN_TOUCH to generate a hover enter.
1768 // The policy should be notified of the stylus presence.
1769 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1770 mDevice->sendToolType(MT_TOOL_PEN);
1771 mDevice->sendMove(centerPoint);
1772 mDevice->sendSync();
1773 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1774 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1775 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
1776
1777 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
1778}
1779
Prabir Pradhan124ea442022-10-28 20:27:44 +00001780// --- StylusButtonIntegrationTest ---
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001781
Prabir Pradhan124ea442022-10-28 20:27:44 +00001782// Verify the behavior of button presses reported by various kinds of styluses, including buttons
1783// reported by the touchscreen's device, by a fused external stylus, and by an un-fused external
1784// stylus.
1785template <typename UinputStylusDevice>
1786class StylusButtonIntegrationTest : public TouchIntegrationTest {
1787protected:
1788 void SetUp() override {
1789#if !defined(__ANDROID__)
1790 GTEST_SKIP();
1791#endif
1792 TouchIntegrationTest::SetUp();
1793 mTouchscreen = mDevice.get();
1794 mTouchscreenInfo = mDeviceInfo;
1795
1796 setUpStylusDevice();
1797 }
1798
1799 UinputStylusDevice* mStylus{nullptr};
1800 InputDeviceInfo mStylusInfo{};
1801
1802 UinputTouchScreen* mTouchscreen{nullptr};
1803 InputDeviceInfo mTouchscreenInfo{};
1804
1805private:
1806 // When we are attempting to test stylus button events that are sent from the touchscreen,
1807 // use the same Uinput device for the touchscreen and the stylus.
1808 template <typename T = UinputStylusDevice>
1809 std::enable_if_t<std::is_same_v<UinputTouchScreen, T>, void> setUpStylusDevice() {
1810 mStylus = mDevice.get();
1811 mStylusInfo = mDeviceInfo;
1812 }
1813
1814 // When we are attempting to stylus buttons from an external stylus being merged with touches
1815 // from a touchscreen, create a new Uinput device through which stylus buttons can be injected.
1816 template <typename T = UinputStylusDevice>
1817 std::enable_if_t<!std::is_same_v<UinputTouchScreen, T>, void> setUpStylusDevice() {
1818 mStylusDeviceLifecycleTracker = createUinputDevice<T>();
1819 mStylus = mStylusDeviceLifecycleTracker.get();
1820 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1821 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1822 const auto info = findDeviceByName(mStylus->getName());
1823 ASSERT_TRUE(info);
1824 mStylusInfo = *info;
1825 }
1826
1827 std::unique_ptr<UinputStylusDevice> mStylusDeviceLifecycleTracker{};
1828
1829 // Hide the base class's device to expose it with a different name for readability.
1830 using TouchIntegrationTest::mDevice;
1831 using TouchIntegrationTest::mDeviceInfo;
1832};
1833
1834using StylusButtonIntegrationTestTypes =
1835 ::testing::Types<UinputTouchScreen, UinputExternalStylus, UinputExternalStylusWithPressure>;
1836TYPED_TEST_SUITE(StylusButtonIntegrationTest, StylusButtonIntegrationTestTypes);
1837
1838TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsGenerateKeyEvents) {
1839 const auto stylusId = TestFixture::mStylusInfo.getId();
1840
1841 TestFixture::mStylus->pressKey(BTN_STYLUS);
1842 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
1843 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
1844 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
1845
1846 TestFixture::mStylus->releaseKey(BTN_STYLUS);
1847 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001848 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001849 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001850}
1851
Prabir Pradhan124ea442022-10-28 20:27:44 +00001852TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsSurroundingTouchGesture) {
1853 const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
1854 const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
1855 const auto stylusId = TestFixture::mStylusInfo.getId();
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001856
1857 // Press the stylus button.
Prabir Pradhan124ea442022-10-28 20:27:44 +00001858 TestFixture::mStylus->pressKey(BTN_STYLUS);
1859 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001860 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001861 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001862
1863 // Start and finish a stylus gesture.
Prabir Pradhan124ea442022-10-28 20:27:44 +00001864 TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
1865 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
1866 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
1867 TestFixture::mTouchscreen->sendDown(centerPoint);
1868 TestFixture::mTouchscreen->sendSync();
1869 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001870 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1871 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001872 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
1873 WithDeviceId(touchscreenId))));
1874 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001875 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
1876 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001877 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
1878 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001879
Prabir Pradhan124ea442022-10-28 20:27:44 +00001880 TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
1881 TestFixture::mTouchscreen->sendSync();
1882 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001883 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001884 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
1885 WithDeviceId(touchscreenId))));
1886 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001887 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001888 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
1889 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001890
1891 // Release the stylus button.
Prabir Pradhan124ea442022-10-28 20:27:44 +00001892 TestFixture::mStylus->releaseKey(BTN_STYLUS);
1893 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001894 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001895 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001896}
1897
Prabir Pradhan9a561c22022-11-07 16:11:23 +00001898TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsSurroundingHoveringTouchGesture) {
1899 const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
1900 const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
1901 const auto stylusId = TestFixture::mStylusInfo.getId();
1902 auto toolTypeDevice =
1903 AllOf(WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithDeviceId(touchscreenId));
1904
1905 // Press the stylus button.
1906 TestFixture::mStylus->pressKey(BTN_STYLUS);
1907 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
1908 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
1909 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
1910
1911 // Start hovering with the stylus.
1912 TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
1913 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
1914 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
1915 TestFixture::mTouchscreen->sendMove(centerPoint);
1916 TestFixture::mTouchscreen->sendSync();
1917 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1918 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1919 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1920 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1921 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
1922 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1923 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1924 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
1925 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1926
1927 // Touch down with the stylus.
1928 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
1929 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
1930 TestFixture::mTouchscreen->sendDown(centerPoint);
1931 TestFixture::mTouchscreen->sendSync();
1932 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1933 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
1934 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1935
1936 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1937 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1938 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1939
1940 // Stop touching with the stylus, and start hovering.
1941 TestFixture::mTouchscreen->sendUp();
1942 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
1943 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
1944 TestFixture::mTouchscreen->sendMove(centerPoint);
1945 TestFixture::mTouchscreen->sendSync();
1946 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1947 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_UP),
1948 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1949 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1950 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1951 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1952 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1953 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
1954 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1955
1956 // Stop hovering.
1957 TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
1958 TestFixture::mTouchscreen->sendSync();
1959 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1960 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
1961 WithButtonState(0))));
1962 // TODO(b/257971675): Fix inconsistent button state when exiting hover.
1963 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1964 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
1965 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1966
1967 // Release the stylus button.
1968 TestFixture::mStylus->releaseKey(BTN_STYLUS);
1969 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
1970 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
1971 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
1972}
1973
Prabir Pradhan124ea442022-10-28 20:27:44 +00001974TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsWithinTouchGesture) {
1975 const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
1976 const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
1977 const auto stylusId = TestFixture::mStylusInfo.getId();
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001978
1979 // Start a stylus gesture.
Prabir Pradhan124ea442022-10-28 20:27:44 +00001980 TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
1981 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
1982 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
1983 TestFixture::mTouchscreen->sendDown(centerPoint);
1984 TestFixture::mTouchscreen->sendSync();
1985 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001986 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001987 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
1988 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001989
1990 // Press and release a stylus button. Each change in button state also generates a MOVE event.
Prabir Pradhan124ea442022-10-28 20:27:44 +00001991 TestFixture::mStylus->pressKey(BTN_STYLUS);
1992 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001993 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001994 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
1995 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001996 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
1997 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001998 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
1999 WithDeviceId(touchscreenId))));
2000 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002001 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
2002 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002003 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2004 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002005
Prabir Pradhan124ea442022-10-28 20:27:44 +00002006 TestFixture::mStylus->releaseKey(BTN_STYLUS);
2007 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002008 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002009 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2010 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002011 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002012 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
2013 WithDeviceId(touchscreenId))));
2014 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002015 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002016 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
2017 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002018
2019 // Finish the stylus gesture.
Prabir Pradhan124ea442022-10-28 20:27:44 +00002020 TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
2021 TestFixture::mTouchscreen->sendSync();
2022 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002023 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002024 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
2025 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002026}
2027
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002028// --- ExternalStylusIntegrationTest ---
2029
2030// Verify the behavior of an external stylus. An external stylus can report pressure or button
2031// data independently of the touchscreen, which is then sent as a MotionEvent as part of an
2032// ongoing stylus gesture that is being emitted by the touchscreen.
2033using ExternalStylusIntegrationTest = TouchIntegrationTest;
2034
2035TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureReported) {
2036 const Point centerPoint = mDevice->getCenterPoint();
2037
2038 // Create an external stylus capable of reporting pressure data that
2039 // should be fused with a touch pointer.
2040 std::unique_ptr<UinputExternalStylusWithPressure> stylus =
2041 createUinputDevice<UinputExternalStylusWithPressure>();
2042 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2043 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2044 const auto stylusInfo = findDeviceByName(stylus->getName());
2045 ASSERT_TRUE(stylusInfo);
2046
2047 ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2048
2049 const auto touchscreenId = mDeviceInfo.getId();
2050
2051 // Set a pressure value on the stylus. It doesn't generate any events.
2052 const auto& RAW_PRESSURE_MAX = UinputExternalStylusWithPressure::RAW_PRESSURE_MAX;
2053 stylus->setPressure(100);
2054 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2055
2056 // Start a finger gesture, and ensure it shows up as stylus gesture
2057 // with the pressure set by the external stylus.
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002058 mDevice->sendSlot(FIRST_SLOT);
Chris Ye1b0c7342020-07-28 21:57:03 -07002059 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002060 mDevice->sendToolType(MT_TOOL_FINGER);
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00002061 mDevice->sendDown(centerPoint);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002062 mDevice->sendSync();
2063 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2064 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002065 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
2066 WithDeviceId(touchscreenId), WithPressure(100.f / RAW_PRESSURE_MAX))));
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002067
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002068 // Change the pressure on the external stylus, and ensure the touchscreen generates a MOVE
2069 // event with the updated pressure.
2070 stylus->setPressure(200);
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +00002071 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2072 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002073 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
2074 WithDeviceId(touchscreenId), WithPressure(200.f / RAW_PRESSURE_MAX))));
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002075
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002076 // The external stylus did not generate any events.
2077 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2078 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
2079}
2080
2081TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureNotReported) {
2082 const Point centerPoint = mDevice->getCenterPoint();
2083
2084 // Create an external stylus capable of reporting pressure data that
2085 // should be fused with a touch pointer.
2086 std::unique_ptr<UinputExternalStylusWithPressure> stylus =
2087 createUinputDevice<UinputExternalStylusWithPressure>();
2088 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2089 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2090 const auto stylusInfo = findDeviceByName(stylus->getName());
2091 ASSERT_TRUE(stylusInfo);
2092
2093 ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2094
2095 const auto touchscreenId = mDeviceInfo.getId();
2096
2097 // Set a pressure value of 0 on the stylus. It doesn't generate any events.
2098 const auto& RAW_PRESSURE_MAX = UinputExternalStylusWithPressure::RAW_PRESSURE_MAX;
Prabir Pradhan3f7545f2022-10-19 16:56:39 +00002099 // Send a non-zero value first to prevent the kernel from consuming the zero event.
2100 stylus->setPressure(100);
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002101 stylus->setPressure(0);
Prabir Pradhan3f7545f2022-10-19 16:56:39 +00002102 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002103
2104 // Start a finger gesture. The touch device will withhold generating any touches for
2105 // up to 72 milliseconds while waiting for pressure data from the external stylus.
2106 mDevice->sendSlot(FIRST_SLOT);
2107 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2108 mDevice->sendToolType(MT_TOOL_FINGER);
2109 mDevice->sendDown(centerPoint);
2110 auto waitUntil = std::chrono::system_clock::now() +
2111 std::chrono::milliseconds(ns2ms(EXTERNAL_STYLUS_DATA_TIMEOUT));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07002112 mDevice->sendSync();
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002113 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled(waitUntil));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002114
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002115 // Since the external stylus did not report a pressure value within the timeout,
2116 // it shows up as a finger pointer.
2117 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2118 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2119 WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER), WithDeviceId(touchscreenId),
2120 WithPressure(1.f))));
2121
2122 // Change the pressure on the external stylus. Since the pressure was not present at the start
2123 // of the gesture, it is ignored for now.
2124 stylus->setPressure(200);
2125 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2126
2127 // Finish the finger gesture.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002128 mDevice->sendTrackingId(INVALID_TRACKING_ID);
2129 mDevice->sendSync();
2130 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2131 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002132 WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))));
2133
2134 // Start a new gesture. Since we have a valid pressure value, it shows up as a stylus.
2135 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2136 mDevice->sendToolType(MT_TOOL_FINGER);
2137 mDevice->sendDown(centerPoint);
2138 mDevice->sendSync();
2139 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2140 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2141 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
2142 WithDeviceId(touchscreenId), WithPressure(200.f / RAW_PRESSURE_MAX))));
2143
2144 // The external stylus did not generate any events.
2145 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2146 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002147}
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00002148
Prabir Pradhan3f7545f2022-10-19 16:56:39 +00002149TEST_F(ExternalStylusIntegrationTest, UnfusedExternalStylus) {
2150 const Point centerPoint = mDevice->getCenterPoint();
2151
2152 // Create an external stylus device that does not support pressure. It should not affect any
2153 // touch pointers.
2154 std::unique_ptr<UinputExternalStylus> stylus = createUinputDevice<UinputExternalStylus>();
2155 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2156 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2157 const auto stylusInfo = findDeviceByName(stylus->getName());
2158 ASSERT_TRUE(stylusInfo);
2159
2160 ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2161
2162 const auto touchscreenId = mDeviceInfo.getId();
2163
2164 // Start a finger gesture and ensure a finger pointer is generated for it, without waiting for
2165 // pressure data from the external stylus.
2166 mDevice->sendSlot(FIRST_SLOT);
2167 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2168 mDevice->sendToolType(MT_TOOL_FINGER);
2169 mDevice->sendDown(centerPoint);
2170 auto waitUntil = std::chrono::system_clock::now() +
2171 std::chrono::milliseconds(ns2ms(EXTERNAL_STYLUS_DATA_TIMEOUT));
2172 mDevice->sendSync();
2173 ASSERT_NO_FATAL_FAILURE(
2174 mTestListener
2175 ->assertNotifyMotionWasCalled(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2176 WithToolType(
2177 AMOTION_EVENT_TOOL_TYPE_FINGER),
2178 WithButtonState(0),
2179 WithDeviceId(touchscreenId),
2180 WithPressure(1.f)),
2181 waitUntil));
2182
2183 // The external stylus did not generate any events.
2184 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2185 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
2186}
2187
Michael Wrightd02c5b62014-02-10 15:10:22 -08002188// --- InputDeviceTest ---
2189class InputDeviceTest : public testing::Test {
2190protected:
2191 static const char* DEVICE_NAME;
2192 static const char* DEVICE_LOCATION;
2193 static const int32_t DEVICE_ID;
2194 static const int32_t DEVICE_GENERATION;
2195 static const int32_t DEVICE_CONTROLLER_NUMBER;
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01002196 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002197 static const int32_t EVENTHUB_ID;
2198 static const std::string DEVICE_BLUETOOTH_ADDRESS;
2199
2200 std::shared_ptr<FakeEventHub> mFakeEventHub;
2201 sp<FakeInputReaderPolicy> mFakePolicy;
2202 std::unique_ptr<TestInputListener> mFakeListener;
2203 std::unique_ptr<InstrumentedInputReader> mReader;
2204 std::shared_ptr<InputDevice> mDevice;
2205
2206 void SetUp() override {
2207 mFakeEventHub = std::make_unique<FakeEventHub>();
2208 mFakePolicy = sp<FakeInputReaderPolicy>::make();
2209 mFakeListener = std::make_unique<TestInputListener>();
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002210 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002211 *mFakeListener);
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002212 InputDeviceIdentifier identifier;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002213 identifier.name = DEVICE_NAME;
2214 identifier.location = DEVICE_LOCATION;
2215 identifier.bluetoothAddress = DEVICE_BLUETOOTH_ADDRESS;
2216 mDevice = std::make_shared<InputDevice>(mReader->getContext(), DEVICE_ID, DEVICE_GENERATION,
2217 identifier);
2218 mReader->pushNextDevice(mDevice);
2219 mFakeEventHub->addDevice(EVENTHUB_ID, DEVICE_NAME, ftl::Flags<InputDeviceClass>(0));
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002220 mReader->loopOnce();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002221 }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002222
2223 void TearDown() override {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002224 mFakeListener.reset();
2225 mFakePolicy.clear();
2226 }
2227};
2228
2229const char* InputDeviceTest::DEVICE_NAME = "device";
2230const char* InputDeviceTest::DEVICE_LOCATION = "USB1";
2231const int32_t InputDeviceTest::DEVICE_ID = END_RESERVED_ID + 1000;
2232const int32_t InputDeviceTest::DEVICE_GENERATION = 2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002233const int32_t InputDeviceTest::DEVICE_CONTROLLER_NUMBER = 0;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002234const ftl::Flags<InputDeviceClass> InputDeviceTest::DEVICE_CLASSES =
2235 InputDeviceClass::KEYBOARD | InputDeviceClass::TOUCH | InputDeviceClass::JOYSTICK;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002236const int32_t InputDeviceTest::EVENTHUB_ID = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002237const std::string InputDeviceTest::DEVICE_BLUETOOTH_ADDRESS = "11:AA:22:BB:33:CC";
2238
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002239TEST_F(InputDeviceTest, ImmutableProperties) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002240 ASSERT_EQ(DEVICE_ID, mDevice->getId());
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002241 ASSERT_STREQ(DEVICE_NAME, mDevice->getName().c_str());
2242 ASSERT_EQ(ftl::Flags<InputDeviceClass>(0), mDevice->getClasses());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002243}
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002244
Michael Wrightd02c5b62014-02-10 15:10:22 -08002245TEST_F(InputDeviceTest, CountryCodeCorrectlyMapped) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002246 mFakeEventHub->setCountryCode(EVENTHUB_ID, InputDeviceCountryCode::INTERNATIONAL);
2247
Michael Wrightd02c5b62014-02-10 15:10:22 -08002248 // Configuration
2249 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002250 InputReaderConfiguration config;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002251 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
2252
Michael Wrightd02c5b62014-02-10 15:10:22 -08002253 ASSERT_EQ(InputDeviceCountryCode::INTERNATIONAL, mDevice->getDeviceInfo().getCountryCode());
2254}
2255
2256TEST_F(InputDeviceTest, WhenDeviceCreated_EnabledIsFalse) {
2257 ASSERT_EQ(mDevice->isEnabled(), false);
2258}
2259
2260TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
2261 // Configuration.
2262 InputReaderConfiguration config;
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00002263 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002264
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01002265 // Reset.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002266 unused += mDevice->reset(ARBITRARY_TIME);
2267
2268 NotifyDeviceResetArgs resetArgs;
2269 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2270 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
2271 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
2272
2273 // Metadata.
2274 ASSERT_TRUE(mDevice->isIgnored());
2275 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mDevice->getSources());
2276
2277 InputDeviceInfo info = mDevice->getDeviceInfo();
2278 ASSERT_EQ(DEVICE_ID, info.getId());
2279 ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
2280 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType());
2281 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources());
2282
2283 // State queries.
2284 ASSERT_EQ(0, mDevice->getMetaState());
2285
2286 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, 0))
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002287 << "Ignored device should return unknown key code state.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002288 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 0))
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002289 << "Ignored device should return unknown scan code state.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002290 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 0))
2291 << "Ignored device should return unknown switch state.";
2292
2293 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B};
2294 uint8_t flags[2] = { 0, 1 };
2295 ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, keyCodes, flags))
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002296 << "Ignored device should never mark any key codes.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002297 ASSERT_EQ(0, flags[0]) << "Flag for unsupported key should be unchanged.";
2298 ASSERT_EQ(1, flags[1]) << "Flag for unsupported key should be unchanged.";
2299}
2300
2301TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) {
2302 // Configuration.
2303 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "key", "value");
2304
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002305 FakeInputMapper& mapper1 =
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002306 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002307 mapper1.setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002308 mapper1.setMetaState(AMETA_ALT_ON);
2309 mapper1.addSupportedKeyCode(AKEYCODE_A);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002310 mapper1.addSupportedKeyCode(AKEYCODE_B);
2311 mapper1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002312 mapper1.setKeyCodeState(AKEYCODE_B, AKEY_STATE_UP);
2313 mapper1.setScanCodeState(2, AKEY_STATE_DOWN);
2314 mapper1.setScanCodeState(3, AKEY_STATE_UP);
2315 mapper1.setSwitchState(4, AKEY_STATE_DOWN);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002316
Arthur Hung2c9a3342019-07-23 14:18:59 +08002317 FakeInputMapper& mapper2 =
2318 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_TOUCHSCREEN);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002319 mapper2.setMetaState(AMETA_SHIFT_ON);
2320
Arthur Hung2c9a3342019-07-23 14:18:59 +08002321 InputReaderConfiguration config;
2322 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
2323
2324 std::string propertyValue;
2325 ASSERT_TRUE(mDevice->getConfiguration().tryGetProperty("key", propertyValue))
2326 << "Device should have read configuration during configuration phase.";
2327 ASSERT_EQ("value", propertyValue);
2328
2329 ASSERT_NO_FATAL_FAILURE(mapper1.assertConfigureWasCalled());
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002330 ASSERT_NO_FATAL_FAILURE(mapper2.assertConfigureWasCalled());
2331
Arthur Hung2c9a3342019-07-23 14:18:59 +08002332 // Reset
2333 unused += mDevice->reset(ARBITRARY_TIME);
2334 ASSERT_NO_FATAL_FAILURE(mapper1.assertResetWasCalled());
2335 ASSERT_NO_FATAL_FAILURE(mapper2.assertResetWasCalled());
2336
2337 NotifyDeviceResetArgs resetArgs;
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00002338 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2339 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002340 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
2341
Arthur Hung2c9a3342019-07-23 14:18:59 +08002342 // Metadata.
2343 ASSERT_FALSE(mDevice->isIgnored());
2344 ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), mDevice->getSources());
2345
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002346 InputDeviceInfo info = mDevice->getDeviceInfo();
2347 ASSERT_EQ(DEVICE_ID, info.getId());
Arthur Hung2c9a3342019-07-23 14:18:59 +08002348 ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
2349 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType());
2350 ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources());
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002351
2352 // State queries.
Arthur Hung2c9a3342019-07-23 14:18:59 +08002353 ASSERT_EQ(AMETA_ALT_ON | AMETA_SHIFT_ON, mDevice->getMetaState())
2354 << "Should query mappers and combine meta states.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002355
Christine Franks1ba71cc2021-04-07 14:37:42 -07002356 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2357 << "Should return unknown key code state when source not supported.";
2358 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2359 << "Should return unknown scan code state when source not supported.";
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002360 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2361 << "Should return unknown switch state when source not supported.";
Christine Franks1ba71cc2021-04-07 14:37:42 -07002362
2363 ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, AKEYCODE_A))
2364 << "Should query mapper when source is supported.";
2365 ASSERT_EQ(AKEY_STATE_UP, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 3))
Christine Franks2a2293c2022-01-18 11:51:16 -08002366 << "Should query mapper when source is supported.";
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002367 ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 4))
2368 << "Should query mapper when source is supported.";
Christine Franks1ba71cc2021-04-07 14:37:42 -07002369
2370 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2};
2371 uint8_t flags[4] = { 0, 0, 0, 1 };
2372 ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
2373 << "Should do nothing when source is unsupported.";
2374 ASSERT_EQ(0, flags[0]) << "Flag should be unchanged when source is unsupported.";
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002375 ASSERT_EQ(0, flags[1]) << "Flag should be unchanged when source is unsupported.";
2376 ASSERT_EQ(0, flags[2]) << "Flag should be unchanged when source is unsupported.";
Christine Franks1ba71cc2021-04-07 14:37:42 -07002377 ASSERT_EQ(1, flags[3]) << "Flag should be unchanged when source is unsupported.";
2378
2379 ASSERT_TRUE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, keyCodes, flags))
2380 << "Should query mapper when source is supported.";
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002381 ASSERT_EQ(1, flags[0]) << "Flag for supported key should be set.";
2382 ASSERT_EQ(1, flags[1]) << "Flag for supported key should be set.";
Christine Franks1ba71cc2021-04-07 14:37:42 -07002383 ASSERT_EQ(0, flags[2]) << "Flag for unsupported key should be unchanged.";
2384 ASSERT_EQ(1, flags[3]) << "Flag for unsupported key should be unchanged.";
2385
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002386 // Event handling.
2387 RawEvent event;
Christine Franks1ba71cc2021-04-07 14:37:42 -07002388 event.deviceId = EVENTHUB_ID;
2389 unused += mDevice->process(&event, 1);
2390
Christine Franks2a2293c2022-01-18 11:51:16 -08002391 ASSERT_NO_FATAL_FAILURE(mapper1.assertProcessWasCalled());
2392 ASSERT_NO_FATAL_FAILURE(mapper2.assertProcessWasCalled());
2393}
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002394
2395// A single input device is associated with a specific display. Check that:
Christine Franks2a2293c2022-01-18 11:51:16 -08002396// 1. Device is disabled if the viewport corresponding to the associated display is not found
Christine Franks2a2293c2022-01-18 11:51:16 -08002397// 2. Device is disabled when setEnabled API is called
2398TEST_F(InputDeviceTest, Configure_AssignsDisplayPort) {
2399 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_TOUCHSCREEN);
2400
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002401 // First Configuration.
2402 std::list<NotifyArgs> unused =
Christine Franks2a2293c2022-01-18 11:51:16 -08002403 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
2404
2405 // Device should be enabled by default.
Siarhei Vishniakou30feb8c2022-09-28 10:48:29 -07002406 ASSERT_TRUE(mDevice->isEnabled());
2407
2408 // Prepare associated info.
2409 constexpr uint8_t hdmi = 1;
2410 const std::string UNIQUE_ID = "local:1";
2411
2412 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi);
2413 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2414 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2415 // Device should be disabled because it is associated with a specific display via
2416 // input port <-> display port association, but the corresponding display is not found
2417 ASSERT_FALSE(mDevice->isEnabled());
2418
2419 // Prepare displays.
2420 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +00002421 ui::ROTATION_0, true /*isActive*/, UNIQUE_ID, hdmi,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002422 ViewportType::INTERNAL);
2423 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2424 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2425 ASSERT_TRUE(mDevice->isEnabled());
2426
2427 // Device should be disabled after set disable.
2428 mFakePolicy->addDisabledDevice(mDevice->getId());
2429 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2430 InputReaderConfiguration::CHANGE_ENABLED_STATE);
2431 ASSERT_FALSE(mDevice->isEnabled());
2432
2433 // Device should still be disabled even found the associated display.
2434 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2435 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2436 ASSERT_FALSE(mDevice->isEnabled());
2437}
2438
2439TEST_F(InputDeviceTest, Configure_AssignsDisplayUniqueId) {
2440 // Device should be enabled by default.
2441 mFakePolicy->clearViewports();
2442 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
2443 std::list<NotifyArgs> unused =
2444 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
2445 ASSERT_TRUE(mDevice->isEnabled());
2446
2447 // Device should be disabled because it is associated with a specific display, but the
2448 // corresponding display is not found.
2449 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
2450 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2451 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2452 ASSERT_FALSE(mDevice->isEnabled());
2453
2454 // Device should be enabled when a display is found.
2455 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +00002456 ui::ROTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002457 NO_PORT, ViewportType::INTERNAL);
2458 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2459 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2460 ASSERT_TRUE(mDevice->isEnabled());
2461
2462 // Device should be disabled after set disable.
2463 mFakePolicy->addDisabledDevice(mDevice->getId());
2464 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2465 InputReaderConfiguration::CHANGE_ENABLED_STATE);
2466 ASSERT_FALSE(mDevice->isEnabled());
2467
2468 // Device should still be disabled even found the associated display.
2469 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2470 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2471 ASSERT_FALSE(mDevice->isEnabled());
2472}
2473
2474TEST_F(InputDeviceTest, Configure_UniqueId_CorrectlyMatches) {
2475 mFakePolicy->clearViewports();
2476 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
2477 std::list<NotifyArgs> unused =
2478 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07002479
Michael Wrightd02c5b62014-02-10 15:10:22 -08002480 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
2481 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +00002482 ui::ROTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID,
Chris Ye1b0c7342020-07-28 21:57:03 -07002483 NO_PORT, ViewportType::INTERNAL);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002484 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002485 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07002486 ASSERT_EQ(DISPLAY_UNIQUE_ID, mDevice->getAssociatedDisplayUniqueId());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002487}
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002488
arthurhungdcef2dc2020-08-11 14:47:50 +08002489/**
2490 * This test reproduces a crash caused by a dangling reference that remains after device is added
Michael Wrightd02c5b62014-02-10 15:10:22 -08002491 * and removed. The reference is accessed in InputDevice::dump(..);
Chris Ye1b0c7342020-07-28 21:57:03 -07002492 */
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07002493TEST_F(InputDeviceTest, DumpDoesNotCrash) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002494 constexpr int32_t TEST_EVENTHUB_ID = 10;
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002495 mFakeEventHub->addDevice(TEST_EVENTHUB_ID, "Test EventHub device", InputDeviceClass::BATTERY);
arthurhungdcef2dc2020-08-11 14:47:50 +08002496
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002497 InputDevice device(mReader->getContext(), 1 /*id*/, 2 /*generation*/, {} /*identifier*/);
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002498 device.addEventHubDevice(TEST_EVENTHUB_ID, true /*populateMappers*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002499 device.removeEventHubDevice(TEST_EVENTHUB_ID);
2500 std::string dumpStr, eventHubDevStr;
2501 device.dump(dumpStr, eventHubDevStr);
2502}
2503
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00002504TEST_F(InputDeviceTest, GetBluetoothAddress) {
2505 const auto& address = mReader->getBluetoothAddress(DEVICE_ID);
2506 ASSERT_TRUE(address);
2507 ASSERT_EQ(DEVICE_BLUETOOTH_ADDRESS, *address);
2508}
2509
Michael Wrightd02c5b62014-02-10 15:10:22 -08002510// --- InputMapperTest ---
2511
2512class InputMapperTest : public testing::Test {
2513protected:
2514 static const char* DEVICE_NAME;
2515 static const char* DEVICE_LOCATION;
2516 static const int32_t DEVICE_ID;
2517 static const int32_t DEVICE_GENERATION;
2518 static const int32_t DEVICE_CONTROLLER_NUMBER;
2519 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
2520 static const int32_t EVENTHUB_ID;
2521
2522 std::shared_ptr<FakeEventHub> mFakeEventHub;
2523 sp<FakeInputReaderPolicy> mFakePolicy;
2524 std::unique_ptr<TestInputListener> mFakeListener;
2525 std::unique_ptr<InstrumentedInputReader> mReader;
2526 std::shared_ptr<InputDevice> mDevice;
2527
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002528 virtual void SetUp(ftl::Flags<InputDeviceClass> classes, int bus = 0) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002529 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07002530 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou473174e2017-12-27 16:44:42 -08002531 mFakeListener = std::make_unique<TestInputListener>();
arthurhungdcef2dc2020-08-11 14:47:50 +08002532 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
2533 *mFakeListener);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002534 mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes, bus);
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002535 // Consume the device reset notification generated when adding a new device.
2536 mFakeListener->assertNotifyDeviceResetWasCalled();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002537 }
2538
Prabir Pradhanc14266f2021-05-12 15:56:24 -07002539 void SetUp() override {
Prabir Pradhanc14266f2021-05-12 15:56:24 -07002540 SetUp(DEVICE_CLASSES);
2541 }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002542
Chris Yea52ade12020-08-27 16:49:20 -07002543 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002544 mFakeListener.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002545 mFakePolicy.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002546 }
2547
2548 void addConfigurationProperty(const char* key, const char* value) {
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002549 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, key, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002550 }
2551
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002552 std::list<NotifyArgs> configureDevice(uint32_t changes) {
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00002553 if (!changes ||
2554 (changes &
2555 (InputReaderConfiguration::CHANGE_DISPLAY_INFO |
2556 InputReaderConfiguration::CHANGE_POINTER_CAPTURE))) {
arthurhungdcef2dc2020-08-11 14:47:50 +08002557 mReader->requestRefreshConfiguration(changes);
2558 mReader->loopOnce();
Prabir Pradhanc7ef27e2020-02-03 19:19:15 -08002559 }
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002560 std::list<NotifyArgs> out =
2561 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes);
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002562 // Loop the reader to flush the input listener queue.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002563 for (const NotifyArgs& args : out) {
2564 mFakeListener->notify(args);
2565 }
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002566 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002567 return out;
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08002568 }
2569
arthurhungdcef2dc2020-08-11 14:47:50 +08002570 std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
2571 const std::string& location, int32_t eventHubId,
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002572 ftl::Flags<InputDeviceClass> classes, int bus = 0) {
arthurhungdcef2dc2020-08-11 14:47:50 +08002573 InputDeviceIdentifier identifier;
2574 identifier.name = name;
2575 identifier.location = location;
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002576 identifier.bus = bus;
arthurhungdcef2dc2020-08-11 14:47:50 +08002577 std::shared_ptr<InputDevice> device =
2578 std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
2579 identifier);
2580 mReader->pushNextDevice(device);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002581 mFakeEventHub->addDevice(eventHubId, name, classes, bus);
arthurhungdcef2dc2020-08-11 14:47:50 +08002582 mReader->loopOnce();
2583 return device;
2584 }
2585
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002586 template <class T, typename... Args>
2587 T& addMapperAndConfigure(Args... args) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002588 T& mapper = mDevice->addMapper<T>(EVENTHUB_ID, args...);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08002589 configureDevice(0);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002590 std::list<NotifyArgs> resetArgList = mDevice->reset(ARBITRARY_TIME);
2591 resetArgList += mapper.reset(ARBITRARY_TIME);
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002592 // Loop the reader to flush the input listener queue.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002593 for (const NotifyArgs& loopArgs : resetArgList) {
2594 mFakeListener->notify(loopArgs);
2595 }
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002596 mReader->loopOnce();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002597 return mapper;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002598 }
2599
2600 void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
Michael Wrighta9cf4192022-12-01 23:46:39 +00002601 ui::Rotation orientation, const std::string& uniqueId,
2602 std::optional<uint8_t> physicalPort,
2603 ViewportType viewportType) {
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00002604 mFakePolicy->addDisplayViewport(displayId, width, height, orientation, true /*isActive*/,
2605 uniqueId, physicalPort, viewportType);
Santos Cordonfa5cf462017-04-05 10:37:00 -07002606 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2607 }
2608
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002609 void clearViewports() {
2610 mFakePolicy->clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002611 }
2612
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002613 std::list<NotifyArgs> process(InputMapper& mapper, nsecs_t when, nsecs_t readTime, int32_t type,
2614 int32_t code, int32_t value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002615 RawEvent event;
2616 event.when = when;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002617 event.readTime = readTime;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002618 event.deviceId = mapper.getDeviceContext().getEventHubId();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002619 event.type = type;
2620 event.code = code;
2621 event.value = value;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002622 std::list<NotifyArgs> processArgList = mapper.process(&event);
2623 for (const NotifyArgs& args : processArgList) {
2624 mFakeListener->notify(args);
2625 }
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002626 // Loop the reader to flush the input listener queue.
arthurhungdcef2dc2020-08-11 14:47:50 +08002627 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002628 return processArgList;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002629 }
2630
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00002631 void resetMapper(InputMapper& mapper, nsecs_t when) {
2632 const auto resetArgs = mapper.reset(when);
Michael Wrighta9cf4192022-12-01 23:46:39 +00002633 for (const auto& args : resetArgs) {
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00002634 mFakeListener->notify(args);
2635 }
2636 // Loop the reader to flush the input listener queue.
2637 mReader->loopOnce();
2638 }
2639
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00002640 std::list<NotifyArgs> handleTimeout(InputMapper& mapper, nsecs_t when) {
2641 std::list<NotifyArgs> generatedArgs = mapper.timeoutExpired(when);
2642 for (const NotifyArgs& args : generatedArgs) {
2643 mFakeListener->notify(args);
2644 }
2645 // Loop the reader to flush the input listener queue.
2646 mReader->loopOnce();
2647 return generatedArgs;
2648 }
2649
Michael Wrightd02c5b62014-02-10 15:10:22 -08002650 static void assertMotionRange(const InputDeviceInfo& info,
2651 int32_t axis, uint32_t source, float min, float max, float flat, float fuzz) {
2652 const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source);
Yi Kong9b14ac62018-07-17 13:48:38 -07002653 ASSERT_TRUE(range != nullptr) << "Axis: " << axis << " Source: " << source;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002654 ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source;
2655 ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source;
2656 ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source;
2657 ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source;
2658 ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source;
2659 ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source;
2660 }
2661
Prabir Pradhanf5334b82021-05-13 14:00:39 -07002662 static void assertPointerCoords(const PointerCoords& coords, float x, float y, float pressure,
2663 float size, float touchMajor, float touchMinor, float toolMajor,
2664 float toolMinor, float orientation, float distance,
2665 float scaledAxisEpsilon = 1.f) {
2666 ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), scaledAxisEpsilon);
2667 ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), scaledAxisEpsilon);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002668 ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON);
2669 ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07002670 ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2671 scaledAxisEpsilon);
2672 ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2673 scaledAxisEpsilon);
2674 ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2675 scaledAxisEpsilon);
2676 ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2677 scaledAxisEpsilon);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002678 ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON);
2679 ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON);
2680 }
2681
Michael Wright17db18e2020-06-26 20:51:44 +01002682 static void assertPosition(const FakePointerController& controller, float x, float y) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002683 float actualX, actualY;
Michael Wright17db18e2020-06-26 20:51:44 +01002684 controller.getPosition(&actualX, &actualY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002685 ASSERT_NEAR(x, actualX, 1);
2686 ASSERT_NEAR(y, actualY, 1);
2687 }
2688};
2689
2690const char* InputMapperTest::DEVICE_NAME = "device";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07002691const char* InputMapperTest::DEVICE_LOCATION = "USB1";
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002692const int32_t InputMapperTest::DEVICE_ID = END_RESERVED_ID + 1000;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002693const int32_t InputMapperTest::DEVICE_GENERATION = 2;
2694const int32_t InputMapperTest::DEVICE_CONTROLLER_NUMBER = 0;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002695const ftl::Flags<InputDeviceClass> InputMapperTest::DEVICE_CLASSES =
2696 ftl::Flags<InputDeviceClass>(0); // not needed for current tests
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002697const int32_t InputMapperTest::EVENTHUB_ID = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002698
2699// --- SwitchInputMapperTest ---
2700
2701class SwitchInputMapperTest : public InputMapperTest {
2702protected:
2703};
2704
2705TEST_F(SwitchInputMapperTest, GetSources) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002706 SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002707
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002708 ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002709}
2710
2711TEST_F(SwitchInputMapperTest, GetSwitchState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002712 SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002713
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002714 mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002715 ASSERT_EQ(1, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002716
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002717 mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002718 ASSERT_EQ(0, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002719}
2720
2721TEST_F(SwitchInputMapperTest, Process) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002722 SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002723 std::list<NotifyArgs> out;
2724 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_LID, 1);
2725 ASSERT_TRUE(out.empty());
2726 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_JACK_PHYSICAL_INSERT, 1);
2727 ASSERT_TRUE(out.empty());
2728 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_HEADPHONE_INSERT, 0);
2729 ASSERT_TRUE(out.empty());
2730 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002731
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002732 ASSERT_EQ(1u, out.size());
2733 const NotifySwitchArgs& args = std::get<NotifySwitchArgs>(*out.begin());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002734 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
Dan Albert1bd2fc02016-02-02 15:11:57 -08002735 ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT), args.switchValues);
2736 ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT) | (1 << SW_HEADPHONE_INSERT),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002737 args.switchMask);
2738 ASSERT_EQ(uint32_t(0), args.policyFlags);
2739}
2740
Chris Ye87143712020-11-10 05:05:58 +00002741// --- VibratorInputMapperTest ---
2742class VibratorInputMapperTest : public InputMapperTest {
2743protected:
2744 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::VIBRATOR); }
2745};
2746
2747TEST_F(VibratorInputMapperTest, GetSources) {
2748 VibratorInputMapper& mapper = addMapperAndConfigure<VibratorInputMapper>();
2749
2750 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mapper.getSources());
2751}
2752
2753TEST_F(VibratorInputMapperTest, GetVibratorIds) {
2754 VibratorInputMapper& mapper = addMapperAndConfigure<VibratorInputMapper>();
2755
2756 ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
2757}
2758
2759TEST_F(VibratorInputMapperTest, Vibrate) {
2760 constexpr uint8_t DEFAULT_AMPLITUDE = 192;
Chris Yefb552902021-02-03 17:18:37 -08002761 constexpr int32_t VIBRATION_TOKEN = 100;
Chris Ye87143712020-11-10 05:05:58 +00002762 VibratorInputMapper& mapper = addMapperAndConfigure<VibratorInputMapper>();
2763
2764 VibrationElement pattern(2);
2765 VibrationSequence sequence(2);
2766 pattern.duration = std::chrono::milliseconds(200);
2767 pattern.channels = {{0 /* vibratorId */, DEFAULT_AMPLITUDE / 2},
2768 {1 /* vibratorId */, DEFAULT_AMPLITUDE}};
2769 sequence.addElement(pattern);
2770 pattern.duration = std::chrono::milliseconds(500);
2771 pattern.channels = {{0 /* vibratorId */, DEFAULT_AMPLITUDE / 4},
2772 {1 /* vibratorId */, DEFAULT_AMPLITUDE}};
2773 sequence.addElement(pattern);
2774
2775 std::vector<int64_t> timings = {0, 1};
2776 std::vector<uint8_t> amplitudes = {DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE / 2};
2777
2778 ASSERT_FALSE(mapper.isVibrating());
Chris Yefb552902021-02-03 17:18:37 -08002779 // Start vibrating
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002780 std::list<NotifyArgs> out = mapper.vibrate(sequence, -1 /* repeat */, VIBRATION_TOKEN);
Chris Ye87143712020-11-10 05:05:58 +00002781 ASSERT_TRUE(mapper.isVibrating());
Chris Yefb552902021-02-03 17:18:37 -08002782 // Verify vibrator state listener was notified.
2783 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002784 ASSERT_EQ(1u, out.size());
2785 const NotifyVibratorStateArgs& vibrateArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
2786 ASSERT_EQ(DEVICE_ID, vibrateArgs.deviceId);
2787 ASSERT_TRUE(vibrateArgs.isOn);
Chris Yefb552902021-02-03 17:18:37 -08002788 // Stop vibrating
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002789 out = mapper.cancelVibrate(VIBRATION_TOKEN);
Chris Yefb552902021-02-03 17:18:37 -08002790 ASSERT_FALSE(mapper.isVibrating());
2791 // Verify vibrator state listener was notified.
2792 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002793 ASSERT_EQ(1u, out.size());
2794 const NotifyVibratorStateArgs& cancelArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
2795 ASSERT_EQ(DEVICE_ID, cancelArgs.deviceId);
2796 ASSERT_FALSE(cancelArgs.isOn);
Chris Ye87143712020-11-10 05:05:58 +00002797}
Michael Wrightd02c5b62014-02-10 15:10:22 -08002798
Chris Yef59a2f42020-10-16 12:55:26 -07002799// --- SensorInputMapperTest ---
2800
2801class SensorInputMapperTest : public InputMapperTest {
2802protected:
2803 static const int32_t ACCEL_RAW_MIN;
2804 static const int32_t ACCEL_RAW_MAX;
2805 static const int32_t ACCEL_RAW_FUZZ;
2806 static const int32_t ACCEL_RAW_FLAT;
2807 static const int32_t ACCEL_RAW_RESOLUTION;
2808
2809 static const int32_t GYRO_RAW_MIN;
2810 static const int32_t GYRO_RAW_MAX;
2811 static const int32_t GYRO_RAW_FUZZ;
2812 static const int32_t GYRO_RAW_FLAT;
2813 static const int32_t GYRO_RAW_RESOLUTION;
2814
2815 static const float GRAVITY_MS2_UNIT;
2816 static const float DEGREE_RADIAN_UNIT;
2817
2818 void prepareAccelAxes();
2819 void prepareGyroAxes();
2820 void setAccelProperties();
2821 void setGyroProperties();
2822 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::SENSOR); }
2823};
2824
2825const int32_t SensorInputMapperTest::ACCEL_RAW_MIN = -32768;
2826const int32_t SensorInputMapperTest::ACCEL_RAW_MAX = 32768;
2827const int32_t SensorInputMapperTest::ACCEL_RAW_FUZZ = 16;
2828const int32_t SensorInputMapperTest::ACCEL_RAW_FLAT = 0;
2829const int32_t SensorInputMapperTest::ACCEL_RAW_RESOLUTION = 8192;
2830
2831const int32_t SensorInputMapperTest::GYRO_RAW_MIN = -2097152;
2832const int32_t SensorInputMapperTest::GYRO_RAW_MAX = 2097152;
2833const int32_t SensorInputMapperTest::GYRO_RAW_FUZZ = 16;
2834const int32_t SensorInputMapperTest::GYRO_RAW_FLAT = 0;
2835const int32_t SensorInputMapperTest::GYRO_RAW_RESOLUTION = 1024;
2836
2837const float SensorInputMapperTest::GRAVITY_MS2_UNIT = 9.80665f;
2838const float SensorInputMapperTest::DEGREE_RADIAN_UNIT = 0.0174533f;
2839
2840void SensorInputMapperTest::prepareAccelAxes() {
2841 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
2842 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
2843 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
2844 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
2845 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Z, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
2846 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
2847}
2848
2849void SensorInputMapperTest::prepareGyroAxes() {
2850 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RX, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
2851 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
2852 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RY, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
2853 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
2854 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RZ, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
2855 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
2856}
2857
2858void SensorInputMapperTest::setAccelProperties() {
2859 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 0, InputDeviceSensorType::ACCELEROMETER,
2860 /* sensorDataIndex */ 0);
2861 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 1, InputDeviceSensorType::ACCELEROMETER,
2862 /* sensorDataIndex */ 1);
2863 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 2, InputDeviceSensorType::ACCELEROMETER,
2864 /* sensorDataIndex */ 2);
2865 mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP);
2866 addConfigurationProperty("sensor.accelerometer.reportingMode", "0");
2867 addConfigurationProperty("sensor.accelerometer.maxDelay", "100000");
2868 addConfigurationProperty("sensor.accelerometer.minDelay", "5000");
2869 addConfigurationProperty("sensor.accelerometer.power", "1.5");
2870}
2871
2872void SensorInputMapperTest::setGyroProperties() {
2873 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 3, InputDeviceSensorType::GYROSCOPE,
2874 /* sensorDataIndex */ 0);
2875 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 4, InputDeviceSensorType::GYROSCOPE,
2876 /* sensorDataIndex */ 1);
2877 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 5, InputDeviceSensorType::GYROSCOPE,
2878 /* sensorDataIndex */ 2);
2879 mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP);
2880 addConfigurationProperty("sensor.gyroscope.reportingMode", "0");
2881 addConfigurationProperty("sensor.gyroscope.maxDelay", "100000");
2882 addConfigurationProperty("sensor.gyroscope.minDelay", "5000");
2883 addConfigurationProperty("sensor.gyroscope.power", "0.8");
2884}
2885
2886TEST_F(SensorInputMapperTest, GetSources) {
2887 SensorInputMapper& mapper = addMapperAndConfigure<SensorInputMapper>();
2888
2889 ASSERT_EQ(static_cast<uint32_t>(AINPUT_SOURCE_SENSOR), mapper.getSources());
2890}
2891
2892TEST_F(SensorInputMapperTest, ProcessAccelerometerSensor) {
2893 setAccelProperties();
2894 prepareAccelAxes();
2895 SensorInputMapper& mapper = addMapperAndConfigure<SensorInputMapper>();
2896
2897 ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::ACCELEROMETER,
2898 std::chrono::microseconds(10000),
2899 std::chrono::microseconds(0)));
Chris Yee14523a2020-12-19 13:46:00 -08002900 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002901 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, 20000);
2902 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, -20000);
2903 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Z, 40000);
2904 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
2905 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Chris Yef59a2f42020-10-16 12:55:26 -07002906
2907 NotifySensorArgs args;
2908 std::vector<float> values = {20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT,
2909 -20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT,
2910 40000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT};
2911
2912 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args));
2913 ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR);
2914 ASSERT_EQ(args.deviceId, DEVICE_ID);
2915 ASSERT_EQ(args.sensorType, InputDeviceSensorType::ACCELEROMETER);
2916 ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
2917 ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME);
2918 ASSERT_EQ(args.values, values);
2919 mapper.flushSensor(InputDeviceSensorType::ACCELEROMETER);
2920}
2921
2922TEST_F(SensorInputMapperTest, ProcessGyroscopeSensor) {
2923 setGyroProperties();
2924 prepareGyroAxes();
2925 SensorInputMapper& mapper = addMapperAndConfigure<SensorInputMapper>();
2926
2927 ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::GYROSCOPE,
2928 std::chrono::microseconds(10000),
2929 std::chrono::microseconds(0)));
Chris Yee14523a2020-12-19 13:46:00 -08002930 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002931 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RX, 20000);
2932 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RY, -20000);
2933 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RZ, 40000);
2934 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
2935 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Chris Yef59a2f42020-10-16 12:55:26 -07002936
2937 NotifySensorArgs args;
2938 std::vector<float> values = {20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT,
2939 -20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT,
2940 40000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT};
2941
2942 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args));
2943 ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR);
2944 ASSERT_EQ(args.deviceId, DEVICE_ID);
2945 ASSERT_EQ(args.sensorType, InputDeviceSensorType::GYROSCOPE);
2946 ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
2947 ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME);
2948 ASSERT_EQ(args.values, values);
2949 mapper.flushSensor(InputDeviceSensorType::GYROSCOPE);
2950}
2951
Michael Wrightd02c5b62014-02-10 15:10:22 -08002952// --- KeyboardInputMapperTest ---
2953
2954class KeyboardInputMapperTest : public InputMapperTest {
2955protected:
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002956 const std::string UNIQUE_ID = "local:0";
2957
Michael Wrighta9cf4192022-12-01 23:46:39 +00002958 void prepareDisplay(ui::Rotation orientation);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002959
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002960 void testDPadKeyRotation(KeyboardInputMapper& mapper, int32_t originalScanCode,
Arthur Hung2c9a3342019-07-23 14:18:59 +08002961 int32_t originalKeyCode, int32_t rotatedKeyCode,
2962 int32_t displayId = ADISPLAY_ID_NONE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002963};
2964
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002965/* Similar to setDisplayInfoAndReconfigure, but pre-populates all parameters except for the
2966 * orientation.
2967 */
Michael Wrighta9cf4192022-12-01 23:46:39 +00002968void KeyboardInputMapperTest::prepareDisplay(ui::Rotation orientation) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01002969 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation, UNIQUE_ID,
2970 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002971}
2972
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002973void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper& mapper,
Arthur Hung2c9a3342019-07-23 14:18:59 +08002974 int32_t originalScanCode, int32_t originalKeyCode,
2975 int32_t rotatedKeyCode, int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002976 NotifyKeyArgs args;
2977
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002978 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002979 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2980 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
2981 ASSERT_EQ(originalScanCode, args.scanCode);
2982 ASSERT_EQ(rotatedKeyCode, args.keyCode);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002983 ASSERT_EQ(displayId, args.displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002984
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002985 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002986 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2987 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
2988 ASSERT_EQ(originalScanCode, args.scanCode);
2989 ASSERT_EQ(rotatedKeyCode, args.keyCode);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002990 ASSERT_EQ(displayId, args.displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002991}
2992
Michael Wrightd02c5b62014-02-10 15:10:22 -08002993TEST_F(KeyboardInputMapperTest, GetSources) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002994 KeyboardInputMapper& mapper =
2995 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
2996 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002997
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002998 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002999}
3000
3001TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) {
3002 const int32_t USAGE_A = 0x070004;
3003 const int32_t USAGE_UNKNOWN = 0x07ffff;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003004 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3005 mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
Chris Yea52ade12020-08-27 16:49:20 -07003006 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, POLICY_FLAG_WAKE);
3007 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, POLICY_FLAG_WAKE);
3008 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, POLICY_FLAG_WAKE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003009
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003010 KeyboardInputMapper& mapper =
3011 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3012 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003013 // Initial metastate is AMETA_NONE.
3014 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003015
3016 // Key down by scan code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003017 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003018 NotifyKeyArgs args;
3019 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3020 ASSERT_EQ(DEVICE_ID, args.deviceId);
3021 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3022 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3023 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3024 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3025 ASSERT_EQ(KEY_HOME, args.scanCode);
3026 ASSERT_EQ(AMETA_NONE, args.metaState);
3027 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3028 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3029 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3030
3031 // Key up by scan code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003032 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003033 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3034 ASSERT_EQ(DEVICE_ID, args.deviceId);
3035 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3036 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3037 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3038 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3039 ASSERT_EQ(KEY_HOME, args.scanCode);
3040 ASSERT_EQ(AMETA_NONE, args.metaState);
3041 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3042 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3043 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3044
3045 // Key down by usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003046 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_A);
3047 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, 0, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003048 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3049 ASSERT_EQ(DEVICE_ID, args.deviceId);
3050 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3051 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3052 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3053 ASSERT_EQ(AKEYCODE_A, args.keyCode);
3054 ASSERT_EQ(0, args.scanCode);
3055 ASSERT_EQ(AMETA_NONE, args.metaState);
3056 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3057 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3058 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3059
3060 // Key up by usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003061 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_A);
3062 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003063 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3064 ASSERT_EQ(DEVICE_ID, args.deviceId);
3065 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3066 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3067 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3068 ASSERT_EQ(AKEYCODE_A, args.keyCode);
3069 ASSERT_EQ(0, args.scanCode);
3070 ASSERT_EQ(AMETA_NONE, args.metaState);
3071 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3072 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3073 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3074
3075 // Key down with unknown scan code or usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003076 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
3077 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UNKNOWN, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003078 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3079 ASSERT_EQ(DEVICE_ID, args.deviceId);
3080 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3081 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3082 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3083 ASSERT_EQ(0, args.keyCode);
3084 ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
3085 ASSERT_EQ(AMETA_NONE, args.metaState);
3086 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3087 ASSERT_EQ(0U, args.policyFlags);
3088 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3089
3090 // Key up with unknown scan code or usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003091 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
3092 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_UNKNOWN, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003093 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3094 ASSERT_EQ(DEVICE_ID, args.deviceId);
3095 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3096 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3097 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3098 ASSERT_EQ(0, args.keyCode);
3099 ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
3100 ASSERT_EQ(AMETA_NONE, args.metaState);
3101 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3102 ASSERT_EQ(0U, args.policyFlags);
3103 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3104}
3105
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003106/**
3107 * Ensure that the readTime is set to the time when the EV_KEY is received.
3108 */
3109TEST_F(KeyboardInputMapperTest, Process_SendsReadTime) {
3110 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3111
3112 KeyboardInputMapper& mapper =
3113 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3114 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3115 NotifyKeyArgs args;
3116
3117 // Key down
3118 process(mapper, ARBITRARY_TIME, 12 /*readTime*/, EV_KEY, KEY_HOME, 1);
3119 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3120 ASSERT_EQ(12, args.readTime);
3121
3122 // Key up
3123 process(mapper, ARBITRARY_TIME, 15 /*readTime*/, EV_KEY, KEY_HOME, 1);
3124 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3125 ASSERT_EQ(15, args.readTime);
3126}
3127
Michael Wrightd02c5b62014-02-10 15:10:22 -08003128TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003129 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFTSHIFT, 0, AKEYCODE_SHIFT_LEFT, 0);
3130 mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
Chris Yea52ade12020-08-27 16:49:20 -07003131 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, 0);
3132 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, 0);
3133 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003134
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003135 KeyboardInputMapper& mapper =
3136 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3137 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003138
Arthur Hung95f68612022-04-07 14:08:22 +08003139 // Initial metastate is AMETA_NONE.
3140 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003141
3142 // Metakey down.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003143 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_LEFTSHIFT, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003144 NotifyKeyArgs args;
3145 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3146 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003147 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
arthurhungdcef2dc2020-08-11 14:47:50 +08003148 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertUpdateGlobalMetaStateWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003149
3150 // Key down.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003151 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_A, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003152 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3153 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003154 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003155
3156 // Key up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003157 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, KEY_A, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003158 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3159 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003160 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003161
3162 // Metakey up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003163 process(mapper, ARBITRARY_TIME + 3, READ_TIME, EV_KEY, KEY_LEFTSHIFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003164 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3165 ASSERT_EQ(AMETA_NONE, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003166 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
arthurhungdcef2dc2020-08-11 14:47:50 +08003167 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertUpdateGlobalMetaStateWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003168}
3169
3170TEST_F(KeyboardInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateDPad) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003171 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3172 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3173 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3174 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003175
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003176 KeyboardInputMapper& mapper =
3177 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3178 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003179
Michael Wrighta9cf4192022-12-01 23:46:39 +00003180 prepareDisplay(ui::ROTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003181 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3182 KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP));
3183 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3184 KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT));
3185 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3186 KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN));
3187 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3188 KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT));
3189}
3190
3191TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003192 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3193 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3194 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3195 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003196
Michael Wrightd02c5b62014-02-10 15:10:22 -08003197 addConfigurationProperty("keyboard.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003198 KeyboardInputMapper& mapper =
3199 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3200 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003201
Michael Wrighta9cf4192022-12-01 23:46:39 +00003202 prepareDisplay(ui::ROTATION_0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003203 ASSERT_NO_FATAL_FAILURE(
3204 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID));
3205 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3206 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3207 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3208 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3209 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3210 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003211
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003212 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003213 prepareDisplay(ui::ROTATION_90);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003214 ASSERT_NO_FATAL_FAILURE(
3215 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3216 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3217 AKEYCODE_DPAD_UP, DISPLAY_ID));
3218 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3219 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3220 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3221 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003222
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003223 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003224 prepareDisplay(ui::ROTATION_180);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003225 ASSERT_NO_FATAL_FAILURE(
3226 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3227 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3228 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3229 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3230 AKEYCODE_DPAD_UP, DISPLAY_ID));
3231 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3232 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003233
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003234 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003235 prepareDisplay(ui::ROTATION_270);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003236 ASSERT_NO_FATAL_FAILURE(
3237 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3238 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3239 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3240 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3241 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3242 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3243 AKEYCODE_DPAD_UP, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003244
3245 // Special case: if orientation changes while key is down, we still emit the same keycode
3246 // in the key up as we did in the key down.
3247 NotifyKeyArgs args;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003248 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003249 prepareDisplay(ui::ROTATION_270);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003250 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003251 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3252 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3253 ASSERT_EQ(KEY_UP, args.scanCode);
3254 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
3255
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003256 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003257 prepareDisplay(ui::ROTATION_180);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003258 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003259 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3260 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3261 ASSERT_EQ(KEY_UP, args.scanCode);
3262 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
3263}
3264
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003265TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_NotOrientationAware) {
3266 // If the keyboard is not orientation aware,
3267 // key events should not be associated with a specific display id
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003268 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003269
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003270 KeyboardInputMapper& mapper =
3271 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3272 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003273 NotifyKeyArgs args;
3274
3275 // Display id should be ADISPLAY_ID_NONE without any display configuration.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003276 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003277 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003278 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003279 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3280 ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
3281
Michael Wrighta9cf4192022-12-01 23:46:39 +00003282 prepareDisplay(ui::ROTATION_0);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003283 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003284 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003285 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003286 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3287 ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
3288}
3289
3290TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_OrientationAware) {
3291 // If the keyboard is orientation aware,
3292 // key events should be associated with the internal viewport
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003293 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003294
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003295 addConfigurationProperty("keyboard.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003296 KeyboardInputMapper& mapper =
3297 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3298 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003299 NotifyKeyArgs args;
3300
3301 // Display id should be ADISPLAY_ID_NONE without any display configuration.
3302 // ^--- already checked by the previous test
3303
Michael Wrighta9cf4192022-12-01 23:46:39 +00003304 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003305 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003306 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003307 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003308 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003309 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3310 ASSERT_EQ(DISPLAY_ID, args.displayId);
3311
3312 constexpr int32_t newDisplayId = 2;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003313 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00003314 setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003315 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003316 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003317 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003318 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003319 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3320 ASSERT_EQ(newDisplayId, args.displayId);
3321}
3322
Michael Wrightd02c5b62014-02-10 15:10:22 -08003323TEST_F(KeyboardInputMapperTest, GetKeyCodeState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003324 KeyboardInputMapper& mapper =
3325 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3326 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003327
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003328 mFakeEventHub->setKeyCodeState(EVENTHUB_ID, AKEYCODE_A, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003329 ASSERT_EQ(1, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003330
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003331 mFakeEventHub->setKeyCodeState(EVENTHUB_ID, AKEYCODE_A, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003332 ASSERT_EQ(0, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003333}
3334
Philip Junker4af3b3d2021-12-14 10:36:55 +01003335TEST_F(KeyboardInputMapperTest, GetKeyCodeForKeyLocation) {
3336 KeyboardInputMapper& mapper =
3337 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3338 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3339
3340 mFakeEventHub->addKeyCodeMapping(EVENTHUB_ID, AKEYCODE_Y, AKEYCODE_Z);
3341 ASSERT_EQ(AKEYCODE_Z, mapper.getKeyCodeForKeyLocation(AKEYCODE_Y))
3342 << "If a mapping is available, the result is equal to the mapping";
3343
3344 ASSERT_EQ(AKEYCODE_A, mapper.getKeyCodeForKeyLocation(AKEYCODE_A))
3345 << "If no mapping is available, the result is the key location";
3346}
3347
Michael Wrightd02c5b62014-02-10 15:10:22 -08003348TEST_F(KeyboardInputMapperTest, GetScanCodeState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003349 KeyboardInputMapper& mapper =
3350 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3351 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003352
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003353 mFakeEventHub->setScanCodeState(EVENTHUB_ID, KEY_A, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003354 ASSERT_EQ(1, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003355
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003356 mFakeEventHub->setScanCodeState(EVENTHUB_ID, KEY_A, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003357 ASSERT_EQ(0, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003358}
3359
3360TEST_F(KeyboardInputMapperTest, MarkSupportedKeyCodes) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003361 KeyboardInputMapper& mapper =
3362 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3363 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003364
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003365 mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003366
Michael Wrightd02c5b62014-02-10 15:10:22 -08003367 uint8_t flags[2] = { 0, 0 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07003368 ASSERT_TRUE(mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, {AKEYCODE_A, AKEYCODE_B}, flags));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003369 ASSERT_TRUE(flags[0]);
3370 ASSERT_FALSE(flags[1]);
3371}
3372
3373TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003374 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3375 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3376 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3377 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3378 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3379 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003380
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003381 KeyboardInputMapper& mapper =
3382 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3383 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003384 // Initial metastate is AMETA_NONE.
3385 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003386
3387 // Initialization should have turned all of the lights off.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003388 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3389 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3390 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003391
3392 // Toggle caps lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003393 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3394 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003395 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3396 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3397 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003398 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003399
3400 // Toggle num lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003401 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3402 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003403 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3404 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3405 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003406 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003407
3408 // Toggle caps lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003409 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3410 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003411 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3412 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3413 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003414 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003415
3416 // Toggle scroll lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003417 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3418 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003419 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3420 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3421 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003422 ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003423
3424 // Toggle num lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003425 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3426 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003427 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3428 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3429 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003430 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003431
3432 // Toggle scroll lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003433 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3434 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003435 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3436 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3437 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003438 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003439}
3440
Chris Yea52ade12020-08-27 16:49:20 -07003441TEST_F(KeyboardInputMapperTest, NoMetaStateWhenMetaKeysNotPresent) {
3442 mFakeEventHub->addKey(EVENTHUB_ID, BTN_A, 0, AKEYCODE_BUTTON_A, 0);
3443 mFakeEventHub->addKey(EVENTHUB_ID, BTN_B, 0, AKEYCODE_BUTTON_B, 0);
3444 mFakeEventHub->addKey(EVENTHUB_ID, BTN_X, 0, AKEYCODE_BUTTON_X, 0);
3445 mFakeEventHub->addKey(EVENTHUB_ID, BTN_Y, 0, AKEYCODE_BUTTON_Y, 0);
3446
3447 KeyboardInputMapper& mapper =
3448 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3449 AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
3450
Chris Yea52ade12020-08-27 16:49:20 -07003451 // Meta state should be AMETA_NONE after reset
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003452 std::list<NotifyArgs> unused = mapper.reset(ARBITRARY_TIME);
Chris Yea52ade12020-08-27 16:49:20 -07003453 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3454 // Meta state should be AMETA_NONE with update, as device doesn't have the keys.
3455 mapper.updateMetaState(AKEYCODE_NUM_LOCK);
3456 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3457
3458 NotifyKeyArgs args;
3459 // Press button "A"
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003460 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_A, 1);
Chris Yea52ade12020-08-27 16:49:20 -07003461 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3462 ASSERT_EQ(AMETA_NONE, args.metaState);
3463 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3464 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3465 ASSERT_EQ(AKEYCODE_BUTTON_A, args.keyCode);
3466
3467 // Button up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003468 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, BTN_A, 0);
Chris Yea52ade12020-08-27 16:49:20 -07003469 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3470 ASSERT_EQ(AMETA_NONE, args.metaState);
3471 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3472 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3473 ASSERT_EQ(AKEYCODE_BUTTON_A, args.keyCode);
3474}
3475
Arthur Hung2c9a3342019-07-23 14:18:59 +08003476TEST_F(KeyboardInputMapperTest, Configure_AssignsDisplayPort) {
3477 // keyboard 1.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003478 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3479 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3480 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3481 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003482
3483 // keyboard 2.
3484 const std::string USB2 = "USB2";
arthurhungdcef2dc2020-08-11 14:47:50 +08003485 const std::string DEVICE_NAME2 = "KEYBOARD2";
Arthur Hung2c9a3342019-07-23 14:18:59 +08003486 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003487 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
arthurhungdcef2dc2020-08-11 14:47:50 +08003488 std::shared_ptr<InputDevice> device2 =
3489 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07003490 ftl::Flags<InputDeviceClass>(0));
arthurhungdcef2dc2020-08-11 14:47:50 +08003491
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003492 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3493 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3494 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3495 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003496
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003497 KeyboardInputMapper& mapper =
3498 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3499 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003500
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003501 KeyboardInputMapper& mapper2 =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003502 device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003503 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003504 std::list<NotifyArgs> unused =
3505 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3506 0 /*changes*/);
3507 unused += device2->reset(ARBITRARY_TIME);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003508
3509 // Prepared displays and associated info.
3510 constexpr uint8_t hdmi1 = 0;
3511 constexpr uint8_t hdmi2 = 1;
3512 const std::string SECONDARY_UNIQUE_ID = "local:1";
3513
3514 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
3515 mFakePolicy->addInputPortAssociation(USB2, hdmi2);
3516
3517 // No associated display viewport found, should disable the device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003518 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3519 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003520 ASSERT_FALSE(device2->isEnabled());
3521
3522 // Prepare second display.
3523 constexpr int32_t newDisplayId = 2;
Michael Wrighta9cf4192022-12-01 23:46:39 +00003524 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003525 UNIQUE_ID, hdmi1, ViewportType::INTERNAL);
Michael Wrighta9cf4192022-12-01 23:46:39 +00003526 setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003527 SECONDARY_UNIQUE_ID, hdmi2, ViewportType::EXTERNAL);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003528 // Default device will reconfigure above, need additional reconfiguration for another device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003529 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3530 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003531
3532 // Device should be enabled after the associated display is found.
3533 ASSERT_TRUE(mDevice->isEnabled());
3534 ASSERT_TRUE(device2->isEnabled());
3535
3536 // Test pad key events
3537 ASSERT_NO_FATAL_FAILURE(
3538 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID));
3539 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3540 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3541 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3542 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3543 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3544 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3545
3546 ASSERT_NO_FATAL_FAILURE(
3547 testDPadKeyRotation(mapper2, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, newDisplayId));
3548 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3549 AKEYCODE_DPAD_RIGHT, newDisplayId));
3550 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3551 AKEYCODE_DPAD_DOWN, newDisplayId));
3552 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3553 AKEYCODE_DPAD_LEFT, newDisplayId));
3554}
Michael Wrightd02c5b62014-02-10 15:10:22 -08003555
arthurhungc903df12020-08-11 15:08:42 +08003556TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleAfterReattach) {
3557 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3558 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3559 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3560 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3561 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3562 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3563
3564 KeyboardInputMapper& mapper =
3565 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3566 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003567 // Initial metastate is AMETA_NONE.
3568 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
arthurhungc903df12020-08-11 15:08:42 +08003569
3570 // Initialization should have turned all of the lights off.
3571 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3572 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3573 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3574
3575 // Toggle caps lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003576 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3577 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003578 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3579 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
3580
3581 // Toggle num lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003582 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3583 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003584 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3585 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState());
3586
3587 // Toggle scroll lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003588 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3589 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003590 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3591 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
3592
3593 mFakeEventHub->removeDevice(EVENTHUB_ID);
3594 mReader->loopOnce();
3595
3596 // keyboard 2 should default toggle keys.
3597 const std::string USB2 = "USB2";
3598 const std::string DEVICE_NAME2 = "KEYBOARD2";
3599 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
3600 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
3601 std::shared_ptr<InputDevice> device2 =
3602 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07003603 ftl::Flags<InputDeviceClass>(0));
arthurhungc903df12020-08-11 15:08:42 +08003604 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3605 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/);
3606 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3607 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3608 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3609 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3610
arthurhung6fe95782020-10-05 22:41:16 +08003611 KeyboardInputMapper& mapper2 =
3612 device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
3613 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003614 std::list<NotifyArgs> unused =
3615 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3616 0 /*changes*/);
3617 unused += device2->reset(ARBITRARY_TIME);
arthurhungc903df12020-08-11 15:08:42 +08003618
3619 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_CAPSL));
3620 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_NUML));
3621 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_SCROLLL));
arthurhung6fe95782020-10-05 22:41:16 +08003622 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON,
3623 mapper2.getMetaState());
arthurhungc903df12020-08-11 15:08:42 +08003624}
3625
Arthur Hungcb40a002021-08-03 14:31:01 +00003626TEST_F(KeyboardInputMapperTest, Process_toggleCapsLockState) {
3627 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3628 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3629 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3630
3631 // Suppose we have two mappers. (DPAD + KEYBOARD)
3632 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_DPAD,
3633 AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
3634 KeyboardInputMapper& mapper =
3635 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3636 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003637 // Initial metastate is AMETA_NONE.
3638 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Arthur Hungcb40a002021-08-03 14:31:01 +00003639
3640 mReader->toggleCapsLockState(DEVICE_ID);
3641 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
3642}
3643
Arthur Hungfb3cc112022-04-13 07:39:50 +00003644TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleInMultiDevices) {
3645 // keyboard 1.
3646 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3647 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3648 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3649 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3650 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3651 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3652
3653 KeyboardInputMapper& mapper1 =
3654 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3655 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3656
3657 // keyboard 2.
3658 const std::string USB2 = "USB2";
3659 const std::string DEVICE_NAME2 = "KEYBOARD2";
3660 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
3661 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
3662 std::shared_ptr<InputDevice> device2 =
3663 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
3664 ftl::Flags<InputDeviceClass>(0));
3665 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3666 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/);
3667 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3668 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3669 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3670 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3671
3672 KeyboardInputMapper& mapper2 =
3673 device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
3674 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003675 std::list<NotifyArgs> unused =
3676 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3677 0 /*changes*/);
3678 unused += device2->reset(ARBITRARY_TIME);
Arthur Hungfb3cc112022-04-13 07:39:50 +00003679
Arthur Hung95f68612022-04-07 14:08:22 +08003680 // Initial metastate is AMETA_NONE.
3681 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3682 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3683
3684 // Toggle num lock on and off.
3685 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3686 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Arthur Hungfb3cc112022-04-13 07:39:50 +00003687 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3688 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper1.getMetaState());
3689 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper2.getMetaState());
3690
3691 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3692 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
3693 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3694 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3695 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3696
3697 // Toggle caps lock on and off.
3698 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3699 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
3700 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3701 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper1.getMetaState());
3702 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper2.getMetaState());
3703
3704 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3705 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
3706 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3707 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3708 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3709
3710 // Toggle scroll lock on and off.
3711 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3712 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
3713 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3714 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper1.getMetaState());
3715 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper2.getMetaState());
3716
3717 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3718 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
3719 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3720 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3721 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3722}
3723
Arthur Hung2141d542022-08-23 07:45:21 +00003724TEST_F(KeyboardInputMapperTest, Process_DisabledDevice) {
3725 const int32_t USAGE_A = 0x070004;
3726 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3727 mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
3728
3729 KeyboardInputMapper& mapper =
3730 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3731 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3732 // Key down by scan code.
3733 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
3734 NotifyKeyArgs args;
3735 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3736 ASSERT_EQ(DEVICE_ID, args.deviceId);
3737 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3738 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3739 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3740 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3741 ASSERT_EQ(KEY_HOME, args.scanCode);
3742 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3743
3744 // Disable device, it should synthesize cancellation events for down events.
3745 mFakePolicy->addDisabledDevice(DEVICE_ID);
3746 configureDevice(InputReaderConfiguration::CHANGE_ENABLED_STATE);
3747
3748 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3749 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3750 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3751 ASSERT_EQ(KEY_HOME, args.scanCode);
3752 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED, args.flags);
3753}
3754
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003755// --- KeyboardInputMapperTest_ExternalDevice ---
3756
3757class KeyboardInputMapperTest_ExternalDevice : public InputMapperTest {
3758protected:
Chris Yea52ade12020-08-27 16:49:20 -07003759 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003760};
3761
3762TEST_F(KeyboardInputMapperTest_ExternalDevice, WakeBehavior) {
Powei Fengd041c5d2019-05-03 17:11:33 -07003763 // For external devices, non-media keys will trigger wake on key down. Media keys need to be
3764 // marked as WAKE in the keylayout file to trigger wake.
Powei Fengd041c5d2019-05-03 17:11:33 -07003765
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003766 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, 0);
3767 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, 0);
3768 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAYPAUSE, 0, AKEYCODE_MEDIA_PLAY_PAUSE,
3769 POLICY_FLAG_WAKE);
Powei Fengd041c5d2019-05-03 17:11:33 -07003770
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003771 KeyboardInputMapper& mapper =
3772 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3773 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Powei Fengd041c5d2019-05-03 17:11:33 -07003774
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003775 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003776 NotifyKeyArgs args;
3777 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3778 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3779
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003780 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003781 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3782 ASSERT_EQ(uint32_t(0), args.policyFlags);
3783
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003784 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAY, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003785 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3786 ASSERT_EQ(uint32_t(0), args.policyFlags);
3787
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003788 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAY, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003789 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3790 ASSERT_EQ(uint32_t(0), args.policyFlags);
3791
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003792 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAYPAUSE, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003793 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3794 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3795
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003796 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAYPAUSE, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003797 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3798 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3799}
3800
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003801TEST_F(KeyboardInputMapperTest_ExternalDevice, DoNotWakeByDefaultBehavior) {
Powei Fengd041c5d2019-05-03 17:11:33 -07003802 // Tv Remote key's wake behavior is prescribed by the keylayout file.
Powei Fengd041c5d2019-05-03 17:11:33 -07003803
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003804 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3805 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3806 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, POLICY_FLAG_WAKE);
Powei Fengd041c5d2019-05-03 17:11:33 -07003807
Powei Fengd041c5d2019-05-03 17:11:33 -07003808 addConfigurationProperty("keyboard.doNotWakeByDefault", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003809 KeyboardInputMapper& mapper =
3810 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3811 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Powei Fengd041c5d2019-05-03 17:11:33 -07003812
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003813 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003814 NotifyKeyArgs args;
3815 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3816 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3817
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003818 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003819 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3820 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3821
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003822 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_DOWN, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003823 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3824 ASSERT_EQ(uint32_t(0), args.policyFlags);
3825
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003826 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_DOWN, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003827 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3828 ASSERT_EQ(uint32_t(0), args.policyFlags);
3829
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003830 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAY, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003831 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3832 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3833
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003834 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAY, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003835 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3836 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3837}
3838
Michael Wrightd02c5b62014-02-10 15:10:22 -08003839// --- CursorInputMapperTest ---
3840
3841class CursorInputMapperTest : public InputMapperTest {
3842protected:
3843 static const int32_t TRACKBALL_MOVEMENT_THRESHOLD;
3844
Michael Wright17db18e2020-06-26 20:51:44 +01003845 std::shared_ptr<FakePointerController> mFakePointerController;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003846
Chris Yea52ade12020-08-27 16:49:20 -07003847 void SetUp() override {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003848 InputMapperTest::SetUp();
3849
Michael Wright17db18e2020-06-26 20:51:44 +01003850 mFakePointerController = std::make_shared<FakePointerController>();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00003851 mFakePolicy->setPointerController(mFakePointerController);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003852 }
3853
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003854 void testMotionRotation(CursorInputMapper& mapper, int32_t originalX, int32_t originalY,
3855 int32_t rotatedX, int32_t rotatedY);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07003856
Michael Wrighta9cf4192022-12-01 23:46:39 +00003857 void prepareDisplay(ui::Rotation orientation) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00003858 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation,
3859 DISPLAY_UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
3860 }
3861
3862 void prepareSecondaryDisplay() {
3863 setDisplayInfoAndReconfigure(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +00003864 ui::ROTATION_0, SECONDARY_DISPLAY_UNIQUE_ID, NO_PORT,
Prabir Pradhanc13ff082022-09-08 22:03:30 +00003865 ViewportType::EXTERNAL);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07003866 }
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003867
3868 static void assertCursorPointerCoords(const PointerCoords& coords, float x, float y,
3869 float pressure) {
3870 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(coords, x, y, pressure, 0.0f, 0.0f, 0.0f, 0.0f,
3871 0.0f, 0.0f, 0.0f, EPSILON));
3872 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003873};
3874
3875const int32_t CursorInputMapperTest::TRACKBALL_MOVEMENT_THRESHOLD = 6;
3876
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003877void CursorInputMapperTest::testMotionRotation(CursorInputMapper& mapper, int32_t originalX,
3878 int32_t originalY, int32_t rotatedX,
3879 int32_t rotatedY) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003880 NotifyMotionArgs args;
3881
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003882 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, originalX);
3883 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, originalY);
3884 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003885 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3886 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003887 ASSERT_NO_FATAL_FAILURE(
3888 assertCursorPointerCoords(args.pointerCoords[0],
3889 float(rotatedX) / TRACKBALL_MOVEMENT_THRESHOLD,
3890 float(rotatedY) / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003891}
3892
3893TEST_F(CursorInputMapperTest, WhenModeIsPointer_GetSources_ReturnsMouse) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003894 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003895 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003896
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003897 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003898}
3899
3900TEST_F(CursorInputMapperTest, WhenModeIsNavigation_GetSources_ReturnsTrackball) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003901 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003902 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003903
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003904 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003905}
3906
3907TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeFromPointerController) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003908 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003909 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003910
3911 InputDeviceInfo info;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003912 mapper.populateDeviceInfo(&info);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003913
3914 // Initially there may not be a valid motion range.
Yi Kong9b14ac62018-07-17 13:48:38 -07003915 ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE));
3916 ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003917 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
3918 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE, 0.0f, 1.0f, 0.0f, 0.0f));
3919
3920 // When the bounds are set, then there should be a valid motion range.
3921 mFakePointerController->setBounds(1, 2, 800 - 1, 480 - 1);
3922
3923 InputDeviceInfo info2;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003924 mapper.populateDeviceInfo(&info2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003925
3926 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
3927 AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE,
3928 1, 800 - 1, 0.0f, 0.0f));
3929 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
3930 AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE,
3931 2, 480 - 1, 0.0f, 0.0f));
3932 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
3933 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE,
3934 0.0f, 1.0f, 0.0f, 0.0f));
3935}
3936
3937TEST_F(CursorInputMapperTest, WhenModeIsNavigation_PopulateDeviceInfo_ReturnsScaledRange) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003938 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003939 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003940
3941 InputDeviceInfo info;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003942 mapper.populateDeviceInfo(&info);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003943
3944 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
3945 AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_TRACKBALL,
3946 -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
3947 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
3948 AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_TRACKBALL,
3949 -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
3950 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
3951 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TRACKBALL,
3952 0.0f, 1.0f, 0.0f, 0.0f));
3953}
3954
3955TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003956 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003957 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003958
arthurhungdcef2dc2020-08-11 14:47:50 +08003959 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003960
3961 NotifyMotionArgs args;
3962
3963 // Button press.
3964 // Mostly testing non x/y behavior here so we don't need to check again elsewhere.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003965 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
3966 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003967 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3968 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3969 ASSERT_EQ(DEVICE_ID, args.deviceId);
3970 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
3971 ASSERT_EQ(uint32_t(0), args.policyFlags);
3972 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
3973 ASSERT_EQ(0, args.flags);
3974 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
3975 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
3976 ASSERT_EQ(0, args.edgeFlags);
3977 ASSERT_EQ(uint32_t(1), args.pointerCount);
3978 ASSERT_EQ(0, args.pointerProperties[0].id);
3979 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003980 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003981 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
3982 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
3983 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3984
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003985 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3986 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3987 ASSERT_EQ(DEVICE_ID, args.deviceId);
3988 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
3989 ASSERT_EQ(uint32_t(0), args.policyFlags);
3990 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
3991 ASSERT_EQ(0, args.flags);
3992 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
3993 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
3994 ASSERT_EQ(0, args.edgeFlags);
3995 ASSERT_EQ(uint32_t(1), args.pointerCount);
3996 ASSERT_EQ(0, args.pointerProperties[0].id);
3997 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003998 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003999 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4000 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4001 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4002
Michael Wrightd02c5b62014-02-10 15:10:22 -08004003 // Button release. Should have same down time.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004004 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4005 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004006 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4007 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
4008 ASSERT_EQ(DEVICE_ID, args.deviceId);
4009 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4010 ASSERT_EQ(uint32_t(0), args.policyFlags);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004011 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
4012 ASSERT_EQ(0, args.flags);
4013 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4014 ASSERT_EQ(0, args.buttonState);
4015 ASSERT_EQ(0, args.edgeFlags);
4016 ASSERT_EQ(uint32_t(1), args.pointerCount);
4017 ASSERT_EQ(0, args.pointerProperties[0].id);
4018 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004019 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004020 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4021 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4022 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4023
4024 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4025 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
4026 ASSERT_EQ(DEVICE_ID, args.deviceId);
4027 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4028 ASSERT_EQ(uint32_t(0), args.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004029 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
4030 ASSERT_EQ(0, args.flags);
4031 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4032 ASSERT_EQ(0, args.buttonState);
4033 ASSERT_EQ(0, args.edgeFlags);
4034 ASSERT_EQ(uint32_t(1), args.pointerCount);
4035 ASSERT_EQ(0, args.pointerProperties[0].id);
4036 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004037 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004038 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4039 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4040 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4041}
4042
4043TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentXYUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004044 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004045 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004046
4047 NotifyMotionArgs args;
4048
4049 // Motion in X but not Y.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004050 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4051 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004052 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4053 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004054 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4055 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f,
4056 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004057
4058 // Motion in Y but not X.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004059 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, -2);
4060 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004061 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4062 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004063 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f,
4064 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004065}
4066
4067TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004068 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004069 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004070
4071 NotifyMotionArgs args;
4072
4073 // Button press.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004074 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4075 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004076 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4077 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004078 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004079
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004080 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4081 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004082 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004083
Michael Wrightd02c5b62014-02-10 15:10:22 -08004084 // Button release.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004085 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4086 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004087 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004088 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004089 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004090
4091 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004092 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004093 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004094}
4095
4096TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004097 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004098 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004099
4100 NotifyMotionArgs args;
4101
4102 // Combined X, Y and Button.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004103 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4104 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, -2);
4105 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4106 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004107 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4108 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004109 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4110 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4111 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004112
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004113 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4114 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004115 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4116 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4117 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004118
Michael Wrightd02c5b62014-02-10 15:10:22 -08004119 // Move X, Y a bit while pressed.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004120 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 2);
4121 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 1);
4122 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004123 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4124 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004125 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4126 2.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4127 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004128
4129 // Release Button.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004130 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4131 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004132 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004133 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004134 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004135
4136 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004137 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004138 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004139}
4140
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004141TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldNotRotateMotions) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004142 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004143 addConfigurationProperty("cursor.mode", "navigation");
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004144 // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
4145 // need to be rotated.
4146 addConfigurationProperty("cursor.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004147 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004148
Michael Wrighta9cf4192022-12-01 23:46:39 +00004149 prepareDisplay(ui::ROTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004150 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1));
4151 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1));
4152 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0));
4153 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, -1));
4154 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1));
4155 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
4156 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0));
4157 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1));
4158}
4159
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004160TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldRotateMotions) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004161 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004162 addConfigurationProperty("cursor.mode", "navigation");
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004163 // Since InputReader works in the un-rotated coordinate space, only devices that are not
4164 // orientation-aware are affected by display rotation.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004165 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004166
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004167 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00004168 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004169 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1));
4170 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1));
4171 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0));
4172 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, -1));
4173 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1));
4174 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
4175 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0));
4176 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1));
4177
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004178 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00004179 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004180 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, -1, 0));
4181 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, -1, 1));
4182 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 0, 1));
4183 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, 1));
4184 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 1, 0));
4185 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, -1));
4186 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, -1));
4187 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, -1));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004188
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004189 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00004190 prepareDisplay(ui::ROTATION_180);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004191 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, -1));
4192 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, -1, -1));
4193 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, -1, 0));
4194 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, -1, 1));
4195 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, 1));
4196 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, 1));
4197 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 1, 0));
4198 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, -1));
4199
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004200 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00004201 prepareDisplay(ui::ROTATION_270);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004202 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 1, 0));
4203 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, -1));
4204 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 0, -1));
4205 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, -1, -1));
4206 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, -1, 0));
4207 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, 1));
4208 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, 1));
4209 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, 1));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004210}
4211
4212TEST_F(CursorInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004213 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004214 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004215
4216 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
4217 mFakePointerController->setPosition(100, 200);
4218 mFakePointerController->setButtonState(0);
4219
4220 NotifyMotionArgs motionArgs;
4221 NotifyKeyArgs keyArgs;
4222
4223 // press BTN_LEFT, release BTN_LEFT
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004224 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_LEFT, 1);
4225 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004226 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4227 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4228 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
4229 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004230 ASSERT_NO_FATAL_FAILURE(
4231 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004232
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004233 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4234 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4235 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
4236 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004237 ASSERT_NO_FATAL_FAILURE(
4238 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004239
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004240 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_LEFT, 0);
4241 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004242 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004243 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004244 ASSERT_EQ(0, motionArgs.buttonState);
4245 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004246 ASSERT_NO_FATAL_FAILURE(
4247 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004248
4249 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004250 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004251 ASSERT_EQ(0, motionArgs.buttonState);
4252 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004253 ASSERT_NO_FATAL_FAILURE(
4254 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004255
4256 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004257 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004258 ASSERT_EQ(0, motionArgs.buttonState);
4259 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004260 ASSERT_NO_FATAL_FAILURE(
4261 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004262
4263 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004264 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_RIGHT, 1);
4265 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 1);
4266 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004267 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4268 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4269 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4270 motionArgs.buttonState);
4271 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4272 mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004273 ASSERT_NO_FATAL_FAILURE(
4274 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004275
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004276 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4277 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4278 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4279 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4280 mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004281 ASSERT_NO_FATAL_FAILURE(
4282 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004283
4284 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4285 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4286 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4287 motionArgs.buttonState);
4288 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4289 mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004290 ASSERT_NO_FATAL_FAILURE(
4291 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004292
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004293 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_RIGHT, 0);
4294 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004295 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004296 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004297 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4298 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004299 ASSERT_NO_FATAL_FAILURE(
4300 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004301
4302 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004303 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004304 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4305 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004306 ASSERT_NO_FATAL_FAILURE(
4307 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004308
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004309 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
4310 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004311 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004312 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4313 ASSERT_EQ(0, motionArgs.buttonState);
4314 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004315 ASSERT_NO_FATAL_FAILURE(
4316 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004317 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
4318 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004319
4320 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004321 ASSERT_EQ(0, motionArgs.buttonState);
4322 ASSERT_EQ(0, mFakePointerController->getButtonState());
4323 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004324 ASSERT_NO_FATAL_FAILURE(
4325 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004326
Michael Wrightd02c5b62014-02-10 15:10:22 -08004327 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4328 ASSERT_EQ(0, motionArgs.buttonState);
4329 ASSERT_EQ(0, mFakePointerController->getButtonState());
4330 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004331 ASSERT_NO_FATAL_FAILURE(
4332 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004333
4334 // press BTN_BACK, release BTN_BACK
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004335 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_BACK, 1);
4336 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004337 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4338 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4339 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004340
Michael Wrightd02c5b62014-02-10 15:10:22 -08004341 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004342 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004343 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4344 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004345 ASSERT_NO_FATAL_FAILURE(
4346 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004347
4348 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4349 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4350 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4351 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004352 ASSERT_NO_FATAL_FAILURE(
4353 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004354
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004355 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_BACK, 0);
4356 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004357 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004358 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004359 ASSERT_EQ(0, motionArgs.buttonState);
4360 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004361 ASSERT_NO_FATAL_FAILURE(
4362 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004363
4364 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004365 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004366 ASSERT_EQ(0, motionArgs.buttonState);
4367 ASSERT_EQ(0, mFakePointerController->getButtonState());
4368
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004369 ASSERT_NO_FATAL_FAILURE(
4370 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004371 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4372 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4373 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4374
4375 // press BTN_SIDE, release BTN_SIDE
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004376 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_SIDE, 1);
4377 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004378 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4379 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4380 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004381
Michael Wrightd02c5b62014-02-10 15:10:22 -08004382 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004383 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004384 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4385 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004386 ASSERT_NO_FATAL_FAILURE(
4387 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004388
4389 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4390 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4391 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4392 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004393 ASSERT_NO_FATAL_FAILURE(
4394 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004395
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004396 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_SIDE, 0);
4397 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004398 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004399 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004400 ASSERT_EQ(0, motionArgs.buttonState);
4401 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004402 ASSERT_NO_FATAL_FAILURE(
4403 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004404
4405 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4406 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4407 ASSERT_EQ(0, motionArgs.buttonState);
4408 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004409 ASSERT_NO_FATAL_FAILURE(
4410 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004411
Michael Wrightd02c5b62014-02-10 15:10:22 -08004412 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4413 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4414 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4415
4416 // press BTN_FORWARD, release BTN_FORWARD
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004417 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_FORWARD, 1);
4418 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004419 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4420 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4421 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004422
Michael Wrightd02c5b62014-02-10 15:10:22 -08004423 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004424 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004425 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4426 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004427 ASSERT_NO_FATAL_FAILURE(
4428 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004429
4430 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4431 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4432 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4433 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004434 ASSERT_NO_FATAL_FAILURE(
4435 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004436
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004437 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_FORWARD, 0);
4438 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004439 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004440 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004441 ASSERT_EQ(0, motionArgs.buttonState);
4442 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004443 ASSERT_NO_FATAL_FAILURE(
4444 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004445
4446 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4447 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4448 ASSERT_EQ(0, motionArgs.buttonState);
4449 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004450 ASSERT_NO_FATAL_FAILURE(
4451 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004452
Michael Wrightd02c5b62014-02-10 15:10:22 -08004453 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4454 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4455 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4456
4457 // press BTN_EXTRA, release BTN_EXTRA
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004458 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_EXTRA, 1);
4459 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004460 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4461 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4462 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004463
Michael Wrightd02c5b62014-02-10 15:10:22 -08004464 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004465 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004466 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4467 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004468 ASSERT_NO_FATAL_FAILURE(
4469 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004470
4471 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4472 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4473 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4474 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004475 ASSERT_NO_FATAL_FAILURE(
4476 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004477
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004478 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_EXTRA, 0);
4479 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004480 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004481 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004482 ASSERT_EQ(0, motionArgs.buttonState);
4483 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004484 ASSERT_NO_FATAL_FAILURE(
4485 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004486
4487 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4488 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4489 ASSERT_EQ(0, motionArgs.buttonState);
4490 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004491 ASSERT_NO_FATAL_FAILURE(
4492 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004493
Michael Wrightd02c5b62014-02-10 15:10:22 -08004494 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4495 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4496 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4497}
4498
4499TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerAround) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004500 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004501 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004502
4503 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
4504 mFakePointerController->setPosition(100, 200);
4505 mFakePointerController->setButtonState(0);
4506
4507 NotifyMotionArgs args;
4508
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004509 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4510 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4511 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004512 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004513 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4514 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4515 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4516 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
Michael Wright17db18e2020-06-26 20:51:44 +01004517 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004518}
4519
4520TEST_F(CursorInputMapperTest, Process_PointerCapture) {
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004521 addConfigurationProperty("cursor.mode", "pointer");
4522 mFakePolicy->setPointerCapture(true);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004523 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004524
4525 NotifyDeviceResetArgs resetArgs;
4526 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
4527 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
4528 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4529
4530 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
4531 mFakePointerController->setPosition(100, 200);
4532 mFakePointerController->setButtonState(0);
4533
4534 NotifyMotionArgs args;
4535
4536 // Move.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004537 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4538 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4539 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004540 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4541 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4542 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4543 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4544 10.0f, 20.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
Michael Wright17db18e2020-06-26 20:51:44 +01004545 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 100.0f, 200.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004546
4547 // Button press.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004548 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4549 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004550 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4551 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4552 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
4553 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4554 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4555 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4556 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4557 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
4558 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4559 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4560
4561 // Button release.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004562 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4563 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004564 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4565 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4566 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
4567 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4568 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4569 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4570 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4571 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
4572 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4573 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4574
4575 // Another move.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004576 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 30);
4577 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 40);
4578 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004579 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4580 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4581 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4582 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4583 30.0f, 40.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
Michael Wright17db18e2020-06-26 20:51:44 +01004584 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 100.0f, 200.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004585
4586 // Disable pointer capture and check that the device generation got bumped
4587 // and events are generated the usual way.
arthurhungdcef2dc2020-08-11 14:47:50 +08004588 const uint32_t generation = mReader->getContext()->getGeneration();
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004589 mFakePolicy->setPointerCapture(false);
4590 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
arthurhungdcef2dc2020-08-11 14:47:50 +08004591 ASSERT_TRUE(mReader->getContext()->getGeneration() != generation);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004592
4593 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004594 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4595
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004596 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4597 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4598 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004599 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4600 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004601 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4602 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4603 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
Michael Wright17db18e2020-06-26 20:51:44 +01004604 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004605}
4606
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00004607/**
4608 * When Pointer Capture is enabled, we expect to report unprocessed relative movements, so any
4609 * pointer acceleration or speed processing should not be applied.
4610 */
4611TEST_F(CursorInputMapperTest, PointerCaptureDisablesVelocityProcessing) {
4612 addConfigurationProperty("cursor.mode", "pointer");
4613 const VelocityControlParameters testParams(5.f /*scale*/, 0.f /*low threshold*/,
4614 100.f /*high threshold*/, 10.f /*acceleration*/);
4615 mFakePolicy->setVelocityControlParams(testParams);
4616 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4617
4618 NotifyDeviceResetArgs resetArgs;
4619 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
4620 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
4621 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4622
4623 NotifyMotionArgs args;
4624
4625 // Move and verify scale is applied.
4626 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4627 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4628 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4629 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4630 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4631 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4632 const float relX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
4633 const float relY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
4634 ASSERT_GT(relX, 10);
4635 ASSERT_GT(relY, 20);
4636
4637 // Enable Pointer Capture
4638 mFakePolicy->setPointerCapture(true);
4639 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
4640 NotifyPointerCaptureChangedArgs captureArgs;
4641 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
4642 ASSERT_TRUE(captureArgs.request.enable);
4643
4644 // Move and verify scale is not applied.
4645 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4646 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4647 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4648 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4649 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4650 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4651 ASSERT_EQ(10, args.pointerCoords[0].getX());
4652 ASSERT_EQ(20, args.pointerCoords[0].getY());
4653}
4654
Prabir Pradhan208360b2022-06-24 18:37:04 +00004655TEST_F(CursorInputMapperTest, PointerCaptureDisablesOrientationChanges) {
4656 addConfigurationProperty("cursor.mode", "pointer");
4657 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4658
4659 NotifyDeviceResetArgs resetArgs;
4660 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
4661 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
4662 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4663
4664 // Ensure the display is rotated.
Michael Wrighta9cf4192022-12-01 23:46:39 +00004665 prepareDisplay(ui::ROTATION_90);
Prabir Pradhan208360b2022-06-24 18:37:04 +00004666
4667 NotifyMotionArgs args;
4668
4669 // Verify that the coordinates are rotated.
4670 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4671 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4672 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4673 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4674 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4675 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4676 ASSERT_EQ(-20, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X));
4677 ASSERT_EQ(10, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
4678
4679 // Enable Pointer Capture.
4680 mFakePolicy->setPointerCapture(true);
4681 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
4682 NotifyPointerCaptureChangedArgs captureArgs;
4683 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
4684 ASSERT_TRUE(captureArgs.request.enable);
4685
4686 // Move and verify rotation is not applied.
4687 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4688 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4689 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4690 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4691 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4692 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4693 ASSERT_EQ(10, args.pointerCoords[0].getX());
4694 ASSERT_EQ(20, args.pointerCoords[0].getY());
4695}
4696
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004697TEST_F(CursorInputMapperTest, ConfigureDisplayId_NoAssociatedViewport) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004698 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004699
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004700 // Set up the default display.
Michael Wrighta9cf4192022-12-01 23:46:39 +00004701 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004702
4703 // Set up the secondary display as the display on which the pointer should be shown.
4704 // The InputDevice is not associated with any display.
4705 prepareSecondaryDisplay();
4706 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
Garfield Tan888a6a42020-01-09 11:39:16 -08004707 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
4708
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004709 mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004710 mFakePointerController->setPosition(100, 200);
4711 mFakePointerController->setButtonState(0);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004712
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004713 // Ensure input events are generated for the secondary display.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004714 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4715 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4716 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004717 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan739dca42022-09-09 20:12:01 +00004718 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4719 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(SECONDARY_DISPLAY_ID),
4720 WithCoords(110.0f, 220.0f))));
Michael Wright17db18e2020-06-26 20:51:44 +01004721 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004722}
4723
4724TEST_F(CursorInputMapperTest, ConfigureDisplayId_WithAssociatedViewport) {
4725 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4726
4727 // Set up the default display.
Michael Wrighta9cf4192022-12-01 23:46:39 +00004728 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004729
4730 // Set up the secondary display as the display on which the pointer should be shown,
4731 // and associate the InputDevice with the secondary display.
4732 prepareSecondaryDisplay();
4733 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
4734 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, SECONDARY_DISPLAY_UNIQUE_ID);
4735 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
4736
4737 mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
4738 mFakePointerController->setPosition(100, 200);
4739 mFakePointerController->setButtonState(0);
4740
4741 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4742 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4743 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4744 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan739dca42022-09-09 20:12:01 +00004745 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4746 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(SECONDARY_DISPLAY_ID),
4747 WithCoords(110.0f, 220.0f))));
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004748 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
4749}
4750
4751TEST_F(CursorInputMapperTest, ConfigureDisplayId_IgnoresEventsForMismatchedPointerDisplay) {
4752 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4753
4754 // Set up the default display as the display on which the pointer should be shown.
Michael Wrighta9cf4192022-12-01 23:46:39 +00004755 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004756 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
4757
4758 // Associate the InputDevice with the secondary display.
4759 prepareSecondaryDisplay();
4760 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, SECONDARY_DISPLAY_UNIQUE_ID);
4761 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
4762
4763 // The mapper should not generate any events because it is associated with a display that is
4764 // different from the pointer display.
4765 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4766 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4767 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4768 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004769}
4770
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00004771// --- BluetoothCursorInputMapperTest ---
4772
4773class BluetoothCursorInputMapperTest : public CursorInputMapperTest {
4774protected:
4775 void SetUp() override {
4776 InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL, BUS_BLUETOOTH);
4777
4778 mFakePointerController = std::make_shared<FakePointerController>();
4779 mFakePolicy->setPointerController(mFakePointerController);
4780 }
4781};
4782
4783TEST_F(BluetoothCursorInputMapperTest, TimestampSmoothening) {
4784 addConfigurationProperty("cursor.mode", "pointer");
4785 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4786
4787 nsecs_t kernelEventTime = ARBITRARY_TIME;
4788 nsecs_t expectedEventTime = ARBITRARY_TIME;
4789 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
4790 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
4791 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4792 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4793 WithEventTime(expectedEventTime))));
4794
4795 // Process several events that come in quick succession, according to their timestamps.
4796 for (int i = 0; i < 3; i++) {
4797 constexpr static nsecs_t delta = ms2ns(1);
4798 static_assert(delta < MIN_BLUETOOTH_TIMESTAMP_DELTA);
4799 kernelEventTime += delta;
4800 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
4801
4802 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
4803 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
4804 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4805 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4806 WithEventTime(expectedEventTime))));
4807 }
4808}
4809
4810TEST_F(BluetoothCursorInputMapperTest, TimestampSmootheningIsCapped) {
4811 addConfigurationProperty("cursor.mode", "pointer");
4812 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4813
4814 nsecs_t expectedEventTime = ARBITRARY_TIME;
4815 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4816 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4817 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4818 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4819 WithEventTime(expectedEventTime))));
4820
4821 // Process several events with the same timestamp from the kernel.
4822 // Ensure that we do not generate events too far into the future.
4823 constexpr static int32_t numEvents =
4824 MAX_BLUETOOTH_SMOOTHING_DELTA / MIN_BLUETOOTH_TIMESTAMP_DELTA;
4825 for (int i = 0; i < numEvents; i++) {
4826 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
4827
4828 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4829 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4830 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4831 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4832 WithEventTime(expectedEventTime))));
4833 }
4834
4835 // By processing more events with the same timestamp, we should not generate events with a
4836 // timestamp that is more than the specified max time delta from the timestamp at its injection.
4837 const nsecs_t cappedEventTime = ARBITRARY_TIME + MAX_BLUETOOTH_SMOOTHING_DELTA;
4838 for (int i = 0; i < 3; i++) {
4839 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4840 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4841 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4842 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4843 WithEventTime(cappedEventTime))));
4844 }
4845}
4846
4847TEST_F(BluetoothCursorInputMapperTest, TimestampSmootheningNotUsed) {
4848 addConfigurationProperty("cursor.mode", "pointer");
4849 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4850
4851 nsecs_t kernelEventTime = ARBITRARY_TIME;
4852 nsecs_t expectedEventTime = ARBITRARY_TIME;
4853 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
4854 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
4855 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4856 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4857 WithEventTime(expectedEventTime))));
4858
4859 // If the next event has a timestamp that is sufficiently spaced out so that Bluetooth timestamp
4860 // smoothening is not needed, its timestamp is not affected.
4861 kernelEventTime += MAX_BLUETOOTH_SMOOTHING_DELTA + ms2ns(1);
4862 expectedEventTime = kernelEventTime;
4863
4864 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
4865 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
4866 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4867 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4868 WithEventTime(expectedEventTime))));
4869}
4870
Michael Wrightd02c5b62014-02-10 15:10:22 -08004871// --- TouchInputMapperTest ---
4872
4873class TouchInputMapperTest : public InputMapperTest {
4874protected:
4875 static const int32_t RAW_X_MIN;
4876 static const int32_t RAW_X_MAX;
4877 static const int32_t RAW_Y_MIN;
4878 static const int32_t RAW_Y_MAX;
4879 static const int32_t RAW_TOUCH_MIN;
4880 static const int32_t RAW_TOUCH_MAX;
4881 static const int32_t RAW_TOOL_MIN;
4882 static const int32_t RAW_TOOL_MAX;
4883 static const int32_t RAW_PRESSURE_MIN;
4884 static const int32_t RAW_PRESSURE_MAX;
4885 static const int32_t RAW_ORIENTATION_MIN;
4886 static const int32_t RAW_ORIENTATION_MAX;
4887 static const int32_t RAW_DISTANCE_MIN;
4888 static const int32_t RAW_DISTANCE_MAX;
4889 static const int32_t RAW_TILT_MIN;
4890 static const int32_t RAW_TILT_MAX;
4891 static const int32_t RAW_ID_MIN;
4892 static const int32_t RAW_ID_MAX;
4893 static const int32_t RAW_SLOT_MIN;
4894 static const int32_t RAW_SLOT_MAX;
4895 static const float X_PRECISION;
4896 static const float Y_PRECISION;
Santos Cordonfa5cf462017-04-05 10:37:00 -07004897 static const float X_PRECISION_VIRTUAL;
4898 static const float Y_PRECISION_VIRTUAL;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004899
4900 static const float GEOMETRIC_SCALE;
Jason Gerecke489fda82012-09-07 17:19:40 -07004901 static const TouchAffineTransformation AFFINE_TRANSFORM;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004902
4903 static const VirtualKeyDefinition VIRTUAL_KEYS[2];
4904
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07004905 const std::string UNIQUE_ID = "local:0";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004906 const std::string SECONDARY_UNIQUE_ID = "local:1";
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07004907
Michael Wrightd02c5b62014-02-10 15:10:22 -08004908 enum Axes {
4909 POSITION = 1 << 0,
4910 TOUCH = 1 << 1,
4911 TOOL = 1 << 2,
4912 PRESSURE = 1 << 3,
4913 ORIENTATION = 1 << 4,
4914 MINOR = 1 << 5,
4915 ID = 1 << 6,
4916 DISTANCE = 1 << 7,
4917 TILT = 1 << 8,
4918 SLOT = 1 << 9,
4919 TOOL_TYPE = 1 << 10,
4920 };
4921
Michael Wrighta9cf4192022-12-01 23:46:39 +00004922 void prepareDisplay(ui::Rotation orientation, std::optional<uint8_t> port = NO_PORT);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004923 void prepareSecondaryDisplay(ViewportType type, std::optional<uint8_t> port = NO_PORT);
Michael Wrighta9cf4192022-12-01 23:46:39 +00004924 void prepareVirtualDisplay(ui::Rotation orientation);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004925 void prepareVirtualKeys();
Jason Gerecke489fda82012-09-07 17:19:40 -07004926 void prepareLocationCalibration();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004927 int32_t toRawX(float displayX);
4928 int32_t toRawY(float displayY);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07004929 int32_t toRotatedRawX(float displayX);
4930 int32_t toRotatedRawY(float displayY);
Jason Gerecke489fda82012-09-07 17:19:40 -07004931 float toCookedX(float rawX, float rawY);
4932 float toCookedY(float rawX, float rawY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004933 float toDisplayX(int32_t rawX);
Santos Cordonfa5cf462017-04-05 10:37:00 -07004934 float toDisplayX(int32_t rawX, int32_t displayWidth);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004935 float toDisplayY(int32_t rawY);
Santos Cordonfa5cf462017-04-05 10:37:00 -07004936 float toDisplayY(int32_t rawY, int32_t displayHeight);
4937
Michael Wrightd02c5b62014-02-10 15:10:22 -08004938};
4939
4940const int32_t TouchInputMapperTest::RAW_X_MIN = 25;
4941const int32_t TouchInputMapperTest::RAW_X_MAX = 1019;
4942const int32_t TouchInputMapperTest::RAW_Y_MIN = 30;
4943const int32_t TouchInputMapperTest::RAW_Y_MAX = 1009;
4944const int32_t TouchInputMapperTest::RAW_TOUCH_MIN = 0;
4945const int32_t TouchInputMapperTest::RAW_TOUCH_MAX = 31;
4946const int32_t TouchInputMapperTest::RAW_TOOL_MIN = 0;
4947const int32_t TouchInputMapperTest::RAW_TOOL_MAX = 15;
Michael Wrightaa449c92017-12-13 21:21:43 +00004948const int32_t TouchInputMapperTest::RAW_PRESSURE_MIN = 0;
4949const int32_t TouchInputMapperTest::RAW_PRESSURE_MAX = 255;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004950const int32_t TouchInputMapperTest::RAW_ORIENTATION_MIN = -7;
4951const int32_t TouchInputMapperTest::RAW_ORIENTATION_MAX = 7;
4952const int32_t TouchInputMapperTest::RAW_DISTANCE_MIN = 0;
4953const int32_t TouchInputMapperTest::RAW_DISTANCE_MAX = 7;
4954const int32_t TouchInputMapperTest::RAW_TILT_MIN = 0;
4955const int32_t TouchInputMapperTest::RAW_TILT_MAX = 150;
4956const int32_t TouchInputMapperTest::RAW_ID_MIN = 0;
4957const int32_t TouchInputMapperTest::RAW_ID_MAX = 9;
4958const int32_t TouchInputMapperTest::RAW_SLOT_MIN = 0;
4959const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9;
4960const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH;
4961const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT;
Santos Cordonfa5cf462017-04-05 10:37:00 -07004962const float TouchInputMapperTest::X_PRECISION_VIRTUAL =
4963 float(RAW_X_MAX - RAW_X_MIN + 1) / VIRTUAL_DISPLAY_WIDTH;
4964const float TouchInputMapperTest::Y_PRECISION_VIRTUAL =
4965 float(RAW_Y_MAX - RAW_Y_MIN + 1) / VIRTUAL_DISPLAY_HEIGHT;
Jason Gerecke489fda82012-09-07 17:19:40 -07004966const TouchAffineTransformation TouchInputMapperTest::AFFINE_TRANSFORM =
4967 TouchAffineTransformation(1, -2, 3, -4, 5, -6);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004968
4969const float TouchInputMapperTest::GEOMETRIC_SCALE =
4970 avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN + 1),
4971 float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN + 1));
4972
4973const VirtualKeyDefinition TouchInputMapperTest::VIRTUAL_KEYS[2] = {
4974 { KEY_HOME, 60, DISPLAY_HEIGHT + 15, 20, 20 },
4975 { KEY_MENU, DISPLAY_HEIGHT - 60, DISPLAY_WIDTH + 15, 20, 20 },
4976};
4977
Michael Wrighta9cf4192022-12-01 23:46:39 +00004978void TouchInputMapperTest::prepareDisplay(ui::Rotation orientation, std::optional<uint8_t> port) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01004979 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation, UNIQUE_ID,
4980 port, ViewportType::INTERNAL);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004981}
4982
4983void TouchInputMapperTest::prepareSecondaryDisplay(ViewportType type, std::optional<uint8_t> port) {
4984 setDisplayInfoAndReconfigure(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrighta9cf4192022-12-01 23:46:39 +00004985 ui::ROTATION_0, SECONDARY_UNIQUE_ID, port, type);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004986}
4987
Michael Wrighta9cf4192022-12-01 23:46:39 +00004988void TouchInputMapperTest::prepareVirtualDisplay(ui::Rotation orientation) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01004989 setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH, VIRTUAL_DISPLAY_HEIGHT,
4990 orientation, VIRTUAL_DISPLAY_UNIQUE_ID, NO_PORT,
4991 ViewportType::VIRTUAL);
Santos Cordonfa5cf462017-04-05 10:37:00 -07004992}
4993
Michael Wrightd02c5b62014-02-10 15:10:22 -08004994void TouchInputMapperTest::prepareVirtualKeys() {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004995 mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[0]);
4996 mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[1]);
4997 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
4998 mFakeEventHub->addKey(EVENTHUB_ID, KEY_MENU, 0, AKEYCODE_MENU, POLICY_FLAG_WAKE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004999}
5000
Jason Gerecke489fda82012-09-07 17:19:40 -07005001void TouchInputMapperTest::prepareLocationCalibration() {
5002 mFakePolicy->setTouchAffineTransformation(AFFINE_TRANSFORM);
5003}
5004
Michael Wrightd02c5b62014-02-10 15:10:22 -08005005int32_t TouchInputMapperTest::toRawX(float displayX) {
5006 return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH + RAW_X_MIN);
5007}
5008
5009int32_t TouchInputMapperTest::toRawY(float displayY) {
5010 return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT + RAW_Y_MIN);
5011}
5012
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005013int32_t TouchInputMapperTest::toRotatedRawX(float displayX) {
5014 return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_HEIGHT + RAW_X_MIN);
5015}
5016
5017int32_t TouchInputMapperTest::toRotatedRawY(float displayY) {
5018 return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_WIDTH + RAW_Y_MIN);
5019}
5020
Jason Gerecke489fda82012-09-07 17:19:40 -07005021float TouchInputMapperTest::toCookedX(float rawX, float rawY) {
5022 AFFINE_TRANSFORM.applyTo(rawX, rawY);
5023 return rawX;
5024}
5025
5026float TouchInputMapperTest::toCookedY(float rawX, float rawY) {
5027 AFFINE_TRANSFORM.applyTo(rawX, rawY);
5028 return rawY;
5029}
5030
Michael Wrightd02c5b62014-02-10 15:10:22 -08005031float TouchInputMapperTest::toDisplayX(int32_t rawX) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005032 return toDisplayX(rawX, DISPLAY_WIDTH);
5033}
5034
5035float TouchInputMapperTest::toDisplayX(int32_t rawX, int32_t displayWidth) {
5036 return float(rawX - RAW_X_MIN) * displayWidth / (RAW_X_MAX - RAW_X_MIN + 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005037}
5038
5039float TouchInputMapperTest::toDisplayY(int32_t rawY) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005040 return toDisplayY(rawY, DISPLAY_HEIGHT);
5041}
5042
5043float TouchInputMapperTest::toDisplayY(int32_t rawY, int32_t displayHeight) {
5044 return float(rawY - RAW_Y_MIN) * displayHeight / (RAW_Y_MAX - RAW_Y_MIN + 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005045}
5046
5047
5048// --- SingleTouchInputMapperTest ---
5049
5050class SingleTouchInputMapperTest : public TouchInputMapperTest {
5051protected:
5052 void prepareButtons();
5053 void prepareAxes(int axes);
5054
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005055 void processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
5056 void processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
5057 void processUp(SingleTouchInputMapper& mappery);
5058 void processPressure(SingleTouchInputMapper& mapper, int32_t pressure);
5059 void processToolMajor(SingleTouchInputMapper& mapper, int32_t toolMajor);
5060 void processDistance(SingleTouchInputMapper& mapper, int32_t distance);
5061 void processTilt(SingleTouchInputMapper& mapper, int32_t tiltX, int32_t tiltY);
5062 void processKey(SingleTouchInputMapper& mapper, int32_t code, int32_t value);
5063 void processSync(SingleTouchInputMapper& mapper);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005064};
5065
5066void SingleTouchInputMapperTest::prepareButtons() {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005067 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005068}
5069
5070void SingleTouchInputMapperTest::prepareAxes(int axes) {
5071 if (axes & POSITION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005072 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
5073 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005074 }
5075 if (axes & PRESSURE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005076 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MIN,
5077 RAW_PRESSURE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005078 }
5079 if (axes & TOOL) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005080 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TOOL_WIDTH, RAW_TOOL_MIN, RAW_TOOL_MAX, 0,
5081 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005082 }
5083 if (axes & DISTANCE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005084 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_DISTANCE, RAW_DISTANCE_MIN,
5085 RAW_DISTANCE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005086 }
5087 if (axes & TILT) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005088 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_X, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
5089 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_Y, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005090 }
5091}
5092
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005093void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005094 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
5095 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
5096 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005097}
5098
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005099void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005100 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
5101 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005102}
5103
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005104void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005105 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005106}
5107
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005108void SingleTouchInputMapperTest::processPressure(SingleTouchInputMapper& mapper, int32_t pressure) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005109 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_PRESSURE, pressure);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005110}
5111
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005112void SingleTouchInputMapperTest::processToolMajor(SingleTouchInputMapper& mapper,
5113 int32_t toolMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005114 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TOOL_WIDTH, toolMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005115}
5116
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005117void SingleTouchInputMapperTest::processDistance(SingleTouchInputMapper& mapper, int32_t distance) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005118 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_DISTANCE, distance);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005119}
5120
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005121void SingleTouchInputMapperTest::processTilt(SingleTouchInputMapper& mapper, int32_t tiltX,
5122 int32_t tiltY) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005123 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_X, tiltX);
5124 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_Y, tiltY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005125}
5126
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005127void SingleTouchInputMapperTest::processKey(SingleTouchInputMapper& mapper, int32_t code,
5128 int32_t value) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005129 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005130}
5131
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005132void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005133 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005134}
5135
Michael Wrightd02c5b62014-02-10 15:10:22 -08005136TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndNotACursor_ReturnsPointer) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005137 prepareButtons();
5138 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005139 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005140
Harry Cutts16a24cc2022-10-26 15:22:19 +00005141 ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005142}
5143
Michael Wrightd02c5b62014-02-10 15:10:22 -08005144TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005145 prepareButtons();
5146 prepareAxes(POSITION);
5147 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005148 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005149
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005150 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005151}
5152
5153TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005154 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005155 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005156 prepareButtons();
5157 prepareAxes(POSITION);
5158 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005159 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005160
5161 // Unknown key.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005162 ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005163
5164 // Virtual key is down.
5165 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5166 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5167 processDown(mapper, x, y);
5168 processSync(mapper);
5169 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5170
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005171 ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005172
5173 // Virtual key is up.
5174 processUp(mapper);
5175 processSync(mapper);
5176 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5177
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005178 ASSERT_EQ(AKEY_STATE_UP, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005179}
5180
5181TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005182 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005183 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005184 prepareButtons();
5185 prepareAxes(POSITION);
5186 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005187 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005188
5189 // Unknown key.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005190 ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005191
5192 // Virtual key is down.
5193 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5194 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5195 processDown(mapper, x, y);
5196 processSync(mapper);
5197 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5198
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005199 ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005200
5201 // Virtual key is up.
5202 processUp(mapper);
5203 processSync(mapper);
5204 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5205
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005206 ASSERT_EQ(AKEY_STATE_UP, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005207}
5208
5209TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005210 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005211 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005212 prepareButtons();
5213 prepareAxes(POSITION);
5214 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005215 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005216
Michael Wrightd02c5b62014-02-10 15:10:22 -08005217 uint8_t flags[2] = { 0, 0 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07005218 ASSERT_TRUE(
5219 mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, {AKEYCODE_HOME, AKEYCODE_A}, flags));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005220 ASSERT_TRUE(flags[0]);
5221 ASSERT_FALSE(flags[1]);
5222}
5223
5224TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005225 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005226 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005227 prepareButtons();
5228 prepareAxes(POSITION);
5229 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005230 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005231
arthurhungdcef2dc2020-08-11 14:47:50 +08005232 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005233
5234 NotifyKeyArgs args;
5235
5236 // Press virtual key.
5237 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5238 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5239 processDown(mapper, x, y);
5240 processSync(mapper);
5241
5242 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
5243 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
5244 ASSERT_EQ(DEVICE_ID, args.deviceId);
5245 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
5246 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
5247 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
5248 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
5249 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
5250 ASSERT_EQ(KEY_HOME, args.scanCode);
5251 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
5252 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
5253
5254 // Release virtual key.
5255 processUp(mapper);
5256 processSync(mapper);
5257
5258 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
5259 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
5260 ASSERT_EQ(DEVICE_ID, args.deviceId);
5261 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
5262 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
5263 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
5264 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
5265 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
5266 ASSERT_EQ(KEY_HOME, args.scanCode);
5267 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
5268 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
5269
5270 // Should not have sent any motions.
5271 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5272}
5273
5274TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005275 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005276 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005277 prepareButtons();
5278 prepareAxes(POSITION);
5279 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005280 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005281
arthurhungdcef2dc2020-08-11 14:47:50 +08005282 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005283
5284 NotifyKeyArgs keyArgs;
5285
5286 // Press virtual key.
5287 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5288 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5289 processDown(mapper, x, y);
5290 processSync(mapper);
5291
5292 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5293 ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
5294 ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
5295 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
5296 ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
5297 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5298 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, keyArgs.flags);
5299 ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
5300 ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
5301 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
5302 ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
5303
5304 // Move out of bounds. This should generate a cancel and a pointer down since we moved
5305 // into the display area.
5306 y -= 100;
5307 processMove(mapper, x, y);
5308 processSync(mapper);
5309
5310 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5311 ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
5312 ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
5313 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
5314 ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
5315 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5316 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
5317 | AKEY_EVENT_FLAG_CANCELED, keyArgs.flags);
5318 ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
5319 ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
5320 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
5321 ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
5322
5323 NotifyMotionArgs motionArgs;
5324 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5325 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5326 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5327 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5328 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5329 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5330 ASSERT_EQ(0, motionArgs.flags);
5331 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5332 ASSERT_EQ(0, motionArgs.buttonState);
5333 ASSERT_EQ(0, motionArgs.edgeFlags);
5334 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5335 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5336 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5337 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5338 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5339 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5340 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5341 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5342
5343 // Keep moving out of bounds. Should generate a pointer move.
5344 y -= 50;
5345 processMove(mapper, x, y);
5346 processSync(mapper);
5347
5348 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5349 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5350 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5351 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5352 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5353 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5354 ASSERT_EQ(0, motionArgs.flags);
5355 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5356 ASSERT_EQ(0, motionArgs.buttonState);
5357 ASSERT_EQ(0, motionArgs.edgeFlags);
5358 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5359 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5360 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5361 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5362 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5363 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5364 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5365 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5366
5367 // Release out of bounds. Should generate a pointer up.
5368 processUp(mapper);
5369 processSync(mapper);
5370
5371 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5372 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5373 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5374 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5375 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5376 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5377 ASSERT_EQ(0, motionArgs.flags);
5378 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5379 ASSERT_EQ(0, motionArgs.buttonState);
5380 ASSERT_EQ(0, motionArgs.edgeFlags);
5381 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5382 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5383 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5384 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5385 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5386 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5387 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5388 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5389
5390 // Should not have sent any more keys or motions.
5391 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5392 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5393}
5394
5395TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005396 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005397 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005398 prepareButtons();
5399 prepareAxes(POSITION);
5400 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005401 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005402
arthurhungdcef2dc2020-08-11 14:47:50 +08005403 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005404
5405 NotifyMotionArgs motionArgs;
5406
5407 // Initially go down out of bounds.
5408 int32_t x = -10;
5409 int32_t y = -10;
5410 processDown(mapper, x, y);
5411 processSync(mapper);
5412
5413 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5414
5415 // Move into the display area. Should generate a pointer down.
5416 x = 50;
5417 y = 75;
5418 processMove(mapper, x, y);
5419 processSync(mapper);
5420
5421 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5422 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5423 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5424 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5425 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5426 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5427 ASSERT_EQ(0, motionArgs.flags);
5428 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5429 ASSERT_EQ(0, motionArgs.buttonState);
5430 ASSERT_EQ(0, motionArgs.edgeFlags);
5431 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5432 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5433 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5434 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5435 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5436 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5437 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5438 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5439
5440 // Release. Should generate a pointer up.
5441 processUp(mapper);
5442 processSync(mapper);
5443
5444 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5445 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5446 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5447 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5448 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5449 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5450 ASSERT_EQ(0, motionArgs.flags);
5451 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5452 ASSERT_EQ(0, motionArgs.buttonState);
5453 ASSERT_EQ(0, motionArgs.edgeFlags);
5454 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5455 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5456 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5457 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5458 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5459 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5460 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5461 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5462
5463 // Should not have sent any more keys or motions.
5464 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5465 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5466}
5467
Santos Cordonfa5cf462017-04-05 10:37:00 -07005468TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture_VirtualDisplay) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005469 addConfigurationProperty("touch.deviceType", "touchScreen");
5470 addConfigurationProperty("touch.displayId", VIRTUAL_DISPLAY_UNIQUE_ID);
5471
Michael Wrighta9cf4192022-12-01 23:46:39 +00005472 prepareVirtualDisplay(ui::ROTATION_0);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005473 prepareButtons();
5474 prepareAxes(POSITION);
5475 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005476 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Santos Cordonfa5cf462017-04-05 10:37:00 -07005477
arthurhungdcef2dc2020-08-11 14:47:50 +08005478 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005479
5480 NotifyMotionArgs motionArgs;
5481
5482 // Down.
5483 int32_t x = 100;
5484 int32_t y = 125;
5485 processDown(mapper, x, y);
5486 processSync(mapper);
5487
5488 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5489 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5490 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5491 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
5492 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5493 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5494 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5495 ASSERT_EQ(0, motionArgs.flags);
5496 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5497 ASSERT_EQ(0, motionArgs.buttonState);
5498 ASSERT_EQ(0, motionArgs.edgeFlags);
5499 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5500 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5501 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5502 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5503 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
5504 1, 0, 0, 0, 0, 0, 0, 0));
5505 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
5506 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
5507 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5508
5509 // Move.
5510 x += 50;
5511 y += 75;
5512 processMove(mapper, x, y);
5513 processSync(mapper);
5514
5515 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5516 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5517 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5518 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
5519 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5520 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5521 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5522 ASSERT_EQ(0, motionArgs.flags);
5523 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5524 ASSERT_EQ(0, motionArgs.buttonState);
5525 ASSERT_EQ(0, motionArgs.edgeFlags);
5526 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5527 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5528 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5529 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5530 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
5531 1, 0, 0, 0, 0, 0, 0, 0));
5532 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
5533 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
5534 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5535
5536 // Up.
5537 processUp(mapper);
5538 processSync(mapper);
5539
5540 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5541 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5542 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5543 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
5544 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5545 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5546 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5547 ASSERT_EQ(0, motionArgs.flags);
5548 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5549 ASSERT_EQ(0, motionArgs.buttonState);
5550 ASSERT_EQ(0, motionArgs.edgeFlags);
5551 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5552 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5553 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5554 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5555 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
5556 1, 0, 0, 0, 0, 0, 0, 0));
5557 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
5558 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
5559 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5560
5561 // Should not have sent any more keys or motions.
5562 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5563 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5564}
5565
Michael Wrightd02c5b62014-02-10 15:10:22 -08005566TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005567 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005568 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005569 prepareButtons();
5570 prepareAxes(POSITION);
5571 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005572 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005573
arthurhungdcef2dc2020-08-11 14:47:50 +08005574 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005575
5576 NotifyMotionArgs motionArgs;
5577
5578 // Down.
5579 int32_t x = 100;
5580 int32_t y = 125;
5581 processDown(mapper, x, y);
5582 processSync(mapper);
5583
5584 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5585 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5586 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5587 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5588 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5589 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5590 ASSERT_EQ(0, motionArgs.flags);
5591 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5592 ASSERT_EQ(0, motionArgs.buttonState);
5593 ASSERT_EQ(0, motionArgs.edgeFlags);
5594 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5595 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5596 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5597 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5598 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5599 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5600 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5601 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5602
5603 // Move.
5604 x += 50;
5605 y += 75;
5606 processMove(mapper, x, y);
5607 processSync(mapper);
5608
5609 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5610 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5611 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5612 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5613 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5614 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5615 ASSERT_EQ(0, motionArgs.flags);
5616 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5617 ASSERT_EQ(0, motionArgs.buttonState);
5618 ASSERT_EQ(0, motionArgs.edgeFlags);
5619 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5620 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5621 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5622 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5623 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5624 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5625 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5626 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5627
5628 // Up.
5629 processUp(mapper);
5630 processSync(mapper);
5631
5632 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5633 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5634 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5635 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5636 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5637 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5638 ASSERT_EQ(0, motionArgs.flags);
5639 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5640 ASSERT_EQ(0, motionArgs.buttonState);
5641 ASSERT_EQ(0, motionArgs.edgeFlags);
5642 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5643 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5644 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5645 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5646 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5647 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5648 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5649 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5650
5651 // Should not have sent any more keys or motions.
5652 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5653 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5654}
5655
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005656TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_DoesNotRotateMotions) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005657 addConfigurationProperty("touch.deviceType", "touchScreen");
5658 prepareButtons();
5659 prepareAxes(POSITION);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005660 // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
5661 // need to be rotated. Touchscreens are orientation-aware by default.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005662 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005663
5664 NotifyMotionArgs args;
5665
5666 // Rotation 90.
Michael Wrighta9cf4192022-12-01 23:46:39 +00005667 prepareDisplay(ui::ROTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005668 processDown(mapper, toRawX(50), toRawY(75));
5669 processSync(mapper);
5670
5671 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5672 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5673 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5674
5675 processUp(mapper);
5676 processSync(mapper);
5677 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5678}
5679
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005680TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_RotatesMotions) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005681 addConfigurationProperty("touch.deviceType", "touchScreen");
5682 prepareButtons();
5683 prepareAxes(POSITION);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005684 // Since InputReader works in the un-rotated coordinate space, only devices that are not
5685 // orientation-aware are affected by display rotation.
5686 addConfigurationProperty("touch.orientationAware", "0");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005687 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005688
5689 NotifyMotionArgs args;
5690
5691 // Rotation 0.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005692 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005693 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005694 processDown(mapper, toRawX(50), toRawY(75));
5695 processSync(mapper);
5696
5697 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5698 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5699 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5700
5701 processUp(mapper);
5702 processSync(mapper);
5703 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5704
5705 // Rotation 90.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005706 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005707 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005708 processDown(mapper, toRawX(75), RAW_Y_MAX - toRawY(50) + RAW_Y_MIN);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005709 processSync(mapper);
5710
5711 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5712 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5713 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5714
5715 processUp(mapper);
5716 processSync(mapper);
5717 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5718
5719 // Rotation 180.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005720 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005721 prepareDisplay(ui::ROTATION_180);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005722 processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
5723 processSync(mapper);
5724
5725 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5726 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5727 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5728
5729 processUp(mapper);
5730 processSync(mapper);
5731 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5732
5733 // Rotation 270.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005734 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005735 prepareDisplay(ui::ROTATION_270);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005736 processDown(mapper, RAW_X_MAX - toRawX(75) + RAW_X_MIN, toRawY(50));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005737 processSync(mapper);
5738
5739 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5740 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5741 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5742
5743 processUp(mapper);
5744 processSync(mapper);
5745 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5746}
5747
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005748TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation0_RotatesMotions) {
5749 addConfigurationProperty("touch.deviceType", "touchScreen");
5750 prepareButtons();
5751 prepareAxes(POSITION);
5752 addConfigurationProperty("touch.orientationAware", "1");
5753 addConfigurationProperty("touch.orientation", "ORIENTATION_0");
5754 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005755 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005756 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5757 NotifyMotionArgs args;
5758
5759 // Orientation 0.
5760 processDown(mapper, toRawX(50), toRawY(75));
5761 processSync(mapper);
5762
5763 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5764 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5765 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5766
5767 processUp(mapper);
5768 processSync(mapper);
5769 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5770}
5771
5772TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation90_RotatesMotions) {
5773 addConfigurationProperty("touch.deviceType", "touchScreen");
5774 prepareButtons();
5775 prepareAxes(POSITION);
5776 addConfigurationProperty("touch.orientationAware", "1");
5777 addConfigurationProperty("touch.orientation", "ORIENTATION_90");
5778 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005779 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005780 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5781 NotifyMotionArgs args;
5782
5783 // Orientation 90.
5784 processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
5785 processSync(mapper);
5786
5787 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5788 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5789 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5790
5791 processUp(mapper);
5792 processSync(mapper);
5793 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5794}
5795
5796TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation180_RotatesMotions) {
5797 addConfigurationProperty("touch.deviceType", "touchScreen");
5798 prepareButtons();
5799 prepareAxes(POSITION);
5800 addConfigurationProperty("touch.orientationAware", "1");
5801 addConfigurationProperty("touch.orientation", "ORIENTATION_180");
5802 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005803 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005804 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5805 NotifyMotionArgs args;
5806
5807 // Orientation 180.
5808 processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
5809 processSync(mapper);
5810
5811 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5812 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5813 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5814
5815 processUp(mapper);
5816 processSync(mapper);
5817 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5818}
5819
5820TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation270_RotatesMotions) {
5821 addConfigurationProperty("touch.deviceType", "touchScreen");
5822 prepareButtons();
5823 prepareAxes(POSITION);
5824 addConfigurationProperty("touch.orientationAware", "1");
5825 addConfigurationProperty("touch.orientation", "ORIENTATION_270");
5826 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005827 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005828 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5829 NotifyMotionArgs args;
5830
5831 // Orientation 270.
5832 processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
5833 processSync(mapper);
5834
5835 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5836 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5837 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5838
5839 processUp(mapper);
5840 processSync(mapper);
5841 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5842}
5843
5844TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationSpecified_RotatesMotionWithDisplay) {
5845 addConfigurationProperty("touch.deviceType", "touchScreen");
5846 prepareButtons();
5847 prepareAxes(POSITION);
5848 // Since InputReader works in the un-rotated coordinate space, only devices that are not
5849 // orientation-aware are affected by display rotation.
5850 addConfigurationProperty("touch.orientationAware", "0");
5851 addConfigurationProperty("touch.orientation", "ORIENTATION_90");
5852 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5853
5854 NotifyMotionArgs args;
5855
5856 // Orientation 90, Rotation 0.
5857 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005858 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005859 processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
5860 processSync(mapper);
5861
5862 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5863 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5864 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5865
5866 processUp(mapper);
5867 processSync(mapper);
5868 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5869
5870 // Orientation 90, Rotation 90.
5871 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005872 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005873 processDown(mapper, toRotatedRawX(50), toRotatedRawY(75));
5874 processSync(mapper);
5875
5876 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5877 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5878 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5879
5880 processUp(mapper);
5881 processSync(mapper);
5882 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5883
5884 // Orientation 90, Rotation 180.
5885 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005886 prepareDisplay(ui::ROTATION_180);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005887 processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
5888 processSync(mapper);
5889
5890 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5891 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5892 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5893
5894 processUp(mapper);
5895 processSync(mapper);
5896 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5897
5898 // Orientation 90, Rotation 270.
5899 clearViewports();
Michael Wrighta9cf4192022-12-01 23:46:39 +00005900 prepareDisplay(ui::ROTATION_270);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005901 processDown(mapper, RAW_X_MAX - toRotatedRawX(50) + RAW_X_MIN,
5902 RAW_Y_MAX - toRotatedRawY(75) + RAW_Y_MIN);
5903 processSync(mapper);
5904
5905 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5906 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5907 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5908
5909 processUp(mapper);
5910 processSync(mapper);
5911 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5912}
5913
Michael Wrightd02c5b62014-02-10 15:10:22 -08005914TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005915 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005916 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005917 prepareButtons();
5918 prepareAxes(POSITION | PRESSURE | TOOL | DISTANCE | TILT);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005919 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005920
5921 // These calculations are based on the input device calibration documentation.
5922 int32_t rawX = 100;
5923 int32_t rawY = 200;
5924 int32_t rawPressure = 10;
5925 int32_t rawToolMajor = 12;
5926 int32_t rawDistance = 2;
5927 int32_t rawTiltX = 30;
5928 int32_t rawTiltY = 110;
5929
5930 float x = toDisplayX(rawX);
5931 float y = toDisplayY(rawY);
5932 float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
5933 float size = float(rawToolMajor) / RAW_TOOL_MAX;
5934 float tool = float(rawToolMajor) * GEOMETRIC_SCALE;
5935 float distance = float(rawDistance);
5936
5937 float tiltCenter = (RAW_TILT_MAX + RAW_TILT_MIN) * 0.5f;
5938 float tiltScale = M_PI / 180;
5939 float tiltXAngle = (rawTiltX - tiltCenter) * tiltScale;
5940 float tiltYAngle = (rawTiltY - tiltCenter) * tiltScale;
5941 float orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
5942 float tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
5943
5944 processDown(mapper, rawX, rawY);
5945 processPressure(mapper, rawPressure);
5946 processToolMajor(mapper, rawToolMajor);
5947 processDistance(mapper, rawDistance);
5948 processTilt(mapper, rawTiltX, rawTiltY);
5949 processSync(mapper);
5950
5951 NotifyMotionArgs args;
5952 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5953 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
5954 x, y, pressure, size, tool, tool, tool, tool, orientation, distance));
5955 ASSERT_EQ(tilt, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TILT));
5956}
5957
Jason Gerecke489fda82012-09-07 17:19:40 -07005958TEST_F(SingleTouchInputMapperTest, Process_XYAxes_AffineCalibration) {
Jason Gerecke489fda82012-09-07 17:19:40 -07005959 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005960 prepareDisplay(ui::ROTATION_0);
Jason Gerecke489fda82012-09-07 17:19:40 -07005961 prepareLocationCalibration();
5962 prepareButtons();
5963 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005964 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Jason Gerecke489fda82012-09-07 17:19:40 -07005965
5966 int32_t rawX = 100;
5967 int32_t rawY = 200;
5968
5969 float x = toDisplayX(toCookedX(rawX, rawY));
5970 float y = toDisplayY(toCookedY(rawX, rawY));
5971
5972 processDown(mapper, rawX, rawY);
5973 processSync(mapper);
5974
5975 NotifyMotionArgs args;
5976 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5977 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
5978 x, y, 1, 0, 0, 0, 0, 0, 0, 0));
5979}
5980
Michael Wrightd02c5b62014-02-10 15:10:22 -08005981TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005982 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00005983 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005984 prepareButtons();
5985 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005986 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005987
5988 NotifyMotionArgs motionArgs;
5989 NotifyKeyArgs keyArgs;
5990
5991 processDown(mapper, 100, 200);
5992 processSync(mapper);
5993 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5994 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5995 ASSERT_EQ(0, motionArgs.buttonState);
5996
5997 // press BTN_LEFT, release BTN_LEFT
5998 processKey(mapper, BTN_LEFT, 1);
5999 processSync(mapper);
6000 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6001 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6002 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
6003
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006004 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6005 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6006 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
6007
Michael Wrightd02c5b62014-02-10 15:10:22 -08006008 processKey(mapper, BTN_LEFT, 0);
6009 processSync(mapper);
6010 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006011 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006012 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006013
6014 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006015 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006016 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006017
6018 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
6019 processKey(mapper, BTN_RIGHT, 1);
6020 processKey(mapper, BTN_MIDDLE, 1);
6021 processSync(mapper);
6022 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6023 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6024 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
6025 motionArgs.buttonState);
6026
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006027 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6028 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6029 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
6030
6031 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6032 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6033 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
6034 motionArgs.buttonState);
6035
Michael Wrightd02c5b62014-02-10 15:10:22 -08006036 processKey(mapper, BTN_RIGHT, 0);
6037 processSync(mapper);
6038 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006039 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006040 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006041
6042 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006043 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006044 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006045
6046 processKey(mapper, BTN_MIDDLE, 0);
6047 processSync(mapper);
6048 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006049 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006050 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006051
6052 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006053 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006054 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006055
6056 // press BTN_BACK, release BTN_BACK
6057 processKey(mapper, BTN_BACK, 1);
6058 processSync(mapper);
6059 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6060 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6061 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006062
Michael Wrightd02c5b62014-02-10 15:10:22 -08006063 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006064 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006065 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
6066
6067 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6068 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6069 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006070
6071 processKey(mapper, BTN_BACK, 0);
6072 processSync(mapper);
6073 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006074 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006075 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006076
6077 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006078 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006079 ASSERT_EQ(0, motionArgs.buttonState);
6080
Michael Wrightd02c5b62014-02-10 15:10:22 -08006081 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6082 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6083 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
6084
6085 // press BTN_SIDE, release BTN_SIDE
6086 processKey(mapper, BTN_SIDE, 1);
6087 processSync(mapper);
6088 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6089 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6090 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006091
Michael Wrightd02c5b62014-02-10 15:10:22 -08006092 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006093 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006094 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
6095
6096 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6097 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6098 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006099
6100 processKey(mapper, BTN_SIDE, 0);
6101 processSync(mapper);
6102 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006103 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006104 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006105
6106 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006107 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006108 ASSERT_EQ(0, motionArgs.buttonState);
6109
Michael Wrightd02c5b62014-02-10 15:10:22 -08006110 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6111 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6112 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
6113
6114 // press BTN_FORWARD, release BTN_FORWARD
6115 processKey(mapper, BTN_FORWARD, 1);
6116 processSync(mapper);
6117 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6118 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6119 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006120
Michael Wrightd02c5b62014-02-10 15:10:22 -08006121 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006122 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006123 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
6124
6125 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6126 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6127 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006128
6129 processKey(mapper, BTN_FORWARD, 0);
6130 processSync(mapper);
6131 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006132 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006133 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006134
6135 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006136 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006137 ASSERT_EQ(0, motionArgs.buttonState);
6138
Michael Wrightd02c5b62014-02-10 15:10:22 -08006139 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6140 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6141 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
6142
6143 // press BTN_EXTRA, release BTN_EXTRA
6144 processKey(mapper, BTN_EXTRA, 1);
6145 processSync(mapper);
6146 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6147 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6148 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006149
Michael Wrightd02c5b62014-02-10 15:10:22 -08006150 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006151 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006152 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
6153
6154 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6155 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6156 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006157
6158 processKey(mapper, BTN_EXTRA, 0);
6159 processSync(mapper);
6160 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006161 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006162 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006163
6164 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006165 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006166 ASSERT_EQ(0, motionArgs.buttonState);
6167
Michael Wrightd02c5b62014-02-10 15:10:22 -08006168 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6169 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6170 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
6171
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006172 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6173
Michael Wrightd02c5b62014-02-10 15:10:22 -08006174 // press BTN_STYLUS, release BTN_STYLUS
6175 processKey(mapper, BTN_STYLUS, 1);
6176 processSync(mapper);
6177 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6178 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006179 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
6180
6181 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6182 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6183 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006184
6185 processKey(mapper, BTN_STYLUS, 0);
6186 processSync(mapper);
6187 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006188 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006189 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006190
6191 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006192 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006193 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006194
6195 // press BTN_STYLUS2, release BTN_STYLUS2
6196 processKey(mapper, BTN_STYLUS2, 1);
6197 processSync(mapper);
6198 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6199 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006200 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
6201
6202 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6203 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6204 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006205
6206 processKey(mapper, BTN_STYLUS2, 0);
6207 processSync(mapper);
6208 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006209 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006210 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006211
6212 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006213 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006214 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006215
6216 // release touch
6217 processUp(mapper);
6218 processSync(mapper);
6219 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6220 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6221 ASSERT_EQ(0, motionArgs.buttonState);
6222}
6223
6224TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006225 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006226 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006227 prepareButtons();
6228 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006229 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006230
6231 NotifyMotionArgs motionArgs;
6232
6233 // default tool type is finger
6234 processDown(mapper, 100, 200);
6235 processSync(mapper);
6236 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6237 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6238 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6239
6240 // eraser
6241 processKey(mapper, BTN_TOOL_RUBBER, 1);
6242 processSync(mapper);
6243 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6244 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6245 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
6246
6247 // stylus
6248 processKey(mapper, BTN_TOOL_RUBBER, 0);
6249 processKey(mapper, BTN_TOOL_PEN, 1);
6250 processSync(mapper);
6251 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6252 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6253 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6254
6255 // brush
6256 processKey(mapper, BTN_TOOL_PEN, 0);
6257 processKey(mapper, BTN_TOOL_BRUSH, 1);
6258 processSync(mapper);
6259 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6260 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6261 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6262
6263 // pencil
6264 processKey(mapper, BTN_TOOL_BRUSH, 0);
6265 processKey(mapper, BTN_TOOL_PENCIL, 1);
6266 processSync(mapper);
6267 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6268 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6269 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6270
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08006271 // air-brush
Michael Wrightd02c5b62014-02-10 15:10:22 -08006272 processKey(mapper, BTN_TOOL_PENCIL, 0);
6273 processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
6274 processSync(mapper);
6275 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6276 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6277 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6278
6279 // mouse
6280 processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
6281 processKey(mapper, BTN_TOOL_MOUSE, 1);
6282 processSync(mapper);
6283 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6284 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6285 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
6286
6287 // lens
6288 processKey(mapper, BTN_TOOL_MOUSE, 0);
6289 processKey(mapper, BTN_TOOL_LENS, 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_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
6294
6295 // double-tap
6296 processKey(mapper, BTN_TOOL_LENS, 0);
6297 processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
6298 processSync(mapper);
6299 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6300 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6301 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6302
6303 // triple-tap
6304 processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
6305 processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
6306 processSync(mapper);
6307 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6308 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6309 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6310
6311 // quad-tap
6312 processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
6313 processKey(mapper, BTN_TOOL_QUADTAP, 1);
6314 processSync(mapper);
6315 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6316 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6317 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6318
6319 // finger
6320 processKey(mapper, BTN_TOOL_QUADTAP, 0);
6321 processKey(mapper, BTN_TOOL_FINGER, 1);
6322 processSync(mapper);
6323 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6324 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6325 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6326
6327 // stylus trumps finger
6328 processKey(mapper, BTN_TOOL_PEN, 1);
6329 processSync(mapper);
6330 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6331 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6332 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6333
6334 // eraser trumps stylus
6335 processKey(mapper, BTN_TOOL_RUBBER, 1);
6336 processSync(mapper);
6337 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6338 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6339 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
6340
6341 // mouse trumps eraser
6342 processKey(mapper, BTN_TOOL_MOUSE, 1);
6343 processSync(mapper);
6344 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6345 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6346 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
6347
6348 // back to default tool type
6349 processKey(mapper, BTN_TOOL_MOUSE, 0);
6350 processKey(mapper, BTN_TOOL_RUBBER, 0);
6351 processKey(mapper, BTN_TOOL_PEN, 0);
6352 processKey(mapper, BTN_TOOL_FINGER, 0);
6353 processSync(mapper);
6354 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6355 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6356 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6357}
6358
6359TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006360 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006361 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006362 prepareButtons();
6363 prepareAxes(POSITION);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006364 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_FINGER, 0, AKEYCODE_UNKNOWN, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006365 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006366
6367 NotifyMotionArgs motionArgs;
6368
6369 // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
6370 processKey(mapper, BTN_TOOL_FINGER, 1);
6371 processMove(mapper, 100, 200);
6372 processSync(mapper);
6373 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6374 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6375 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6376 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6377
6378 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6379 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6380 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6381 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6382
6383 // move a little
6384 processMove(mapper, 150, 250);
6385 processSync(mapper);
6386 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6387 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6388 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6389 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6390
6391 // down when BTN_TOUCH is pressed, pressure defaults to 1
6392 processKey(mapper, BTN_TOUCH, 1);
6393 processSync(mapper);
6394 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6395 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6396 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6397 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6398
6399 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6400 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6401 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6402 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6403
6404 // up when BTN_TOUCH is released, hover restored
6405 processKey(mapper, BTN_TOUCH, 0);
6406 processSync(mapper);
6407 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6408 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6409 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6410 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6411
6412 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6413 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6414 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6415 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6416
6417 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6418 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6419 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6420 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6421
6422 // exit hover when pointer goes away
6423 processKey(mapper, BTN_TOOL_FINGER, 0);
6424 processSync(mapper);
6425 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6426 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6427 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6428 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6429}
6430
6431TEST_F(SingleTouchInputMapperTest, Process_WhenAbsPressureIsPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006432 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006433 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006434 prepareButtons();
6435 prepareAxes(POSITION | PRESSURE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006436 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006437
6438 NotifyMotionArgs motionArgs;
6439
6440 // initially hovering because pressure is 0
6441 processDown(mapper, 100, 200);
6442 processPressure(mapper, 0);
6443 processSync(mapper);
6444 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6445 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6446 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6447 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6448
6449 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6450 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6451 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6452 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6453
6454 // move a little
6455 processMove(mapper, 150, 250);
6456 processSync(mapper);
6457 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6458 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6459 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6460 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6461
6462 // down when pressure is non-zero
6463 processPressure(mapper, RAW_PRESSURE_MAX);
6464 processSync(mapper);
6465 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6466 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6467 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6468 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6469
6470 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6471 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6472 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6473 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6474
6475 // up when pressure becomes 0, hover restored
6476 processPressure(mapper, 0);
6477 processSync(mapper);
6478 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6479 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6480 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6481 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6482
6483 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6484 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6485 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6486 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6487
6488 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6489 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6490 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6491 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6492
6493 // exit hover when pointer goes away
6494 processUp(mapper);
6495 processSync(mapper);
6496 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6497 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6498 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6499 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6500}
6501
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00006502TEST_F(SingleTouchInputMapperTest, Reset_CancelsOngoingGesture) {
6503 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006504 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00006505 prepareButtons();
6506 prepareAxes(POSITION | PRESSURE);
6507 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6508
6509 // Touch down.
6510 processDown(mapper, 100, 200);
6511 processPressure(mapper, 1);
6512 processSync(mapper);
6513 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6514 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
6515
6516 // Reset the mapper. This should cancel the ongoing gesture.
6517 resetMapper(mapper, ARBITRARY_TIME);
6518 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6519 WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
6520
6521 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6522}
6523
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006524TEST_F(SingleTouchInputMapperTest, Reset_RecreatesTouchState) {
6525 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006526 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006527 prepareButtons();
6528 prepareAxes(POSITION | PRESSURE);
6529 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6530
6531 // Set the initial state for the touch pointer.
6532 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_X, 100);
6533 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_Y, 200);
6534 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MAX);
6535 mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1);
6536
6537 // Reset the mapper. When the mapper is reset, we expect it to attempt to recreate the touch
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00006538 // state by reading the current axis values. Since there was no ongoing gesture, calling reset
6539 // does not generate any events.
6540 resetMapper(mapper, ARBITRARY_TIME);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006541
6542 // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
6543 // the recreated touch state to generate a down event.
6544 processSync(mapper);
6545 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6546 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
6547
6548 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6549}
6550
lilinnan687e58f2022-07-19 16:00:50 +08006551TEST_F(SingleTouchInputMapperTest,
6552 Process_WhenViewportDisplayIdChanged_TouchIsCanceledAndDeviceIsReset) {
6553 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006554 prepareDisplay(ui::ROTATION_0);
lilinnan687e58f2022-07-19 16:00:50 +08006555 prepareButtons();
6556 prepareAxes(POSITION);
6557 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6558 NotifyMotionArgs motionArgs;
6559
6560 // Down.
Prabir Pradhan3e5ec702022-07-29 16:26:24 +00006561 processDown(mapper, 100, 200);
lilinnan687e58f2022-07-19 16:00:50 +08006562 processSync(mapper);
6563
6564 // We should receive a down event
6565 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6566 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6567
6568 // Change display id
6569 clearViewports();
6570 prepareSecondaryDisplay(ViewportType::INTERNAL);
6571
6572 // We should receive a cancel event
6573 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6574 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
6575 // Then receive reset called
6576 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6577}
6578
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006579TEST_F(SingleTouchInputMapperTest,
6580 Process_WhenViewportActiveStatusChanged_TouchIsCanceledAndDeviceIsReset) {
6581 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006582 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006583 prepareButtons();
6584 prepareAxes(POSITION);
6585 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6586 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6587 NotifyMotionArgs motionArgs;
6588
6589 // Start a new gesture.
6590 processDown(mapper, 100, 200);
6591 processSync(mapper);
6592 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6593 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6594
6595 // Make the viewport inactive. This will put the device in disabled mode.
6596 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
6597 viewport->isActive = false;
6598 mFakePolicy->updateViewport(*viewport);
6599 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
6600
6601 // We should receive a cancel event for the ongoing gesture.
6602 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6603 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
6604 // Then we should be notified that the device was reset.
6605 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6606
6607 // No events are generated while the viewport is inactive.
6608 processMove(mapper, 101, 201);
6609 processSync(mapper);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006610 processUp(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006611 processSync(mapper);
6612 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6613
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006614 // Start a new gesture while the viewport is still inactive.
6615 processDown(mapper, 300, 400);
6616 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_X, 300);
6617 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_Y, 400);
6618 mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1);
6619 processSync(mapper);
6620
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006621 // Make the viewport active again. The device should resume processing events.
6622 viewport->isActive = true;
6623 mFakePolicy->updateViewport(*viewport);
6624 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
6625
6626 // The device is reset because it changes back to direct mode, without generating any events.
6627 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6628 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6629
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006630 // In the next sync, the touch state that was recreated when the device was reset is reported.
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006631 processSync(mapper);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006632 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6633 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006634
6635 // No more events.
6636 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6637 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
6638}
6639
Prabir Pradhan211ba622022-10-31 21:09:21 +00006640TEST_F(SingleTouchInputMapperTest, ButtonIsReleasedOnTouchUp) {
6641 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006642 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan211ba622022-10-31 21:09:21 +00006643 prepareButtons();
6644 prepareAxes(POSITION);
6645 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6646 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6647
6648 // Press a stylus button.
6649 processKey(mapper, BTN_STYLUS, 1);
6650 processSync(mapper);
6651
6652 // Start a touch gesture and ensure the BUTTON_PRESS event is generated.
6653 processDown(mapper, 100, 200);
6654 processSync(mapper);
6655 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6656 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
6657 WithCoords(toDisplayX(100), toDisplayY(200)),
6658 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
6659 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6660 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
6661 WithCoords(toDisplayX(100), toDisplayY(200)),
6662 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
6663
6664 // Release the touch gesture. Ensure that the BUTTON_RELEASE event is generated even though
6665 // the button has not actually been released, since there will be no pointers through which the
6666 // button state can be reported. The event is generated at the location of the pointer before
6667 // it went up.
6668 processUp(mapper);
6669 processSync(mapper);
6670 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6671 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
6672 WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
6673 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6674 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
6675 WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
6676}
6677
Prabir Pradhan5632d622021-09-06 07:57:20 -07006678// --- TouchDisplayProjectionTest ---
6679
6680class TouchDisplayProjectionTest : public SingleTouchInputMapperTest {
6681public:
6682 // The values inside DisplayViewport are expected to be pre-rotated. This updates the current
6683 // DisplayViewport to pre-rotate the values. The viewport's physical display will be set to the
6684 // rotated equivalent of the given un-rotated physical display bounds.
Michael Wrighta9cf4192022-12-01 23:46:39 +00006685 void configurePhysicalDisplay(ui::Rotation orientation, Rect naturalPhysicalDisplay) {
Prabir Pradhan5632d622021-09-06 07:57:20 -07006686 uint32_t inverseRotationFlags;
6687 auto width = DISPLAY_WIDTH;
6688 auto height = DISPLAY_HEIGHT;
6689 switch (orientation) {
Michael Wrighta9cf4192022-12-01 23:46:39 +00006690 case ui::ROTATION_90:
Prabir Pradhan5632d622021-09-06 07:57:20 -07006691 inverseRotationFlags = ui::Transform::ROT_270;
6692 std::swap(width, height);
6693 break;
Michael Wrighta9cf4192022-12-01 23:46:39 +00006694 case ui::ROTATION_180:
Prabir Pradhan5632d622021-09-06 07:57:20 -07006695 inverseRotationFlags = ui::Transform::ROT_180;
6696 break;
Michael Wrighta9cf4192022-12-01 23:46:39 +00006697 case ui::ROTATION_270:
Prabir Pradhan5632d622021-09-06 07:57:20 -07006698 inverseRotationFlags = ui::Transform::ROT_90;
6699 std::swap(width, height);
6700 break;
Michael Wrighta9cf4192022-12-01 23:46:39 +00006701 case ui::ROTATION_0:
Prabir Pradhan5632d622021-09-06 07:57:20 -07006702 inverseRotationFlags = ui::Transform::ROT_0;
6703 break;
Prabir Pradhan5632d622021-09-06 07:57:20 -07006704 }
6705
6706 const ui::Transform rotation(inverseRotationFlags, width, height);
6707 const Rect rotatedPhysicalDisplay = rotation.transform(naturalPhysicalDisplay);
6708
6709 std::optional<DisplayViewport> internalViewport =
6710 *mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
6711 DisplayViewport& v = *internalViewport;
6712 v.displayId = DISPLAY_ID;
6713 v.orientation = orientation;
6714
6715 v.logicalLeft = 0;
6716 v.logicalTop = 0;
6717 v.logicalRight = 100;
6718 v.logicalBottom = 100;
6719
6720 v.physicalLeft = rotatedPhysicalDisplay.left;
6721 v.physicalTop = rotatedPhysicalDisplay.top;
6722 v.physicalRight = rotatedPhysicalDisplay.right;
6723 v.physicalBottom = rotatedPhysicalDisplay.bottom;
6724
6725 v.deviceWidth = width;
6726 v.deviceHeight = height;
6727
6728 v.isActive = true;
6729 v.uniqueId = UNIQUE_ID;
6730 v.type = ViewportType::INTERNAL;
6731 mFakePolicy->updateViewport(v);
6732 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
6733 }
6734
6735 void assertReceivedMove(const Point& point) {
6736 NotifyMotionArgs motionArgs;
6737 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6738 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6739 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6740 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], point.x, point.y,
6741 1, 0, 0, 0, 0, 0, 0, 0));
6742 }
6743};
6744
6745TEST_F(TouchDisplayProjectionTest, IgnoresTouchesOutsidePhysicalDisplay) {
6746 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006747 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan5632d622021-09-06 07:57:20 -07006748
6749 prepareButtons();
6750 prepareAxes(POSITION);
6751 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6752
6753 NotifyMotionArgs motionArgs;
6754
6755 // Configure the DisplayViewport such that the logical display maps to a subsection of
6756 // the display panel called the physical display. Here, the physical display is bounded by the
6757 // points (10, 20) and (70, 160) inside the display space, which is of the size 400 x 800.
6758 static const Rect kPhysicalDisplay{10, 20, 70, 160};
6759 static const std::array<Point, 6> kPointsOutsidePhysicalDisplay{
6760 {{-10, -10}, {0, 0}, {5, 100}, {50, 15}, {75, 100}, {50, 165}}};
6761
Michael Wrighta9cf4192022-12-01 23:46:39 +00006762 for (auto orientation : {ui::ROTATION_0, ui::ROTATION_90, ui::ROTATION_180, ui::ROTATION_270}) {
Prabir Pradhan5632d622021-09-06 07:57:20 -07006763 configurePhysicalDisplay(orientation, kPhysicalDisplay);
6764
6765 // Touches outside the physical display should be ignored, and should not generate any
6766 // events. Ensure touches at the following points that lie outside of the physical display
6767 // area do not generate any events.
6768 for (const auto& point : kPointsOutsidePhysicalDisplay) {
6769 processDown(mapper, toRawX(point.x), toRawY(point.y));
6770 processSync(mapper);
6771 processUp(mapper);
6772 processSync(mapper);
6773 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled())
6774 << "Unexpected event generated for touch outside physical display at point: "
6775 << point.x << ", " << point.y;
6776 }
6777 }
6778}
6779
6780TEST_F(TouchDisplayProjectionTest, EmitsTouchDownAfterEnteringPhysicalDisplay) {
6781 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006782 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan5632d622021-09-06 07:57:20 -07006783
6784 prepareButtons();
6785 prepareAxes(POSITION);
6786 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6787
6788 NotifyMotionArgs motionArgs;
6789
6790 // Configure the DisplayViewport such that the logical display maps to a subsection of
6791 // the display panel called the physical display. Here, the physical display is bounded by the
6792 // points (10, 20) and (70, 160) inside the display space, which is of the size 400 x 800.
6793 static const Rect kPhysicalDisplay{10, 20, 70, 160};
6794
Michael Wrighta9cf4192022-12-01 23:46:39 +00006795 for (auto orientation : {ui::ROTATION_0, ui::ROTATION_90, ui::ROTATION_180, ui::ROTATION_270}) {
Prabir Pradhan5632d622021-09-06 07:57:20 -07006796 configurePhysicalDisplay(orientation, kPhysicalDisplay);
6797
6798 // Touches that start outside the physical display should be ignored until it enters the
6799 // physical display bounds, at which point it should generate a down event. Start a touch at
6800 // the point (5, 100), which is outside the physical display bounds.
6801 static const Point kOutsidePoint{5, 100};
6802 processDown(mapper, toRawX(kOutsidePoint.x), toRawY(kOutsidePoint.y));
6803 processSync(mapper);
6804 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6805
6806 // Move the touch into the physical display area. This should generate a pointer down.
6807 processMove(mapper, toRawX(11), toRawY(21));
6808 processSync(mapper);
6809 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6810 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6811 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6812 ASSERT_NO_FATAL_FAILURE(
6813 assertPointerCoords(motionArgs.pointerCoords[0], 11, 21, 1, 0, 0, 0, 0, 0, 0, 0));
6814
6815 // Move the touch inside the physical display area. This should generate a pointer move.
6816 processMove(mapper, toRawX(69), toRawY(159));
6817 processSync(mapper);
6818 assertReceivedMove({69, 159});
6819
6820 // Move outside the physical display area. Since the pointer is already down, this should
6821 // now continue generating events.
6822 processMove(mapper, toRawX(kOutsidePoint.x), toRawY(kOutsidePoint.y));
6823 processSync(mapper);
6824 assertReceivedMove(kOutsidePoint);
6825
6826 // Release. This should generate a pointer up.
6827 processUp(mapper);
6828 processSync(mapper);
6829 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6830 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6831 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], kOutsidePoint.x,
6832 kOutsidePoint.y, 1, 0, 0, 0, 0, 0, 0, 0));
6833
6834 // Ensure no more events were generated.
6835 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6836 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6837 }
6838}
6839
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00006840// --- ExternalStylusFusionTest ---
6841
6842class ExternalStylusFusionTest : public SingleTouchInputMapperTest {
6843public:
6844 SingleTouchInputMapper& initializeInputMapperWithExternalStylus() {
6845 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00006846 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00006847 prepareButtons();
6848 prepareAxes(POSITION);
6849 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6850
6851 mStylusState.when = ARBITRARY_TIME;
6852 mStylusState.pressure = 0.f;
6853 mStylusState.toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
6854 mReader->getContext()->setExternalStylusDevices({mExternalStylusDeviceInfo});
6855 configureDevice(InputReaderConfiguration::CHANGE_EXTERNAL_STYLUS_PRESENCE);
6856 processExternalStylusState(mapper);
6857 return mapper;
6858 }
6859
6860 std::list<NotifyArgs> processExternalStylusState(InputMapper& mapper) {
6861 std::list<NotifyArgs> generatedArgs = mapper.updateExternalStylusState(mStylusState);
6862 for (const NotifyArgs& args : generatedArgs) {
6863 mFakeListener->notify(args);
6864 }
6865 // Loop the reader to flush the input listener queue.
6866 mReader->loopOnce();
6867 return generatedArgs;
6868 }
6869
6870protected:
6871 StylusState mStylusState{};
6872 static constexpr uint32_t EXPECTED_SOURCE =
6873 AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_BLUETOOTH_STYLUS;
6874
6875 void testStartFusedStylusGesture(SingleTouchInputMapper& mapper) {
6876 auto toolTypeSource =
6877 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS));
6878
6879 // The first pointer is withheld.
6880 processDown(mapper, 100, 200);
6881 processSync(mapper);
6882 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6883 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
6884 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
6885
6886 // The external stylus reports pressure. The withheld finger pointer is released as a
6887 // stylus.
6888 mStylusState.pressure = 1.f;
6889 processExternalStylusState(mapper);
6890 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6891 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
6892 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
6893
6894 // Subsequent pointer events are not withheld.
6895 processMove(mapper, 101, 201);
6896 processSync(mapper);
6897 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6898 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
6899
6900 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
6901 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6902 }
6903
6904 void testSuccessfulFusionGesture(SingleTouchInputMapper& mapper) {
6905 ASSERT_NO_FATAL_FAILURE(testStartFusedStylusGesture(mapper));
6906
6907 // Releasing the touch pointer ends the gesture.
6908 processUp(mapper);
6909 processSync(mapper);
6910 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6911 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(EXPECTED_SOURCE),
6912 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
6913
6914 mStylusState.pressure = 0.f;
6915 processExternalStylusState(mapper);
6916 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
6917 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6918 }
6919
6920 void testUnsuccessfulFusionGesture(SingleTouchInputMapper& mapper) {
6921 auto toolTypeSource =
6922 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER));
6923
6924 // The first pointer is withheld when an external stylus is connected,
6925 // and a timeout is requested.
6926 processDown(mapper, 100, 200);
6927 processSync(mapper);
6928 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6929 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
6930 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
6931
6932 // If the timeout expires early, it is requested again.
6933 handleTimeout(mapper, ARBITRARY_TIME + 1);
6934 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
6935 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
6936
6937 // When the timeout expires, the withheld touch is released as a finger pointer.
6938 handleTimeout(mapper, ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT);
6939 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6940 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
6941
6942 // Subsequent pointer events are not withheld.
6943 processMove(mapper, 101, 201);
6944 processSync(mapper);
6945 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6946 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
6947 processUp(mapper);
6948 processSync(mapper);
6949 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6950 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP))));
6951
6952 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
6953 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6954 }
6955
6956private:
6957 InputDeviceInfo mExternalStylusDeviceInfo{};
6958};
6959
6960TEST_F(ExternalStylusFusionTest, UsesBluetoothStylusSource) {
6961 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
6962 ASSERT_EQ(EXPECTED_SOURCE, mapper.getSources());
6963}
6964
6965TEST_F(ExternalStylusFusionTest, UnsuccessfulFusion) {
6966 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
6967 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
6968}
6969
6970TEST_F(ExternalStylusFusionTest, SuccessfulFusion_TouchFirst) {
6971 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
6972 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
6973}
6974
6975// Test a successful stylus fusion gesture where the pressure is reported by the external
6976// before the touch is reported by the touchscreen.
6977TEST_F(ExternalStylusFusionTest, SuccessfulFusion_PressureFirst) {
6978 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
6979 auto toolTypeSource =
6980 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS));
6981
6982 // The external stylus reports pressure first. It is ignored for now.
6983 mStylusState.pressure = 1.f;
6984 processExternalStylusState(mapper);
6985 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6986 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
6987
6988 // When the touch goes down afterwards, it is reported as a stylus pointer.
6989 processDown(mapper, 100, 200);
6990 processSync(mapper);
6991 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6992 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
6993 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
6994
6995 processMove(mapper, 101, 201);
6996 processSync(mapper);
6997 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6998 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
6999 processUp(mapper);
7000 processSync(mapper);
7001 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7002 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP))));
7003
7004 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7005 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7006}
7007
7008TEST_F(ExternalStylusFusionTest, FusionIsRepeatedForEachNewGesture) {
7009 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7010
7011 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
7012 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
7013
7014 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
7015 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
7016 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
7017 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
7018}
7019
7020TEST_F(ExternalStylusFusionTest, FusedPointerReportsPressureChanges) {
7021 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7022 auto toolTypeSource =
7023 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS));
7024
7025 mStylusState.pressure = 0.8f;
7026 processExternalStylusState(mapper);
7027 processDown(mapper, 100, 200);
7028 processSync(mapper);
7029 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7030 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
7031 WithPressure(0.8f))));
7032 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7033
7034 // The external stylus reports a pressure change. We wait for some time for a touch event.
7035 mStylusState.pressure = 0.6f;
7036 processExternalStylusState(mapper);
7037 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7038 ASSERT_NO_FATAL_FAILURE(
7039 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7040
7041 // If a touch is reported within the timeout, it reports the updated pressure.
7042 processMove(mapper, 101, 201);
7043 processSync(mapper);
7044 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7045 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7046 WithPressure(0.6f))));
7047 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7048
7049 // There is another pressure change.
7050 mStylusState.pressure = 0.5f;
7051 processExternalStylusState(mapper);
7052 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7053 ASSERT_NO_FATAL_FAILURE(
7054 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7055
7056 // If a touch is not reported within the timeout, a move event is generated to report
7057 // the new pressure.
7058 handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
7059 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7060 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7061 WithPressure(0.5f))));
7062
7063 // If a zero pressure is reported before the touch goes up, the previous pressure value is
7064 // repeated indefinitely.
7065 mStylusState.pressure = 0.0f;
7066 processExternalStylusState(mapper);
7067 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7068 ASSERT_NO_FATAL_FAILURE(
7069 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7070 processMove(mapper, 102, 202);
7071 processSync(mapper);
7072 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7073 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7074 WithPressure(0.5f))));
7075 processMove(mapper, 103, 203);
7076 processSync(mapper);
7077 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7078 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7079 WithPressure(0.5f))));
7080
7081 processUp(mapper);
7082 processSync(mapper);
7083 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7084 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(EXPECTED_SOURCE),
7085 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
7086
7087 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7088 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7089}
7090
7091TEST_F(ExternalStylusFusionTest, FusedPointerReportsToolTypeChanges) {
7092 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7093 auto source = WithSource(EXPECTED_SOURCE);
7094
7095 mStylusState.pressure = 1.f;
7096 mStylusState.toolType = AMOTION_EVENT_TOOL_TYPE_ERASER;
7097 processExternalStylusState(mapper);
7098 processDown(mapper, 100, 200);
7099 processSync(mapper);
7100 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7101 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
7102 WithToolType(AMOTION_EVENT_TOOL_TYPE_ERASER))));
7103 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7104
7105 // The external stylus reports a tool change. We wait for some time for a touch event.
7106 mStylusState.toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
7107 processExternalStylusState(mapper);
7108 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7109 ASSERT_NO_FATAL_FAILURE(
7110 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7111
7112 // If a touch is reported within the timeout, it reports the updated pressure.
7113 processMove(mapper, 101, 201);
7114 processSync(mapper);
7115 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7116 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7117 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
7118 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7119
7120 // There is another tool type change.
7121 mStylusState.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
7122 processExternalStylusState(mapper);
7123 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7124 ASSERT_NO_FATAL_FAILURE(
7125 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7126
7127 // If a touch is not reported within the timeout, a move event is generated to report
7128 // the new tool type.
7129 handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
7130 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7131 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7132 WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))));
7133
7134 processUp(mapper);
7135 processSync(mapper);
7136 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7137 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_UP),
7138 WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))));
7139
7140 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7141 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7142}
7143
7144TEST_F(ExternalStylusFusionTest, FusedPointerReportsButtons) {
7145 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7146 auto toolTypeSource =
7147 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS));
7148
7149 ASSERT_NO_FATAL_FAILURE(testStartFusedStylusGesture(mapper));
7150
7151 // The external stylus reports a button change. We wait for some time for a touch event.
7152 mStylusState.buttons = AMOTION_EVENT_BUTTON_STYLUS_PRIMARY;
7153 processExternalStylusState(mapper);
7154 ASSERT_NO_FATAL_FAILURE(
7155 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7156
7157 // If a touch is reported within the timeout, it reports the updated button state.
7158 processMove(mapper, 101, 201);
7159 processSync(mapper);
7160 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7161 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7162 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
7163 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7164 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
7165 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
7166 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7167
7168 // The button is now released.
7169 mStylusState.buttons = 0;
7170 processExternalStylusState(mapper);
7171 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7172 ASSERT_NO_FATAL_FAILURE(
7173 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7174
7175 // If a touch is not reported within the timeout, a move event is generated to report
7176 // the new button state.
7177 handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007178 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7179 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
7180 WithButtonState(0))));
7181 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan124ea442022-10-28 20:27:44 +00007182 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7183 WithButtonState(0))));
7184
7185 processUp(mapper);
7186 processSync(mapper);
7187 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007188 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
7189
7190 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7191 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7192}
7193
Michael Wrightd02c5b62014-02-10 15:10:22 -08007194// --- MultiTouchInputMapperTest ---
7195
7196class MultiTouchInputMapperTest : public TouchInputMapperTest {
7197protected:
7198 void prepareAxes(int axes);
7199
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007200 void processPosition(MultiTouchInputMapper& mapper, int32_t x, int32_t y);
7201 void processTouchMajor(MultiTouchInputMapper& mapper, int32_t touchMajor);
7202 void processTouchMinor(MultiTouchInputMapper& mapper, int32_t touchMinor);
7203 void processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor);
7204 void processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor);
7205 void processOrientation(MultiTouchInputMapper& mapper, int32_t orientation);
7206 void processPressure(MultiTouchInputMapper& mapper, int32_t pressure);
7207 void processDistance(MultiTouchInputMapper& mapper, int32_t distance);
7208 void processId(MultiTouchInputMapper& mapper, int32_t id);
7209 void processSlot(MultiTouchInputMapper& mapper, int32_t slot);
7210 void processToolType(MultiTouchInputMapper& mapper, int32_t toolType);
7211 void processKey(MultiTouchInputMapper& mapper, int32_t code, int32_t value);
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00007212 void processHidUsage(MultiTouchInputMapper& mapper, int32_t usageCode, int32_t value);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007213 void processMTSync(MultiTouchInputMapper& mapper);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00007214 void processSync(MultiTouchInputMapper& mapper, nsecs_t eventTime = ARBITRARY_TIME,
7215 nsecs_t readTime = READ_TIME);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007216};
7217
7218void MultiTouchInputMapperTest::prepareAxes(int axes) {
7219 if (axes & POSITION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007220 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
7221 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007222 }
7223 if (axes & TOUCH) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007224 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN,
7225 RAW_TOUCH_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007226 if (axes & MINOR) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007227 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN,
7228 RAW_TOUCH_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007229 }
7230 }
7231 if (axes & TOOL) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007232 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
7233 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007234 if (axes & MINOR) {
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08007235 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007236 RAW_TOOL_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007237 }
7238 }
7239 if (axes & ORIENTATION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007240 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_ORIENTATION, RAW_ORIENTATION_MIN,
7241 RAW_ORIENTATION_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007242 }
7243 if (axes & PRESSURE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007244 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_PRESSURE, RAW_PRESSURE_MIN,
7245 RAW_PRESSURE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007246 }
7247 if (axes & DISTANCE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007248 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_DISTANCE, RAW_DISTANCE_MIN,
7249 RAW_DISTANCE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007250 }
7251 if (axes & ID) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007252 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX, 0,
7253 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007254 }
7255 if (axes & SLOT) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007256 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX, 0, 0);
7257 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007258 }
7259 if (axes & TOOL_TYPE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007260 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOOL_TYPE, 0, MT_TOOL_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007261 }
7262}
7263
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007264void MultiTouchInputMapperTest::processPosition(MultiTouchInputMapper& mapper, int32_t x,
7265 int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007266 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_X, x);
7267 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007268}
7269
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007270void MultiTouchInputMapperTest::processTouchMajor(MultiTouchInputMapper& mapper,
7271 int32_t touchMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007272 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, touchMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007273}
7274
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007275void MultiTouchInputMapperTest::processTouchMinor(MultiTouchInputMapper& mapper,
7276 int32_t touchMinor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007277 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, touchMinor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007278}
7279
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007280void MultiTouchInputMapperTest::processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007281 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_WIDTH_MAJOR, toolMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007282}
7283
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007284void MultiTouchInputMapperTest::processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007285 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_WIDTH_MINOR, toolMinor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007286}
7287
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007288void MultiTouchInputMapperTest::processOrientation(MultiTouchInputMapper& mapper,
7289 int32_t orientation) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007290 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_ORIENTATION, orientation);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007291}
7292
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007293void MultiTouchInputMapperTest::processPressure(MultiTouchInputMapper& mapper, int32_t pressure) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007294 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_PRESSURE, pressure);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007295}
7296
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007297void MultiTouchInputMapperTest::processDistance(MultiTouchInputMapper& mapper, int32_t distance) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007298 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_DISTANCE, distance);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007299}
7300
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007301void MultiTouchInputMapperTest::processId(MultiTouchInputMapper& mapper, int32_t id) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007302 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TRACKING_ID, id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007303}
7304
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007305void MultiTouchInputMapperTest::processSlot(MultiTouchInputMapper& mapper, int32_t slot) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007306 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_SLOT, slot);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007307}
7308
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007309void MultiTouchInputMapperTest::processToolType(MultiTouchInputMapper& mapper, int32_t toolType) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007310 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOOL_TYPE, toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007311}
7312
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007313void MultiTouchInputMapperTest::processKey(MultiTouchInputMapper& mapper, int32_t code,
7314 int32_t value) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007315 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007316}
7317
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00007318void MultiTouchInputMapperTest::processHidUsage(MultiTouchInputMapper& mapper, int32_t usageCode,
7319 int32_t value) {
7320 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, usageCode);
7321 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UNKNOWN, value);
7322}
7323
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007324void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007325 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_MT_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007326}
7327
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00007328void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper& mapper, nsecs_t eventTime,
7329 nsecs_t readTime) {
7330 process(mapper, eventTime, readTime, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007331}
7332
Michael Wrightd02c5b62014-02-10 15:10:22 -08007333TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007334 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007335 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007336 prepareAxes(POSITION);
7337 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007338 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007339
arthurhungdcef2dc2020-08-11 14:47:50 +08007340 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007341
7342 NotifyMotionArgs motionArgs;
7343
7344 // Two fingers down at once.
7345 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
7346 processPosition(mapper, x1, y1);
7347 processMTSync(mapper);
7348 processPosition(mapper, x2, y2);
7349 processMTSync(mapper);
7350 processSync(mapper);
7351
7352 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7353 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7354 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7355 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7356 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7357 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7358 ASSERT_EQ(0, motionArgs.flags);
7359 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7360 ASSERT_EQ(0, motionArgs.buttonState);
7361 ASSERT_EQ(0, motionArgs.edgeFlags);
7362 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7363 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7364 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7365 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7366 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7367 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7368 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7369 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7370
7371 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7372 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7373 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7374 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7375 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007376 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007377 ASSERT_EQ(0, motionArgs.flags);
7378 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7379 ASSERT_EQ(0, motionArgs.buttonState);
7380 ASSERT_EQ(0, motionArgs.edgeFlags);
7381 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7382 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7383 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7384 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7385 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7386 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7387 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7388 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7389 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7390 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7391 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7392 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7393
7394 // Move.
7395 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
7396 processPosition(mapper, x1, y1);
7397 processMTSync(mapper);
7398 processPosition(mapper, x2, y2);
7399 processMTSync(mapper);
7400 processSync(mapper);
7401
7402 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7403 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7404 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7405 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7406 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7407 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7408 ASSERT_EQ(0, motionArgs.flags);
7409 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7410 ASSERT_EQ(0, motionArgs.buttonState);
7411 ASSERT_EQ(0, motionArgs.edgeFlags);
7412 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7413 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7414 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7415 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7416 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7417 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7418 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7419 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7420 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7421 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7422 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7423 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7424
7425 // First finger up.
7426 x2 += 15; y2 -= 20;
7427 processPosition(mapper, x2, y2);
7428 processMTSync(mapper);
7429 processSync(mapper);
7430
7431 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7432 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7433 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7434 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7435 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007436 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007437 ASSERT_EQ(0, motionArgs.flags);
7438 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7439 ASSERT_EQ(0, motionArgs.buttonState);
7440 ASSERT_EQ(0, motionArgs.edgeFlags);
7441 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7442 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7443 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7444 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7445 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7446 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7447 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7448 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7449 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7450 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7451 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7452 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7453
7454 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7455 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7456 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7457 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7458 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7459 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7460 ASSERT_EQ(0, motionArgs.flags);
7461 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7462 ASSERT_EQ(0, motionArgs.buttonState);
7463 ASSERT_EQ(0, motionArgs.edgeFlags);
7464 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7465 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7466 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7467 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7468 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7469 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7470 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7471 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7472
7473 // Move.
7474 x2 += 20; y2 -= 25;
7475 processPosition(mapper, x2, y2);
7476 processMTSync(mapper);
7477 processSync(mapper);
7478
7479 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7480 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7481 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7482 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7483 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7484 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7485 ASSERT_EQ(0, motionArgs.flags);
7486 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7487 ASSERT_EQ(0, motionArgs.buttonState);
7488 ASSERT_EQ(0, motionArgs.edgeFlags);
7489 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7490 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7491 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7492 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7493 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7494 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7495 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7496 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7497
7498 // New finger down.
7499 int32_t x3 = 700, y3 = 300;
7500 processPosition(mapper, x2, y2);
7501 processMTSync(mapper);
7502 processPosition(mapper, x3, y3);
7503 processMTSync(mapper);
7504 processSync(mapper);
7505
7506 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7507 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7508 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7509 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7510 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007511 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007512 ASSERT_EQ(0, motionArgs.flags);
7513 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7514 ASSERT_EQ(0, motionArgs.buttonState);
7515 ASSERT_EQ(0, motionArgs.edgeFlags);
7516 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7517 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7518 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7519 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7520 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7521 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7522 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7523 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7524 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7525 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7526 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7527 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7528
7529 // Second finger up.
7530 x3 += 30; y3 -= 20;
7531 processPosition(mapper, x3, y3);
7532 processMTSync(mapper);
7533 processSync(mapper);
7534
7535 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7536 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7537 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7538 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7539 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007540 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007541 ASSERT_EQ(0, motionArgs.flags);
7542 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7543 ASSERT_EQ(0, motionArgs.buttonState);
7544 ASSERT_EQ(0, motionArgs.edgeFlags);
7545 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7546 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7547 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7548 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7549 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7550 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7551 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7552 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7553 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7554 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7555 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7556 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7557
7558 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7559 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7560 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7561 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7562 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7563 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7564 ASSERT_EQ(0, motionArgs.flags);
7565 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7566 ASSERT_EQ(0, motionArgs.buttonState);
7567 ASSERT_EQ(0, motionArgs.edgeFlags);
7568 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7569 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7570 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7571 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7572 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7573 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7574 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7575 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7576
7577 // Last finger up.
7578 processMTSync(mapper);
7579 processSync(mapper);
7580
7581 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7582 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7583 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7584 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7585 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7586 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7587 ASSERT_EQ(0, motionArgs.flags);
7588 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7589 ASSERT_EQ(0, motionArgs.buttonState);
7590 ASSERT_EQ(0, motionArgs.edgeFlags);
7591 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7592 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7593 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7594 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7595 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7596 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7597 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7598 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7599
7600 // Should not have sent any more keys or motions.
7601 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7602 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7603}
7604
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08007605TEST_F(MultiTouchInputMapperTest, AxisResolution_IsPopulated) {
7606 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007607 prepareDisplay(ui::ROTATION_0);
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08007608
7609 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
7610 /*fuzz*/ 0, /*resolution*/ 10);
7611 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
7612 /*fuzz*/ 0, /*resolution*/ 11);
7613 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
7614 /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 12);
7615 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
7616 /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 13);
7617 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
7618 /*flat*/ 0, /*flat*/ 0, /*resolution*/ 14);
7619 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
7620 /*flat*/ 0, /*flat*/ 0, /*resolution*/ 15);
7621
7622 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
7623
7624 // X and Y axes
7625 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_X, 10 / X_PRECISION);
7626 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_Y, 11 / Y_PRECISION);
7627 // Touch major and minor
7628 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR, 12 * GEOMETRIC_SCALE);
7629 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR, 13 * GEOMETRIC_SCALE);
7630 // Tool major and minor
7631 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR, 14 * GEOMETRIC_SCALE);
7632 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR, 15 * GEOMETRIC_SCALE);
7633}
7634
7635TEST_F(MultiTouchInputMapperTest, TouchMajorAndMinorAxes_DoNotAppearIfNotSupported) {
7636 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007637 prepareDisplay(ui::ROTATION_0);
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08007638
7639 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
7640 /*fuzz*/ 0, /*resolution*/ 10);
7641 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
7642 /*fuzz*/ 0, /*resolution*/ 11);
7643
7644 // We do not add ABS_MT_TOUCH_MAJOR / MINOR or ABS_MT_WIDTH_MAJOR / MINOR axes
7645
7646 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
7647
7648 // Touch major and minor
7649 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR);
7650 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR);
7651 // Tool major and minor
7652 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR);
7653 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR);
7654}
7655
Michael Wrightd02c5b62014-02-10 15:10:22 -08007656TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007657 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007658 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007659 prepareAxes(POSITION | ID);
7660 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007661 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007662
arthurhungdcef2dc2020-08-11 14:47:50 +08007663 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007664
7665 NotifyMotionArgs motionArgs;
7666
7667 // Two fingers down at once.
7668 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
7669 processPosition(mapper, x1, y1);
7670 processId(mapper, 1);
7671 processMTSync(mapper);
7672 processPosition(mapper, x2, y2);
7673 processId(mapper, 2);
7674 processMTSync(mapper);
7675 processSync(mapper);
7676
7677 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7678 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7679 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7680 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7681 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7682 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7683 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7684
7685 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007686 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007687 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7688 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7689 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7690 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7691 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7692 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7693 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7694 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7695 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7696
7697 // Move.
7698 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
7699 processPosition(mapper, x1, y1);
7700 processId(mapper, 1);
7701 processMTSync(mapper);
7702 processPosition(mapper, x2, y2);
7703 processId(mapper, 2);
7704 processMTSync(mapper);
7705 processSync(mapper);
7706
7707 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7708 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7709 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7710 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7711 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7712 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7713 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7714 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7715 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7716 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7717 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7718
7719 // First finger up.
7720 x2 += 15; y2 -= 20;
7721 processPosition(mapper, x2, y2);
7722 processId(mapper, 2);
7723 processMTSync(mapper);
7724 processSync(mapper);
7725
7726 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007727 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007728 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7729 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7730 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7731 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7732 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7733 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7734 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7735 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7736 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7737
7738 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7739 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7740 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7741 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7742 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7743 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7744 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7745
7746 // Move.
7747 x2 += 20; y2 -= 25;
7748 processPosition(mapper, x2, y2);
7749 processId(mapper, 2);
7750 processMTSync(mapper);
7751 processSync(mapper);
7752
7753 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7754 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7755 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7756 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7757 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7758 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7759 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7760
7761 // New finger down.
7762 int32_t x3 = 700, y3 = 300;
7763 processPosition(mapper, x2, y2);
7764 processId(mapper, 2);
7765 processMTSync(mapper);
7766 processPosition(mapper, x3, y3);
7767 processId(mapper, 3);
7768 processMTSync(mapper);
7769 processSync(mapper);
7770
7771 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007772 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007773 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7774 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7775 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7776 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7777 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7778 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7779 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7780 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7781 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7782
7783 // Second finger up.
7784 x3 += 30; y3 -= 20;
7785 processPosition(mapper, x3, y3);
7786 processId(mapper, 3);
7787 processMTSync(mapper);
7788 processSync(mapper);
7789
7790 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007791 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007792 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7793 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7794 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7795 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7796 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7797 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7798 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7799 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7800 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7801
7802 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7803 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7804 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7805 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7806 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7807 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7808 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7809
7810 // Last finger up.
7811 processMTSync(mapper);
7812 processSync(mapper);
7813
7814 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7815 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7816 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7817 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7818 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7819 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7820 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7821
7822 // Should not have sent any more keys or motions.
7823 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7824 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7825}
7826
7827TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithSlots) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007828 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007829 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007830 prepareAxes(POSITION | ID | SLOT);
7831 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007832 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007833
arthurhungdcef2dc2020-08-11 14:47:50 +08007834 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007835
7836 NotifyMotionArgs motionArgs;
7837
7838 // Two fingers down at once.
7839 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
7840 processPosition(mapper, x1, y1);
7841 processId(mapper, 1);
7842 processSlot(mapper, 1);
7843 processPosition(mapper, x2, y2);
7844 processId(mapper, 2);
7845 processSync(mapper);
7846
7847 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7848 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7849 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7850 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7851 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7852 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7853 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7854
7855 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007856 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007857 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7858 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7859 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7860 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7861 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7862 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7863 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7864 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7865 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7866
7867 // Move.
7868 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
7869 processSlot(mapper, 0);
7870 processPosition(mapper, x1, y1);
7871 processSlot(mapper, 1);
7872 processPosition(mapper, x2, y2);
7873 processSync(mapper);
7874
7875 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7876 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7877 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7878 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7879 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7880 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7881 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7882 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7883 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7884 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7885 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7886
7887 // First finger up.
7888 x2 += 15; y2 -= 20;
7889 processSlot(mapper, 0);
7890 processId(mapper, -1);
7891 processSlot(mapper, 1);
7892 processPosition(mapper, x2, y2);
7893 processSync(mapper);
7894
7895 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007896 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007897 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7898 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7899 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7900 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7901 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7902 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7903 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7904 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7905 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7906
7907 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7908 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7909 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7910 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7911 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7912 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7913 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7914
7915 // Move.
7916 x2 += 20; y2 -= 25;
7917 processPosition(mapper, x2, y2);
7918 processSync(mapper);
7919
7920 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7921 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7922 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7923 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7924 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7925 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7926 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7927
7928 // New finger down.
7929 int32_t x3 = 700, y3 = 300;
7930 processPosition(mapper, x2, y2);
7931 processSlot(mapper, 0);
7932 processId(mapper, 3);
7933 processPosition(mapper, x3, y3);
7934 processSync(mapper);
7935
7936 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007937 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007938 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7939 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7940 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7941 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7942 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7943 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7944 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7945 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7946 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7947
7948 // Second finger up.
7949 x3 += 30; y3 -= 20;
7950 processSlot(mapper, 1);
7951 processId(mapper, -1);
7952 processSlot(mapper, 0);
7953 processPosition(mapper, x3, y3);
7954 processSync(mapper);
7955
7956 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007957 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007958 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7959 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7960 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7961 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7962 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7963 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7964 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7965 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7966 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7967
7968 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7969 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7970 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7971 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7972 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7973 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7974 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7975
7976 // Last finger up.
7977 processId(mapper, -1);
7978 processSync(mapper);
7979
7980 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7981 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7982 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7983 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7984 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7985 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7986 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7987
7988 // Should not have sent any more keys or motions.
7989 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7990 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7991}
7992
7993TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007994 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00007995 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007996 prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR | DISTANCE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007997 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007998
7999 // These calculations are based on the input device calibration documentation.
8000 int32_t rawX = 100;
8001 int32_t rawY = 200;
8002 int32_t rawTouchMajor = 7;
8003 int32_t rawTouchMinor = 6;
8004 int32_t rawToolMajor = 9;
8005 int32_t rawToolMinor = 8;
8006 int32_t rawPressure = 11;
8007 int32_t rawDistance = 0;
8008 int32_t rawOrientation = 3;
8009 int32_t id = 5;
8010
8011 float x = toDisplayX(rawX);
8012 float y = toDisplayY(rawY);
8013 float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
8014 float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
8015 float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
8016 float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
8017 float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
8018 float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
8019 float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2;
8020 float distance = float(rawDistance);
8021
8022 processPosition(mapper, rawX, rawY);
8023 processTouchMajor(mapper, rawTouchMajor);
8024 processTouchMinor(mapper, rawTouchMinor);
8025 processToolMajor(mapper, rawToolMajor);
8026 processToolMinor(mapper, rawToolMinor);
8027 processPressure(mapper, rawPressure);
8028 processOrientation(mapper, rawOrientation);
8029 processDistance(mapper, rawDistance);
8030 processId(mapper, id);
8031 processMTSync(mapper);
8032 processSync(mapper);
8033
8034 NotifyMotionArgs args;
8035 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8036 ASSERT_EQ(0, args.pointerProperties[0].id);
8037 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8038 x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor,
8039 orientation, distance));
8040}
8041
8042TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008043 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008044 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008045 prepareAxes(POSITION | TOUCH | TOOL | MINOR);
8046 addConfigurationProperty("touch.size.calibration", "geometric");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008047 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008048
8049 // These calculations are based on the input device calibration documentation.
8050 int32_t rawX = 100;
8051 int32_t rawY = 200;
8052 int32_t rawTouchMajor = 140;
8053 int32_t rawTouchMinor = 120;
8054 int32_t rawToolMajor = 180;
8055 int32_t rawToolMinor = 160;
8056
8057 float x = toDisplayX(rawX);
8058 float y = toDisplayY(rawY);
8059 float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
8060 float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
8061 float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
8062 float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
8063 float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
8064
8065 processPosition(mapper, rawX, rawY);
8066 processTouchMajor(mapper, rawTouchMajor);
8067 processTouchMinor(mapper, rawTouchMinor);
8068 processToolMajor(mapper, rawToolMajor);
8069 processToolMinor(mapper, rawToolMinor);
8070 processMTSync(mapper);
8071 processSync(mapper);
8072
8073 NotifyMotionArgs args;
8074 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8075 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8076 x, y, 1.0f, size, touchMajor, touchMinor, toolMajor, toolMinor, 0, 0));
8077}
8078
8079TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_SummedLinearCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008080 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008081 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008082 prepareAxes(POSITION | TOUCH | TOOL);
8083 addConfigurationProperty("touch.size.calibration", "diameter");
8084 addConfigurationProperty("touch.size.scale", "10");
8085 addConfigurationProperty("touch.size.bias", "160");
8086 addConfigurationProperty("touch.size.isSummed", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008087 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008088
8089 // These calculations are based on the input device calibration documentation.
8090 // Note: We only provide a single common touch/tool value because the device is assumed
8091 // not to emit separate values for each pointer (isSummed = 1).
8092 int32_t rawX = 100;
8093 int32_t rawY = 200;
8094 int32_t rawX2 = 150;
8095 int32_t rawY2 = 250;
8096 int32_t rawTouchMajor = 5;
8097 int32_t rawToolMajor = 8;
8098
8099 float x = toDisplayX(rawX);
8100 float y = toDisplayY(rawY);
8101 float x2 = toDisplayX(rawX2);
8102 float y2 = toDisplayY(rawY2);
8103 float size = float(rawTouchMajor) / 2 / RAW_TOUCH_MAX;
8104 float touch = float(rawTouchMajor) / 2 * 10.0f + 160.0f;
8105 float tool = float(rawToolMajor) / 2 * 10.0f + 160.0f;
8106
8107 processPosition(mapper, rawX, rawY);
8108 processTouchMajor(mapper, rawTouchMajor);
8109 processToolMajor(mapper, rawToolMajor);
8110 processMTSync(mapper);
8111 processPosition(mapper, rawX2, rawY2);
8112 processTouchMajor(mapper, rawTouchMajor);
8113 processToolMajor(mapper, rawToolMajor);
8114 processMTSync(mapper);
8115 processSync(mapper);
8116
8117 NotifyMotionArgs args;
8118 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8119 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
8120
8121 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008122 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008123 ASSERT_EQ(size_t(2), args.pointerCount);
8124 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8125 x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
8126 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1],
8127 x2, y2, 1.0f, size, touch, touch, tool, tool, 0, 0));
8128}
8129
8130TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_AreaCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008131 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008132 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008133 prepareAxes(POSITION | TOUCH | TOOL);
8134 addConfigurationProperty("touch.size.calibration", "area");
8135 addConfigurationProperty("touch.size.scale", "43");
8136 addConfigurationProperty("touch.size.bias", "3");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008137 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008138
8139 // These calculations are based on the input device calibration documentation.
8140 int32_t rawX = 100;
8141 int32_t rawY = 200;
8142 int32_t rawTouchMajor = 5;
8143 int32_t rawToolMajor = 8;
8144
8145 float x = toDisplayX(rawX);
8146 float y = toDisplayY(rawY);
8147 float size = float(rawTouchMajor) / RAW_TOUCH_MAX;
8148 float touch = sqrtf(rawTouchMajor) * 43.0f + 3.0f;
8149 float tool = sqrtf(rawToolMajor) * 43.0f + 3.0f;
8150
8151 processPosition(mapper, rawX, rawY);
8152 processTouchMajor(mapper, rawTouchMajor);
8153 processToolMajor(mapper, rawToolMajor);
8154 processMTSync(mapper);
8155 processSync(mapper);
8156
8157 NotifyMotionArgs args;
8158 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8159 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8160 x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
8161}
8162
8163TEST_F(MultiTouchInputMapperTest, Process_PressureAxis_AmplitudeCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008164 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008165 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008166 prepareAxes(POSITION | PRESSURE);
8167 addConfigurationProperty("touch.pressure.calibration", "amplitude");
8168 addConfigurationProperty("touch.pressure.scale", "0.01");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008169 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008170
Michael Wrightaa449c92017-12-13 21:21:43 +00008171 InputDeviceInfo info;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008172 mapper.populateDeviceInfo(&info);
Michael Wrightaa449c92017-12-13 21:21:43 +00008173 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
8174 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TOUCHSCREEN,
8175 0.0f, RAW_PRESSURE_MAX * 0.01, 0.0f, 0.0f));
8176
Michael Wrightd02c5b62014-02-10 15:10:22 -08008177 // These calculations are based on the input device calibration documentation.
8178 int32_t rawX = 100;
8179 int32_t rawY = 200;
8180 int32_t rawPressure = 60;
8181
8182 float x = toDisplayX(rawX);
8183 float y = toDisplayY(rawY);
8184 float pressure = float(rawPressure) * 0.01f;
8185
8186 processPosition(mapper, rawX, rawY);
8187 processPressure(mapper, rawPressure);
8188 processMTSync(mapper);
8189 processSync(mapper);
8190
8191 NotifyMotionArgs args;
8192 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8193 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8194 x, y, pressure, 0, 0, 0, 0, 0, 0, 0));
8195}
8196
8197TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008198 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008199 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008200 prepareAxes(POSITION | ID | SLOT);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008201 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008202
8203 NotifyMotionArgs motionArgs;
8204 NotifyKeyArgs keyArgs;
8205
8206 processId(mapper, 1);
8207 processPosition(mapper, 100, 200);
8208 processSync(mapper);
8209 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8210 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8211 ASSERT_EQ(0, motionArgs.buttonState);
8212
8213 // press BTN_LEFT, release BTN_LEFT
8214 processKey(mapper, BTN_LEFT, 1);
8215 processSync(mapper);
8216 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8217 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8218 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
8219
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008220 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8221 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8222 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
8223
Michael Wrightd02c5b62014-02-10 15:10:22 -08008224 processKey(mapper, BTN_LEFT, 0);
8225 processSync(mapper);
8226 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008227 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008228 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008229
8230 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008231 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008232 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008233
8234 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
8235 processKey(mapper, BTN_RIGHT, 1);
8236 processKey(mapper, BTN_MIDDLE, 1);
8237 processSync(mapper);
8238 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8239 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8240 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
8241 motionArgs.buttonState);
8242
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008243 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8244 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8245 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
8246
8247 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8248 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8249 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
8250 motionArgs.buttonState);
8251
Michael Wrightd02c5b62014-02-10 15:10:22 -08008252 processKey(mapper, BTN_RIGHT, 0);
8253 processSync(mapper);
8254 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008255 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008256 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008257
8258 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008259 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008260 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008261
8262 processKey(mapper, BTN_MIDDLE, 0);
8263 processSync(mapper);
8264 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008265 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008266 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008267
8268 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008269 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008270 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008271
8272 // press BTN_BACK, release BTN_BACK
8273 processKey(mapper, BTN_BACK, 1);
8274 processSync(mapper);
8275 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8276 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
8277 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008278
Michael Wrightd02c5b62014-02-10 15:10:22 -08008279 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008280 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008281 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
8282
8283 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8284 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8285 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008286
8287 processKey(mapper, BTN_BACK, 0);
8288 processSync(mapper);
8289 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008290 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008291 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008292
8293 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008294 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008295 ASSERT_EQ(0, motionArgs.buttonState);
8296
Michael Wrightd02c5b62014-02-10 15:10:22 -08008297 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8298 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
8299 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
8300
8301 // press BTN_SIDE, release BTN_SIDE
8302 processKey(mapper, BTN_SIDE, 1);
8303 processSync(mapper);
8304 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8305 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
8306 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008307
Michael Wrightd02c5b62014-02-10 15:10:22 -08008308 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008309 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008310 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
8311
8312 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8313 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8314 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008315
8316 processKey(mapper, BTN_SIDE, 0);
8317 processSync(mapper);
8318 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008319 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008320 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008321
8322 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008323 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008324 ASSERT_EQ(0, motionArgs.buttonState);
8325
Michael Wrightd02c5b62014-02-10 15:10:22 -08008326 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8327 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
8328 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
8329
8330 // press BTN_FORWARD, release BTN_FORWARD
8331 processKey(mapper, BTN_FORWARD, 1);
8332 processSync(mapper);
8333 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8334 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
8335 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008336
Michael Wrightd02c5b62014-02-10 15:10:22 -08008337 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008338 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008339 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
8340
8341 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8342 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8343 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008344
8345 processKey(mapper, BTN_FORWARD, 0);
8346 processSync(mapper);
8347 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008348 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008349 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008350
8351 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008352 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008353 ASSERT_EQ(0, motionArgs.buttonState);
8354
Michael Wrightd02c5b62014-02-10 15:10:22 -08008355 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8356 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
8357 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
8358
8359 // press BTN_EXTRA, release BTN_EXTRA
8360 processKey(mapper, BTN_EXTRA, 1);
8361 processSync(mapper);
8362 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8363 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
8364 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008365
Michael Wrightd02c5b62014-02-10 15:10:22 -08008366 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008367 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008368 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
8369
8370 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8371 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8372 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008373
8374 processKey(mapper, BTN_EXTRA, 0);
8375 processSync(mapper);
8376 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008377 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008378 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008379
8380 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008381 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008382 ASSERT_EQ(0, motionArgs.buttonState);
8383
Michael Wrightd02c5b62014-02-10 15:10:22 -08008384 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8385 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
8386 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
8387
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008388 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
8389
Michael Wrightd02c5b62014-02-10 15:10:22 -08008390 // press BTN_STYLUS, release BTN_STYLUS
8391 processKey(mapper, BTN_STYLUS, 1);
8392 processSync(mapper);
8393 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8394 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008395 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
8396
8397 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8398 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8399 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008400
8401 processKey(mapper, BTN_STYLUS, 0);
8402 processSync(mapper);
8403 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008404 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008405 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008406
8407 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008408 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008409 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008410
8411 // press BTN_STYLUS2, release BTN_STYLUS2
8412 processKey(mapper, BTN_STYLUS2, 1);
8413 processSync(mapper);
8414 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8415 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008416 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
8417
8418 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8419 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8420 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008421
8422 processKey(mapper, BTN_STYLUS2, 0);
8423 processSync(mapper);
8424 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008425 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008426 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008427
8428 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008429 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008430 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008431
8432 // release touch
8433 processId(mapper, -1);
8434 processSync(mapper);
8435 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8436 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8437 ASSERT_EQ(0, motionArgs.buttonState);
8438}
8439
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00008440TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleMappedStylusButtons) {
8441 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008442 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00008443 prepareAxes(POSITION | ID | SLOT);
8444 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8445
8446 mFakeEventHub->addKey(EVENTHUB_ID, BTN_A, 0, AKEYCODE_STYLUS_BUTTON_PRIMARY, 0);
8447 mFakeEventHub->addKey(EVENTHUB_ID, 0, 0xabcd, AKEYCODE_STYLUS_BUTTON_SECONDARY, 0);
8448
8449 // Touch down.
8450 processId(mapper, 1);
8451 processPosition(mapper, 100, 200);
8452 processSync(mapper);
8453 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8454 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithButtonState(0))));
8455
8456 // Press and release button mapped to the primary stylus button.
8457 processKey(mapper, BTN_A, 1);
8458 processSync(mapper);
8459 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8460 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
8461 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
8462 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8463 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
8464 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
8465
8466 processKey(mapper, BTN_A, 0);
8467 processSync(mapper);
8468 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8469 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithButtonState(0))));
8470 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8471 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
8472
8473 // Press and release the HID usage mapped to the secondary stylus button.
8474 processHidUsage(mapper, 0xabcd, 1);
8475 processSync(mapper);
8476 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8477 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
8478 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY))));
8479 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8480 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
8481 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY))));
8482
8483 processHidUsage(mapper, 0xabcd, 0);
8484 processSync(mapper);
8485 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8486 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithButtonState(0))));
8487 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8488 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
8489
8490 // Release touch.
8491 processId(mapper, -1);
8492 processSync(mapper);
8493 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8494 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
8495}
8496
Michael Wrightd02c5b62014-02-10 15:10:22 -08008497TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008498 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008499 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008500 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008501 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008502
8503 NotifyMotionArgs motionArgs;
8504
8505 // default tool type is finger
8506 processId(mapper, 1);
8507 processPosition(mapper, 100, 200);
8508 processSync(mapper);
8509 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8510 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8511 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8512
8513 // eraser
8514 processKey(mapper, BTN_TOOL_RUBBER, 1);
8515 processSync(mapper);
8516 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8517 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8518 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
8519
8520 // stylus
8521 processKey(mapper, BTN_TOOL_RUBBER, 0);
8522 processKey(mapper, BTN_TOOL_PEN, 1);
8523 processSync(mapper);
8524 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8525 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8526 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8527
8528 // brush
8529 processKey(mapper, BTN_TOOL_PEN, 0);
8530 processKey(mapper, BTN_TOOL_BRUSH, 1);
8531 processSync(mapper);
8532 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8533 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8534 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8535
8536 // pencil
8537 processKey(mapper, BTN_TOOL_BRUSH, 0);
8538 processKey(mapper, BTN_TOOL_PENCIL, 1);
8539 processSync(mapper);
8540 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8541 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8542 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8543
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08008544 // air-brush
Michael Wrightd02c5b62014-02-10 15:10:22 -08008545 processKey(mapper, BTN_TOOL_PENCIL, 0);
8546 processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
8547 processSync(mapper);
8548 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8549 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8550 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8551
8552 // mouse
8553 processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
8554 processKey(mapper, BTN_TOOL_MOUSE, 1);
8555 processSync(mapper);
8556 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8557 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8558 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
8559
8560 // lens
8561 processKey(mapper, BTN_TOOL_MOUSE, 0);
8562 processKey(mapper, BTN_TOOL_LENS, 1);
8563 processSync(mapper);
8564 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8565 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8566 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
8567
8568 // double-tap
8569 processKey(mapper, BTN_TOOL_LENS, 0);
8570 processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
8571 processSync(mapper);
8572 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8573 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8574 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8575
8576 // triple-tap
8577 processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
8578 processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
8579 processSync(mapper);
8580 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8581 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8582 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8583
8584 // quad-tap
8585 processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
8586 processKey(mapper, BTN_TOOL_QUADTAP, 1);
8587 processSync(mapper);
8588 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8589 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8590 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8591
8592 // finger
8593 processKey(mapper, BTN_TOOL_QUADTAP, 0);
8594 processKey(mapper, BTN_TOOL_FINGER, 1);
8595 processSync(mapper);
8596 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8597 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8598 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8599
8600 // stylus trumps finger
8601 processKey(mapper, BTN_TOOL_PEN, 1);
8602 processSync(mapper);
8603 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8604 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8605 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8606
8607 // eraser trumps stylus
8608 processKey(mapper, BTN_TOOL_RUBBER, 1);
8609 processSync(mapper);
8610 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8611 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8612 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
8613
8614 // mouse trumps eraser
8615 processKey(mapper, BTN_TOOL_MOUSE, 1);
8616 processSync(mapper);
8617 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8618 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8619 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
8620
8621 // MT tool type trumps BTN tool types: MT_TOOL_FINGER
8622 processToolType(mapper, MT_TOOL_FINGER); // this is the first time we send MT_TOOL_TYPE
8623 processSync(mapper);
8624 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8625 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8626 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8627
8628 // MT tool type trumps BTN tool types: MT_TOOL_PEN
8629 processToolType(mapper, MT_TOOL_PEN);
8630 processSync(mapper);
8631 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8632 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8633 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8634
8635 // back to default tool type
8636 processToolType(mapper, -1); // use a deliberately undefined tool type, for testing
8637 processKey(mapper, BTN_TOOL_MOUSE, 0);
8638 processKey(mapper, BTN_TOOL_RUBBER, 0);
8639 processKey(mapper, BTN_TOOL_PEN, 0);
8640 processKey(mapper, BTN_TOOL_FINGER, 0);
8641 processSync(mapper);
8642 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8643 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8644 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8645}
8646
8647TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008648 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008649 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008650 prepareAxes(POSITION | ID | SLOT);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008651 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008652 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008653
8654 NotifyMotionArgs motionArgs;
8655
8656 // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
8657 processId(mapper, 1);
8658 processPosition(mapper, 100, 200);
8659 processSync(mapper);
8660 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8661 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8662 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8663 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8664
8665 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8666 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8667 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8668 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8669
8670 // move a little
8671 processPosition(mapper, 150, 250);
8672 processSync(mapper);
8673 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8674 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8675 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8676 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8677
8678 // down when BTN_TOUCH is pressed, pressure defaults to 1
8679 processKey(mapper, BTN_TOUCH, 1);
8680 processSync(mapper);
8681 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8682 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8683 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8684 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8685
8686 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8687 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8688 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8689 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
8690
8691 // up when BTN_TOUCH is released, hover restored
8692 processKey(mapper, BTN_TOUCH, 0);
8693 processSync(mapper);
8694 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8695 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8696 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8697 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
8698
8699 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8700 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8701 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8702 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8703
8704 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8705 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8706 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8707 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8708
8709 // exit hover when pointer goes away
8710 processId(mapper, -1);
8711 processSync(mapper);
8712 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8713 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8714 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8715 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8716}
8717
8718TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTPressureIsPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008719 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008720 prepareDisplay(ui::ROTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008721 prepareAxes(POSITION | ID | SLOT | PRESSURE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008722 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008723
8724 NotifyMotionArgs motionArgs;
8725
8726 // initially hovering because pressure is 0
8727 processId(mapper, 1);
8728 processPosition(mapper, 100, 200);
8729 processPressure(mapper, 0);
8730 processSync(mapper);
8731 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8732 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8733 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8734 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8735
8736 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8737 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8738 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8739 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8740
8741 // move a little
8742 processPosition(mapper, 150, 250);
8743 processSync(mapper);
8744 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8745 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8746 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8747 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8748
8749 // down when pressure becomes non-zero
8750 processPressure(mapper, RAW_PRESSURE_MAX);
8751 processSync(mapper);
8752 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8753 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8754 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8755 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8756
8757 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8758 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8759 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8760 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
8761
8762 // up when pressure becomes 0, hover restored
8763 processPressure(mapper, 0);
8764 processSync(mapper);
8765 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8766 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8767 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8768 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
8769
8770 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8771 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8772 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8773 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8774
8775 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8776 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8777 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8778 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8779
8780 // exit hover when pointer goes away
8781 processId(mapper, -1);
8782 processSync(mapper);
8783 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8784 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8785 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8786 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8787}
8788
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008789/**
8790 * Set the input device port <--> display port associations, and check that the
8791 * events are routed to the display that matches the display port.
8792 * This can be checked by looking at the displayId of the resulting NotifyMotionArgs.
8793 */
8794TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayPort) {
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008795 const std::string usb2 = "USB2";
8796 const uint8_t hdmi1 = 0;
8797 const uint8_t hdmi2 = 1;
8798 const std::string secondaryUniqueId = "uniqueId2";
Michael Wrightfe3de7d2020-07-02 19:05:30 +01008799 constexpr ViewportType type = ViewportType::EXTERNAL;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008800
8801 addConfigurationProperty("touch.deviceType", "touchScreen");
8802 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008803 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008804
8805 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
8806 mFakePolicy->addInputPortAssociation(usb2, hdmi2);
8807
8808 // We are intentionally not adding the viewport for display 1 yet. Since the port association
8809 // for this input device is specified, and the matching viewport is not present,
8810 // the input device should be disabled (at the mapper level).
8811
8812 // Add viewport for display 2 on hdmi2
8813 prepareSecondaryDisplay(type, hdmi2);
8814 // Send a touch event
8815 processPosition(mapper, 100, 100);
8816 processSync(mapper);
8817 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8818
8819 // Add viewport for display 1 on hdmi1
Michael Wrighta9cf4192022-12-01 23:46:39 +00008820 prepareDisplay(ui::ROTATION_0, hdmi1);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008821 // Send a touch event again
8822 processPosition(mapper, 100, 100);
8823 processSync(mapper);
8824
8825 NotifyMotionArgs args;
8826 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8827 ASSERT_EQ(DISPLAY_ID, args.displayId);
8828}
Michael Wrightd02c5b62014-02-10 15:10:22 -08008829
Arthur Hung6d5b4b22022-01-21 07:21:10 +00008830TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayUniqueId) {
8831 addConfigurationProperty("touch.deviceType", "touchScreen");
8832 prepareAxes(POSITION);
8833 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8834
8835 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
8836
Michael Wrighta9cf4192022-12-01 23:46:39 +00008837 prepareDisplay(ui::ROTATION_0);
8838 prepareVirtualDisplay(ui::ROTATION_0);
Arthur Hung6d5b4b22022-01-21 07:21:10 +00008839
8840 // Send a touch event
8841 processPosition(mapper, 100, 100);
8842 processSync(mapper);
8843
8844 NotifyMotionArgs args;
8845 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8846 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
8847}
8848
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008849TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
Garfield Tan888a6a42020-01-09 11:39:16 -08008850 // Setup for second display.
Michael Wright17db18e2020-06-26 20:51:44 +01008851 std::shared_ptr<FakePointerController> fakePointerController =
8852 std::make_shared<FakePointerController>();
Garfield Tan888a6a42020-01-09 11:39:16 -08008853 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008854 fakePointerController->setPosition(100, 200);
8855 fakePointerController->setButtonState(0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00008856 mFakePolicy->setPointerController(fakePointerController);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008857
Garfield Tan888a6a42020-01-09 11:39:16 -08008858 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
Michael Wrightfe3de7d2020-07-02 19:05:30 +01008859 prepareSecondaryDisplay(ViewportType::EXTERNAL);
Garfield Tan888a6a42020-01-09 11:39:16 -08008860
Michael Wrighta9cf4192022-12-01 23:46:39 +00008861 prepareDisplay(ui::ROTATION_0);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008862 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008863 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008864
Harry Cutts16a24cc2022-10-26 15:22:19 +00008865 // Check source is a touchpad that would obtain the PointerController.
8866 ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008867
8868 NotifyMotionArgs motionArgs;
8869 processPosition(mapper, 100, 100);
8870 processSync(mapper);
8871
8872 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8873 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8874 ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
8875}
8876
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00008877/**
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008878 * Ensure that the readTime is set to the SYN_REPORT value when processing touch events.
8879 */
8880TEST_F(MultiTouchInputMapperTest, Process_SendsReadTime) {
8881 addConfigurationProperty("touch.deviceType", "touchScreen");
8882 prepareAxes(POSITION);
8883 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8884
Michael Wrighta9cf4192022-12-01 23:46:39 +00008885 prepareDisplay(ui::ROTATION_0);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008886 process(mapper, 10, 11 /*readTime*/, EV_ABS, ABS_MT_TRACKING_ID, 1);
8887 process(mapper, 15, 16 /*readTime*/, EV_ABS, ABS_MT_POSITION_X, 100);
8888 process(mapper, 20, 21 /*readTime*/, EV_ABS, ABS_MT_POSITION_Y, 100);
8889 process(mapper, 25, 26 /*readTime*/, EV_SYN, SYN_REPORT, 0);
8890
8891 NotifyMotionArgs args;
8892 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8893 ASSERT_EQ(26, args.readTime);
8894
8895 process(mapper, 30, 31 /*readTime*/, EV_ABS, ABS_MT_POSITION_X, 110);
8896 process(mapper, 30, 32 /*readTime*/, EV_ABS, ABS_MT_POSITION_Y, 220);
8897 process(mapper, 30, 33 /*readTime*/, EV_SYN, SYN_REPORT, 0);
8898
8899 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8900 ASSERT_EQ(33, args.readTime);
8901}
8902
8903/**
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00008904 * When the viewport is not active (isActive=false), the touch mapper should be disabled and the
8905 * events should not be delivered to the listener.
8906 */
8907TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreDropped) {
8908 addConfigurationProperty("touch.deviceType", "touchScreen");
Yuncheol Heo50c19b12022-11-02 20:33:08 -07008909 // Don't set touch.enableForInactiveViewport to verify the default behavior.
Michael Wrighta9cf4192022-12-01 23:46:39 +00008910 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
8911 false /*isActive*/, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00008912 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8913 prepareAxes(POSITION);
8914 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8915
8916 NotifyMotionArgs motionArgs;
8917 processPosition(mapper, 100, 100);
8918 processSync(mapper);
8919
8920 mFakeListener->assertNotifyMotionWasNotCalled();
8921}
8922
Yuncheol Heo50c19b12022-11-02 20:33:08 -07008923/**
8924 * When the viewport is not active (isActive=false) and touch.enableForInactiveViewport is true,
8925 * the touch mapper can process the events and the events can be delivered to the listener.
8926 */
8927TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreProcessed) {
8928 addConfigurationProperty("touch.deviceType", "touchScreen");
8929 addConfigurationProperty("touch.enableForInactiveViewport", "1");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008930 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
8931 false /*isActive*/, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Yuncheol Heo50c19b12022-11-02 20:33:08 -07008932 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8933 prepareAxes(POSITION);
8934 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8935
8936 NotifyMotionArgs motionArgs;
8937 processPosition(mapper, 100, 100);
8938 processSync(mapper);
8939
8940 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8941 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8942}
8943
Garfield Tanc734e4f2021-01-15 20:01:39 -08008944TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_AbortTouches) {
8945 addConfigurationProperty("touch.deviceType", "touchScreen");
Yuncheol Heo50c19b12022-11-02 20:33:08 -07008946 addConfigurationProperty("touch.enableForInactiveViewport", "0");
Michael Wrighta9cf4192022-12-01 23:46:39 +00008947 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
8948 true /*isActive*/, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Garfield Tanc734e4f2021-01-15 20:01:39 -08008949 std::optional<DisplayViewport> optionalDisplayViewport =
8950 mFakePolicy->getDisplayViewportByUniqueId(UNIQUE_ID);
8951 ASSERT_TRUE(optionalDisplayViewport.has_value());
8952 DisplayViewport displayViewport = *optionalDisplayViewport;
8953
8954 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8955 prepareAxes(POSITION);
8956 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8957
8958 // Finger down
8959 int32_t x = 100, y = 100;
8960 processPosition(mapper, x, y);
8961 processSync(mapper);
8962
8963 NotifyMotionArgs motionArgs;
8964 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8965 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8966
8967 // Deactivate display viewport
8968 displayViewport.isActive = false;
8969 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
8970 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8971
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00008972 // The ongoing touch should be canceled immediately
8973 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8974 EXPECT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
8975
8976 // Finger move is ignored
Garfield Tanc734e4f2021-01-15 20:01:39 -08008977 x += 10, y += 10;
8978 processPosition(mapper, x, y);
8979 processSync(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00008980 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
Garfield Tanc734e4f2021-01-15 20:01:39 -08008981
8982 // Reactivate display viewport
8983 displayViewport.isActive = true;
8984 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
8985 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8986
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00008987 // Finger move again starts new gesture
Garfield Tanc734e4f2021-01-15 20:01:39 -08008988 x += 10, y += 10;
8989 processPosition(mapper, x, y);
8990 processSync(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00008991 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8992 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Garfield Tanc734e4f2021-01-15 20:01:39 -08008993}
8994
Arthur Hung7c645402019-01-25 17:45:42 +08008995TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) {
8996 // Setup the first touch screen device.
Arthur Hung7c645402019-01-25 17:45:42 +08008997 prepareAxes(POSITION | ID | SLOT);
8998 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008999 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung7c645402019-01-25 17:45:42 +08009000
9001 // Create the second touch screen device, and enable multi fingers.
9002 const std::string USB2 = "USB2";
arthurhungdcef2dc2020-08-11 14:47:50 +08009003 const std::string DEVICE_NAME2 = "TOUCHSCREEN2";
Arthur Hung2c9a3342019-07-23 14:18:59 +08009004 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009005 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
arthurhungdcef2dc2020-08-11 14:47:50 +08009006 std::shared_ptr<InputDevice> device2 =
9007 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07009008 ftl::Flags<InputDeviceClass>(0));
arthurhungdcef2dc2020-08-11 14:47:50 +08009009
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009010 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
9011 0 /*flat*/, 0 /*fuzz*/);
9012 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
9013 0 /*flat*/, 0 /*fuzz*/);
9014 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX,
9015 0 /*flat*/, 0 /*fuzz*/);
9016 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX,
9017 0 /*flat*/, 0 /*fuzz*/);
9018 mFakeEventHub->setAbsoluteAxisValue(SECOND_EVENTHUB_ID, ABS_MT_SLOT, 0 /*value*/);
9019 mFakeEventHub->addConfigurationProperty(SECOND_EVENTHUB_ID, String8("touch.deviceType"),
9020 String8("touchScreen"));
Arthur Hung7c645402019-01-25 17:45:42 +08009021
9022 // Setup the second touch screen device.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009023 MultiTouchInputMapper& mapper2 = device2->addMapper<MultiTouchInputMapper>(SECOND_EVENTHUB_ID);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009024 std::list<NotifyArgs> unused =
9025 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
9026 0 /*changes*/);
9027 unused += device2->reset(ARBITRARY_TIME);
Arthur Hung7c645402019-01-25 17:45:42 +08009028
9029 // Setup PointerController.
Michael Wright17db18e2020-06-26 20:51:44 +01009030 std::shared_ptr<FakePointerController> fakePointerController =
9031 std::make_shared<FakePointerController>();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009032 mFakePolicy->setPointerController(fakePointerController);
Arthur Hung7c645402019-01-25 17:45:42 +08009033
9034 // Setup policy for associated displays and show touches.
9035 const uint8_t hdmi1 = 0;
9036 const uint8_t hdmi2 = 1;
9037 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
9038 mFakePolicy->addInputPortAssociation(USB2, hdmi2);
9039 mFakePolicy->setShowTouches(true);
9040
9041 // Create displays.
Michael Wrighta9cf4192022-12-01 23:46:39 +00009042 prepareDisplay(ui::ROTATION_0, hdmi1);
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009043 prepareSecondaryDisplay(ViewportType::EXTERNAL, hdmi2);
Arthur Hung7c645402019-01-25 17:45:42 +08009044
9045 // Default device will reconfigure above, need additional reconfiguration for another device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009046 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
9047 InputReaderConfiguration::CHANGE_DISPLAY_INFO |
9048 InputReaderConfiguration::CHANGE_SHOW_TOUCHES);
Arthur Hung7c645402019-01-25 17:45:42 +08009049
9050 // Two fingers down at default display.
9051 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
9052 processPosition(mapper, x1, y1);
9053 processId(mapper, 1);
9054 processSlot(mapper, 1);
9055 processPosition(mapper, x2, y2);
9056 processId(mapper, 2);
9057 processSync(mapper);
9058
9059 std::map<int32_t, std::vector<int32_t>>::const_iterator iter =
9060 fakePointerController->getSpots().find(DISPLAY_ID);
9061 ASSERT_TRUE(iter != fakePointerController->getSpots().end());
9062 ASSERT_EQ(size_t(2), iter->second.size());
9063
9064 // Two fingers down at second display.
9065 processPosition(mapper2, x1, y1);
9066 processId(mapper2, 1);
9067 processSlot(mapper2, 1);
9068 processPosition(mapper2, x2, y2);
9069 processId(mapper2, 2);
9070 processSync(mapper2);
9071
9072 iter = fakePointerController->getSpots().find(SECONDARY_DISPLAY_ID);
9073 ASSERT_TRUE(iter != fakePointerController->getSpots().end());
9074 ASSERT_EQ(size_t(2), iter->second.size());
Prabir Pradhan197e0862022-07-01 14:28:00 +00009075
9076 // Disable the show touches configuration and ensure the spots are cleared.
9077 mFakePolicy->setShowTouches(false);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009078 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
9079 InputReaderConfiguration::CHANGE_SHOW_TOUCHES);
Prabir Pradhan197e0862022-07-01 14:28:00 +00009080
9081 ASSERT_TRUE(fakePointerController->getSpots().empty());
Arthur Hung7c645402019-01-25 17:45:42 +08009082}
9083
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009084TEST_F(MultiTouchInputMapperTest, VideoFrames_ReceivedByListener) {
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009085 prepareAxes(POSITION);
9086 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009087 prepareDisplay(ui::ROTATION_0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009088 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009089
9090 NotifyMotionArgs motionArgs;
9091 // Unrotated video frame
9092 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9093 std::vector<TouchVideoFrame> frames{frame};
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009094 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009095 processPosition(mapper, 100, 200);
9096 processSync(mapper);
9097 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9098 ASSERT_EQ(frames, motionArgs.videoFrames);
9099
9100 // Subsequent touch events should not have any videoframes
9101 // This is implemented separately in FakeEventHub,
9102 // but that should match the behaviour of TouchVideoDevice.
9103 processPosition(mapper, 200, 200);
9104 processSync(mapper);
9105 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9106 ASSERT_EQ(std::vector<TouchVideoFrame>(), motionArgs.videoFrames);
9107}
9108
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009109TEST_F(MultiTouchInputMapperTest, VideoFrames_AreNotRotated) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009110 prepareAxes(POSITION);
9111 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009112 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009113 // Unrotated video frame
9114 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9115 NotifyMotionArgs motionArgs;
9116
9117 // Test all 4 orientations
Michael Wrighta9cf4192022-12-01 23:46:39 +00009118 for (ui::Rotation orientation : ftl::enum_range<ui::Rotation>()) {
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009119 SCOPED_TRACE("Orientation " + StringPrintf("%i", orientation));
9120 clearViewports();
9121 prepareDisplay(orientation);
9122 std::vector<TouchVideoFrame> frames{frame};
9123 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
9124 processPosition(mapper, 100, 200);
9125 processSync(mapper);
9126 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9127 ASSERT_EQ(frames, motionArgs.videoFrames);
9128 }
9129}
9130
9131TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_AreRotated) {
9132 prepareAxes(POSITION);
9133 addConfigurationProperty("touch.deviceType", "touchScreen");
9134 // Since InputReader works in the un-rotated coordinate space, only devices that are not
9135 // orientation-aware are affected by display rotation.
9136 addConfigurationProperty("touch.orientationAware", "0");
9137 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9138 // Unrotated video frame
9139 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9140 NotifyMotionArgs motionArgs;
9141
9142 // Test all 4 orientations
Michael Wrighta9cf4192022-12-01 23:46:39 +00009143 for (ui::Rotation orientation : ftl::enum_range<ui::Rotation>()) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009144 SCOPED_TRACE("Orientation " + StringPrintf("%i", orientation));
9145 clearViewports();
9146 prepareDisplay(orientation);
9147 std::vector<TouchVideoFrame> frames{frame};
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009148 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009149 processPosition(mapper, 100, 200);
9150 processSync(mapper);
9151 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009152 // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
9153 // compared to the display. This is so that when the window transform (which contains the
9154 // display rotation) is applied later by InputDispatcher, the coordinates end up in the
9155 // window's coordinate space.
9156 frames[0].rotate(getInverseRotation(orientation));
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009157 ASSERT_EQ(frames, motionArgs.videoFrames);
lilinnan687e58f2022-07-19 16:00:50 +08009158
9159 // Release finger.
9160 processSync(mapper);
9161 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009162 }
9163}
9164
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009165TEST_F(MultiTouchInputMapperTest, VideoFrames_MultipleFramesAreNotRotated) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009166 prepareAxes(POSITION);
9167 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009168 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009169 // Unrotated video frames. There's no rule that they must all have the same dimensions,
9170 // so mix these.
9171 TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9172 TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
9173 TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
9174 std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
9175 NotifyMotionArgs motionArgs;
9176
Michael Wrighta9cf4192022-12-01 23:46:39 +00009177 prepareDisplay(ui::ROTATION_90);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009178 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009179 processPosition(mapper, 100, 200);
9180 processSync(mapper);
9181 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009182 ASSERT_EQ(frames, motionArgs.videoFrames);
9183}
9184
9185TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_MultipleFramesAreRotated) {
9186 prepareAxes(POSITION);
9187 addConfigurationProperty("touch.deviceType", "touchScreen");
9188 // Since InputReader works in the un-rotated coordinate space, only devices that are not
9189 // orientation-aware are affected by display rotation.
9190 addConfigurationProperty("touch.orientationAware", "0");
9191 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9192 // Unrotated video frames. There's no rule that they must all have the same dimensions,
9193 // so mix these.
9194 TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9195 TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
9196 TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
9197 std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
9198 NotifyMotionArgs motionArgs;
9199
Michael Wrighta9cf4192022-12-01 23:46:39 +00009200 prepareDisplay(ui::ROTATION_90);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009201 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
9202 processPosition(mapper, 100, 200);
9203 processSync(mapper);
9204 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9205 std::for_each(frames.begin(), frames.end(), [](TouchVideoFrame& frame) {
9206 // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
9207 // compared to the display. This is so that when the window transform (which contains the
9208 // display rotation) is applied later by InputDispatcher, the coordinates end up in the
9209 // window's coordinate space.
Michael Wrighta9cf4192022-12-01 23:46:39 +00009210 frame.rotate(getInverseRotation(ui::ROTATION_90));
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009211 });
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009212 ASSERT_EQ(frames, motionArgs.videoFrames);
9213}
9214
Arthur Hung9da14732019-09-02 16:16:58 +08009215/**
9216 * If we had defined port associations, but the viewport is not ready, the touch device would be
9217 * expected to be disabled, and it should be enabled after the viewport has found.
9218 */
9219TEST_F(MultiTouchInputMapperTest, Configure_EnabledForAssociatedDisplay) {
Arthur Hung9da14732019-09-02 16:16:58 +08009220 constexpr uint8_t hdmi2 = 1;
9221 const std::string secondaryUniqueId = "uniqueId2";
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009222 constexpr ViewportType type = ViewportType::EXTERNAL;
Arthur Hung9da14732019-09-02 16:16:58 +08009223
9224 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi2);
9225
9226 addConfigurationProperty("touch.deviceType", "touchScreen");
9227 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009228 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung9da14732019-09-02 16:16:58 +08009229
9230 ASSERT_EQ(mDevice->isEnabled(), false);
9231
9232 // Add display on hdmi2, the device should be enabled and can receive touch event.
9233 prepareSecondaryDisplay(type, hdmi2);
9234 ASSERT_EQ(mDevice->isEnabled(), true);
9235
9236 // Send a touch event.
9237 processPosition(mapper, 100, 100);
9238 processSync(mapper);
9239
9240 NotifyMotionArgs args;
9241 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9242 ASSERT_EQ(SECONDARY_DISPLAY_ID, args.displayId);
9243}
9244
Arthur Hung421eb1c2020-01-16 00:09:42 +08009245TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleSingleTouch) {
Arthur Hung421eb1c2020-01-16 00:09:42 +08009246 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009247 prepareDisplay(ui::ROTATION_0);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009248 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009249 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung421eb1c2020-01-16 00:09:42 +08009250
9251 NotifyMotionArgs motionArgs;
9252
9253 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
9254 // finger down
9255 processId(mapper, 1);
9256 processPosition(mapper, x1, y1);
9257 processSync(mapper);
9258 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9259 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9260 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9261
9262 // finger move
9263 processId(mapper, 1);
9264 processPosition(mapper, x2, y2);
9265 processSync(mapper);
9266 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9267 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9268 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9269
9270 // finger up.
9271 processId(mapper, -1);
9272 processSync(mapper);
9273 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9274 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9275 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9276
9277 // new finger down
9278 processId(mapper, 1);
9279 processPosition(mapper, x3, y3);
9280 processSync(mapper);
9281 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9282 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9283 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9284}
9285
9286/**
arthurhungcc7f9802020-04-30 17:55:40 +08009287 * Test single touch should be canceled when received the MT_TOOL_PALM event, and the following
9288 * MOVE and UP events should be ignored.
Arthur Hung421eb1c2020-01-16 00:09:42 +08009289 */
arthurhungcc7f9802020-04-30 17:55:40 +08009290TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_SinglePointer) {
Arthur Hung421eb1c2020-01-16 00:09:42 +08009291 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009292 prepareDisplay(ui::ROTATION_0);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009293 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009294 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung421eb1c2020-01-16 00:09:42 +08009295
9296 NotifyMotionArgs motionArgs;
9297
9298 // default tool type is finger
9299 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
arthurhungcc7f9802020-04-30 17:55:40 +08009300 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009301 processPosition(mapper, x1, y1);
9302 processSync(mapper);
9303 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9304 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9305 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9306
9307 // Tool changed to MT_TOOL_PALM expect sending the cancel event.
9308 processToolType(mapper, MT_TOOL_PALM);
9309 processSync(mapper);
9310 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9311 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
9312
9313 // Ignore the following MOVE and UP events if had detect a palm event.
arthurhungcc7f9802020-04-30 17:55:40 +08009314 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009315 processPosition(mapper, x2, y2);
9316 processSync(mapper);
9317 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9318
9319 // finger up.
arthurhungcc7f9802020-04-30 17:55:40 +08009320 processId(mapper, INVALID_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009321 processSync(mapper);
9322 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9323
9324 // new finger down
arthurhungcc7f9802020-04-30 17:55:40 +08009325 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009326 processToolType(mapper, MT_TOOL_FINGER);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009327 processPosition(mapper, x3, y3);
9328 processSync(mapper);
9329 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9330 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9331 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9332}
9333
arthurhungbf89a482020-04-17 17:37:55 +08009334/**
arthurhungcc7f9802020-04-30 17:55:40 +08009335 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event from some finger,
9336 * and the rest active fingers could still be allowed to receive the events
arthurhungbf89a482020-04-17 17:37:55 +08009337 */
arthurhungcc7f9802020-04-30 17:55:40 +08009338TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_TwoPointers) {
arthurhungbf89a482020-04-17 17:37:55 +08009339 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009340 prepareDisplay(ui::ROTATION_0);
arthurhungbf89a482020-04-17 17:37:55 +08009341 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
9342 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9343
9344 NotifyMotionArgs motionArgs;
9345
9346 // default tool type is finger
arthurhungcc7f9802020-04-30 17:55:40 +08009347 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220;
9348 processId(mapper, FIRST_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +08009349 processPosition(mapper, x1, y1);
9350 processSync(mapper);
9351 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9352 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9353 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9354
9355 // Second finger down.
arthurhungcc7f9802020-04-30 17:55:40 +08009356 processSlot(mapper, SECOND_SLOT);
9357 processId(mapper, SECOND_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +08009358 processPosition(mapper, x2, y2);
arthurhungcc7f9802020-04-30 17:55:40 +08009359 processSync(mapper);
9360 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009361 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009362 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
9363
9364 // If the tool type of the first finger changes to MT_TOOL_PALM,
9365 // we expect to receive ACTION_POINTER_UP with cancel flag.
9366 processSlot(mapper, FIRST_SLOT);
9367 processId(mapper, FIRST_TRACKING_ID);
9368 processToolType(mapper, MT_TOOL_PALM);
9369 processSync(mapper);
9370 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009371 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009372 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9373
9374 // The following MOVE events of second finger should be processed.
9375 processSlot(mapper, SECOND_SLOT);
9376 processId(mapper, SECOND_TRACKING_ID);
9377 processPosition(mapper, x2 + 1, y2 + 1);
9378 processSync(mapper);
9379 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9380 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9381 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9382
9383 // First finger up. It used to be in palm mode, and we already generated ACTION_POINTER_UP for
9384 // it. Second finger receive move.
9385 processSlot(mapper, FIRST_SLOT);
9386 processId(mapper, INVALID_TRACKING_ID);
9387 processSync(mapper);
9388 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9389 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9390 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9391
9392 // Second finger keeps moving.
9393 processSlot(mapper, SECOND_SLOT);
9394 processId(mapper, SECOND_TRACKING_ID);
9395 processPosition(mapper, x2 + 2, y2 + 2);
9396 processSync(mapper);
9397 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9398 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9399 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9400
9401 // Second finger up.
9402 processId(mapper, INVALID_TRACKING_ID);
9403 processSync(mapper);
9404 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9405 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9406 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9407}
9408
9409/**
9410 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event, if only 1 finger
9411 * is active, it should send CANCEL after receiving the MT_TOOL_PALM event.
9412 */
9413TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_ShouldCancelWhenAllTouchIsPalm) {
9414 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009415 prepareDisplay(ui::ROTATION_0);
arthurhungcc7f9802020-04-30 17:55:40 +08009416 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
9417 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9418
9419 NotifyMotionArgs motionArgs;
9420
9421 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
9422 // First finger down.
9423 processId(mapper, FIRST_TRACKING_ID);
9424 processPosition(mapper, x1, y1);
9425 processSync(mapper);
9426 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9427 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9428 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9429
9430 // Second finger down.
9431 processSlot(mapper, SECOND_SLOT);
9432 processId(mapper, SECOND_TRACKING_ID);
9433 processPosition(mapper, x2, y2);
arthurhungbf89a482020-04-17 17:37:55 +08009434 processSync(mapper);
9435 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009436 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
arthurhungbf89a482020-04-17 17:37:55 +08009437 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9438
arthurhungcc7f9802020-04-30 17:55:40 +08009439 // If the tool type of the first finger changes to MT_TOOL_PALM,
9440 // we expect to receive ACTION_POINTER_UP with cancel flag.
9441 processSlot(mapper, FIRST_SLOT);
9442 processId(mapper, FIRST_TRACKING_ID);
9443 processToolType(mapper, MT_TOOL_PALM);
9444 processSync(mapper);
9445 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009446 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009447 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9448
9449 // Second finger keeps moving.
9450 processSlot(mapper, SECOND_SLOT);
9451 processId(mapper, SECOND_TRACKING_ID);
9452 processPosition(mapper, x2 + 1, y2 + 1);
9453 processSync(mapper);
9454 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9455 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9456
9457 // second finger becomes palm, receive cancel due to only 1 finger is active.
9458 processId(mapper, SECOND_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +08009459 processToolType(mapper, MT_TOOL_PALM);
9460 processSync(mapper);
9461 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9462 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
9463
arthurhungcc7f9802020-04-30 17:55:40 +08009464 // third finger down.
9465 processSlot(mapper, THIRD_SLOT);
9466 processId(mapper, THIRD_TRACKING_ID);
9467 processToolType(mapper, MT_TOOL_FINGER);
arthurhungbf89a482020-04-17 17:37:55 +08009468 processPosition(mapper, x3, y3);
9469 processSync(mapper);
arthurhungbf89a482020-04-17 17:37:55 +08009470 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9471 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9472 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
arthurhungcc7f9802020-04-30 17:55:40 +08009473 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9474
9475 // third finger move
9476 processId(mapper, THIRD_TRACKING_ID);
9477 processPosition(mapper, x3 + 1, y3 + 1);
9478 processSync(mapper);
9479 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9480 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9481
9482 // first finger up, third finger receive move.
9483 processSlot(mapper, FIRST_SLOT);
9484 processId(mapper, INVALID_TRACKING_ID);
9485 processSync(mapper);
9486 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9487 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9488 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9489
9490 // second finger up, third finger receive move.
9491 processSlot(mapper, SECOND_SLOT);
9492 processId(mapper, INVALID_TRACKING_ID);
9493 processSync(mapper);
9494 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9495 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9496 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9497
9498 // third finger up.
9499 processSlot(mapper, THIRD_SLOT);
9500 processId(mapper, INVALID_TRACKING_ID);
9501 processSync(mapper);
9502 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9503 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9504 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9505}
9506
9507/**
9508 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event from some finger,
9509 * and the active finger could still be allowed to receive the events
9510 */
9511TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_KeepFirstPointer) {
9512 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009513 prepareDisplay(ui::ROTATION_0);
arthurhungcc7f9802020-04-30 17:55:40 +08009514 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
9515 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9516
9517 NotifyMotionArgs motionArgs;
9518
9519 // default tool type is finger
9520 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220;
9521 processId(mapper, FIRST_TRACKING_ID);
9522 processPosition(mapper, x1, y1);
9523 processSync(mapper);
9524 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9525 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9526 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9527
9528 // Second finger down.
9529 processSlot(mapper, SECOND_SLOT);
9530 processId(mapper, SECOND_TRACKING_ID);
9531 processPosition(mapper, x2, y2);
9532 processSync(mapper);
9533 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009534 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009535 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9536
9537 // If the tool type of the second finger changes to MT_TOOL_PALM,
9538 // we expect to receive ACTION_POINTER_UP with cancel flag.
9539 processId(mapper, SECOND_TRACKING_ID);
9540 processToolType(mapper, MT_TOOL_PALM);
9541 processSync(mapper);
9542 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009543 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009544 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9545
9546 // The following MOVE event should be processed.
9547 processSlot(mapper, FIRST_SLOT);
9548 processId(mapper, FIRST_TRACKING_ID);
9549 processPosition(mapper, x1 + 1, y1 + 1);
9550 processSync(mapper);
9551 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9552 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9553 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9554
9555 // second finger up.
9556 processSlot(mapper, SECOND_SLOT);
9557 processId(mapper, INVALID_TRACKING_ID);
9558 processSync(mapper);
9559 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9560 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9561
9562 // first finger keep moving
9563 processSlot(mapper, FIRST_SLOT);
9564 processId(mapper, FIRST_TRACKING_ID);
9565 processPosition(mapper, x1 + 2, y1 + 2);
9566 processSync(mapper);
9567 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9568 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9569
9570 // first finger up.
9571 processId(mapper, INVALID_TRACKING_ID);
9572 processSync(mapper);
9573 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9574 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9575 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
arthurhungbf89a482020-04-17 17:37:55 +08009576}
9577
Arthur Hung9ad18942021-06-19 02:04:46 +00009578/**
9579 * Test multi-touch should sent ACTION_POINTER_UP/ACTION_UP when received the INVALID_TRACKING_ID,
9580 * to prevent the driver side may send unexpected data after set tracking id as INVALID_TRACKING_ID
9581 * cause slot be valid again.
9582 */
9583TEST_F(MultiTouchInputMapperTest, Process_MultiTouch_WithInvalidTrackingId) {
9584 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009585 prepareDisplay(ui::ROTATION_0);
Arthur Hung9ad18942021-06-19 02:04:46 +00009586 prepareAxes(POSITION | ID | SLOT | PRESSURE);
9587 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9588
9589 NotifyMotionArgs motionArgs;
9590
9591 constexpr int32_t x1 = 100, y1 = 200, x2 = 0, y2 = 0;
9592 // First finger down.
9593 processId(mapper, FIRST_TRACKING_ID);
9594 processPosition(mapper, x1, y1);
9595 processPressure(mapper, RAW_PRESSURE_MAX);
9596 processSync(mapper);
9597 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9598 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9599 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9600
9601 // First finger move.
9602 processId(mapper, FIRST_TRACKING_ID);
9603 processPosition(mapper, x1 + 1, y1 + 1);
9604 processPressure(mapper, RAW_PRESSURE_MAX);
9605 processSync(mapper);
9606 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9607 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9608 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9609
9610 // Second finger down.
9611 processSlot(mapper, SECOND_SLOT);
9612 processId(mapper, SECOND_TRACKING_ID);
9613 processPosition(mapper, x2, y2);
9614 processPressure(mapper, RAW_PRESSURE_MAX);
9615 processSync(mapper);
9616 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009617 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Arthur Hung9ad18942021-06-19 02:04:46 +00009618 ASSERT_EQ(uint32_t(2), motionArgs.pointerCount);
9619
9620 // second finger up with some unexpected data.
9621 processSlot(mapper, SECOND_SLOT);
9622 processId(mapper, INVALID_TRACKING_ID);
9623 processPosition(mapper, x2, y2);
9624 processSync(mapper);
9625 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009626 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Arthur Hung9ad18942021-06-19 02:04:46 +00009627 ASSERT_EQ(uint32_t(2), motionArgs.pointerCount);
9628
9629 // first finger up with some unexpected data.
9630 processSlot(mapper, FIRST_SLOT);
9631 processId(mapper, INVALID_TRACKING_ID);
9632 processPosition(mapper, x2, y2);
9633 processPressure(mapper, RAW_PRESSURE_MAX);
9634 processSync(mapper);
9635 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9636 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9637 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9638}
9639
Prabir Pradhanafabcde2022-09-27 19:32:43 +00009640TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState) {
9641 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009642 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00009643 prepareAxes(POSITION | ID | SLOT | PRESSURE);
9644 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9645
9646 // First finger down.
9647 processId(mapper, FIRST_TRACKING_ID);
9648 processPosition(mapper, 100, 200);
9649 processPressure(mapper, RAW_PRESSURE_MAX);
9650 processSync(mapper);
9651 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9652 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
9653
9654 // Second finger down.
9655 processSlot(mapper, SECOND_SLOT);
9656 processId(mapper, SECOND_TRACKING_ID);
9657 processPosition(mapper, 300, 400);
9658 processPressure(mapper, RAW_PRESSURE_MAX);
9659 processSync(mapper);
9660 ASSERT_NO_FATAL_FAILURE(
9661 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(ACTION_POINTER_1_DOWN)));
9662
9663 // Reset the mapper. When the mapper is reset, we expect the current multi-touch state to be
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00009664 // preserved. Resetting should cancel the ongoing gesture.
9665 resetMapper(mapper, ARBITRARY_TIME);
9666 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9667 WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
Prabir Pradhanafabcde2022-09-27 19:32:43 +00009668
9669 // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
9670 // the existing touch state to generate a down event.
9671 processPosition(mapper, 301, 302);
9672 processSync(mapper);
9673 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9674 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
9675 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9676 AllOf(WithMotionAction(ACTION_POINTER_1_DOWN), WithPressure(1.f))));
9677
9678 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9679}
9680
9681TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState_NoPointersDown) {
9682 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009683 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00009684 prepareAxes(POSITION | ID | SLOT | PRESSURE);
9685 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9686
9687 // First finger touches down and releases.
9688 processId(mapper, FIRST_TRACKING_ID);
9689 processPosition(mapper, 100, 200);
9690 processPressure(mapper, RAW_PRESSURE_MAX);
9691 processSync(mapper);
9692 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9693 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
9694 processId(mapper, INVALID_TRACKING_ID);
9695 processSync(mapper);
9696 ASSERT_NO_FATAL_FAILURE(
9697 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
9698
9699 // Reset the mapper. When the mapper is reset, we expect it to restore the latest
9700 // raw state where no pointers are down.
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00009701 resetMapper(mapper, ARBITRARY_TIME);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00009702 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9703
9704 // Send an empty sync frame. Since there are no pointers, no events are generated.
9705 processSync(mapper);
9706 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9707}
9708
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +00009709TEST_F(MultiTouchInputMapperTest, StylusSourceIsAddedDynamicallyFromToolType) {
Prabir Pradhanf9a41282022-10-25 17:15:50 +00009710 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009711 prepareDisplay(ui::ROTATION_0);
Prabir Pradhanf9a41282022-10-25 17:15:50 +00009712 prepareAxes(POSITION | ID | SLOT | PRESSURE | TOOL_TYPE);
9713 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +00009714 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
Prabir Pradhanf9a41282022-10-25 17:15:50 +00009715
9716 // Even if the device supports reporting the ABS_MT_TOOL_TYPE axis, which could give it the
9717 // ability to report MT_TOOL_PEN, we do not report the device as coming from a stylus source.
9718 // Due to limitations in the evdev protocol, we cannot say for certain that a device is capable
9719 // of reporting stylus events just because it supports ABS_MT_TOOL_TYPE.
9720 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
9721
9722 // However, if the device ever ends up reporting an event with MT_TOOL_PEN, it should be
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +00009723 // reported with the stylus source.
Prabir Pradhanf9a41282022-10-25 17:15:50 +00009724 processId(mapper, FIRST_TRACKING_ID);
9725 processToolType(mapper, MT_TOOL_PEN);
9726 processPosition(mapper, 100, 200);
9727 processPressure(mapper, RAW_PRESSURE_MAX);
9728 processSync(mapper);
9729 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9730 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
9731 WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
9732 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
9733
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +00009734 // Now that we know the device supports styluses, ensure that the device is re-configured with
9735 // the stylus source.
9736 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS, mapper.getSources());
9737 {
9738 const auto& devices = mReader->getInputDevices();
9739 auto deviceInfo =
9740 std::find_if(devices.begin(), devices.end(),
9741 [](const InputDeviceInfo& info) { return info.getId() == DEVICE_ID; });
9742 LOG_ALWAYS_FATAL_IF(deviceInfo == devices.end(), "Cannot find InputDevice");
9743 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS, deviceInfo->getSources());
9744 }
9745
9746 // Ensure the device was not reset to prevent interruptions of any ongoing gestures.
9747 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
9748
Prabir Pradhanf9a41282022-10-25 17:15:50 +00009749 processId(mapper, INVALID_TRACKING_ID);
9750 processSync(mapper);
9751 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9752 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
9753 WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
9754 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
Prabir Pradhanf9a41282022-10-25 17:15:50 +00009755}
9756
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009757// --- MultiTouchInputMapperTest_ExternalDevice ---
9758
9759class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest {
9760protected:
Chris Yea52ade12020-08-27 16:49:20 -07009761 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009762};
9763
9764/**
9765 * Expect fallback to internal viewport if device is external and external viewport is not present.
9766 */
9767TEST_F(MultiTouchInputMapperTest_ExternalDevice, Viewports_Fallback) {
9768 prepareAxes(POSITION);
9769 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +00009770 prepareDisplay(ui::ROTATION_0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009771 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9772
9773 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
9774
9775 NotifyMotionArgs motionArgs;
9776
9777 // Expect the event to be sent to the internal viewport,
9778 // because an external viewport is not present.
9779 processPosition(mapper, 100, 100);
9780 processSync(mapper);
9781 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9782 ASSERT_EQ(ADISPLAY_ID_DEFAULT, motionArgs.displayId);
9783
9784 // Expect the event to be sent to the external viewport if it is present.
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009785 prepareSecondaryDisplay(ViewportType::EXTERNAL);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009786 processPosition(mapper, 100, 100);
9787 processSync(mapper);
9788 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9789 ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
9790}
Arthur Hung4197f6b2020-03-16 15:39:59 +08009791
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009792TEST_F(MultiTouchInputMapperTest, Process_TouchpadCapture) {
9793 // we need a pointer controller for mouse mode of touchpad (start pointer at 0,0)
9794 std::shared_ptr<FakePointerController> fakePointerController =
9795 std::make_shared<FakePointerController>();
9796 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
9797 fakePointerController->setPosition(0, 0);
9798 fakePointerController->setButtonState(0);
9799
9800 // prepare device and capture
Michael Wrighta9cf4192022-12-01 23:46:39 +00009801 prepareDisplay(ui::ROTATION_0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009802 prepareAxes(POSITION | ID | SLOT);
9803 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
9804 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
9805 mFakePolicy->setPointerCapture(true);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009806 mFakePolicy->setPointerController(fakePointerController);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009807 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9808
9809 // captured touchpad should be a touchpad source
9810 NotifyDeviceResetArgs resetArgs;
9811 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
9812 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
9813
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00009814 InputDeviceInfo deviceInfo = mDevice->getDeviceInfo();
Chris Yef74dc422020-09-02 22:41:50 -07009815
9816 const InputDeviceInfo::MotionRange* relRangeX =
9817 deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, AINPUT_SOURCE_TOUCHPAD);
9818 ASSERT_NE(relRangeX, nullptr);
9819 ASSERT_EQ(relRangeX->min, -(RAW_X_MAX - RAW_X_MIN));
9820 ASSERT_EQ(relRangeX->max, RAW_X_MAX - RAW_X_MIN);
9821 const InputDeviceInfo::MotionRange* relRangeY =
9822 deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, AINPUT_SOURCE_TOUCHPAD);
9823 ASSERT_NE(relRangeY, nullptr);
9824 ASSERT_EQ(relRangeY->min, -(RAW_Y_MAX - RAW_Y_MIN));
9825 ASSERT_EQ(relRangeY->max, RAW_Y_MAX - RAW_Y_MIN);
9826
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009827 // run captured pointer tests - note that this is unscaled, so input listener events should be
9828 // identical to what the hardware sends (accounting for any
9829 // calibration).
9830 // FINGER 0 DOWN
Chris Ye364fdb52020-08-05 15:07:56 -07009831 processSlot(mapper, 0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009832 processId(mapper, 1);
9833 processPosition(mapper, 100 + RAW_X_MIN, 100 + RAW_Y_MIN);
9834 processKey(mapper, BTN_TOUCH, 1);
9835 processSync(mapper);
9836
9837 // expect coord[0] to contain initial location of touch 0
9838 NotifyMotionArgs args;
9839 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9840 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
9841 ASSERT_EQ(1U, args.pointerCount);
9842 ASSERT_EQ(0, args.pointerProperties[0].id);
9843 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, args.source);
9844 ASSERT_NO_FATAL_FAILURE(
9845 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
9846
9847 // FINGER 1 DOWN
9848 processSlot(mapper, 1);
9849 processId(mapper, 2);
9850 processPosition(mapper, 560 + RAW_X_MIN, 154 + RAW_Y_MIN);
9851 processSync(mapper);
9852
9853 // expect coord[0] to contain previous location, coord[1] to contain new touch 1 location
9854 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009855 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009856 ASSERT_EQ(2U, args.pointerCount);
9857 ASSERT_EQ(0, args.pointerProperties[0].id);
9858 ASSERT_EQ(1, args.pointerProperties[1].id);
9859 ASSERT_NO_FATAL_FAILURE(
9860 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
9861 ASSERT_NO_FATAL_FAILURE(
9862 assertPointerCoords(args.pointerCoords[1], 560, 154, 1, 0, 0, 0, 0, 0, 0, 0));
9863
9864 // FINGER 1 MOVE
9865 processPosition(mapper, 540 + RAW_X_MIN, 690 + RAW_Y_MIN);
9866 processSync(mapper);
9867
9868 // expect coord[0] to contain previous location, coord[1] to contain new touch 1 location
9869 // from move
9870 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9871 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9872 ASSERT_NO_FATAL_FAILURE(
9873 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
9874 ASSERT_NO_FATAL_FAILURE(
9875 assertPointerCoords(args.pointerCoords[1], 540, 690, 1, 0, 0, 0, 0, 0, 0, 0));
9876
9877 // FINGER 0 MOVE
9878 processSlot(mapper, 0);
9879 processPosition(mapper, 50 + RAW_X_MIN, 800 + RAW_Y_MIN);
9880 processSync(mapper);
9881
9882 // expect coord[0] to contain new touch 0 location, coord[1] to contain previous location
9883 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9884 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9885 ASSERT_NO_FATAL_FAILURE(
9886 assertPointerCoords(args.pointerCoords[0], 50, 800, 1, 0, 0, 0, 0, 0, 0, 0));
9887 ASSERT_NO_FATAL_FAILURE(
9888 assertPointerCoords(args.pointerCoords[1], 540, 690, 1, 0, 0, 0, 0, 0, 0, 0));
9889
9890 // BUTTON DOWN
9891 processKey(mapper, BTN_LEFT, 1);
9892 processSync(mapper);
9893
9894 // touchinputmapper design sends a move before button press
9895 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9896 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9897 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9898 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
9899
9900 // BUTTON UP
9901 processKey(mapper, BTN_LEFT, 0);
9902 processSync(mapper);
9903
9904 // touchinputmapper design sends a move after button release
9905 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9906 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
9907 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9908 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9909
9910 // FINGER 0 UP
9911 processId(mapper, -1);
9912 processSync(mapper);
9913 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9914 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | 0x0000, args.action);
9915
9916 // FINGER 1 MOVE
9917 processSlot(mapper, 1);
9918 processPosition(mapper, 320 + RAW_X_MIN, 900 + RAW_Y_MIN);
9919 processSync(mapper);
9920
9921 // expect coord[0] to contain new location of touch 1, and properties[0].id to contain 1
9922 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9923 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9924 ASSERT_EQ(1U, args.pointerCount);
9925 ASSERT_EQ(1, args.pointerProperties[0].id);
9926 ASSERT_NO_FATAL_FAILURE(
9927 assertPointerCoords(args.pointerCoords[0], 320, 900, 1, 0, 0, 0, 0, 0, 0, 0));
9928
9929 // FINGER 1 UP
9930 processId(mapper, -1);
9931 processKey(mapper, BTN_TOUCH, 0);
9932 processSync(mapper);
9933 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9934 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
9935
Harry Cutts16a24cc2022-10-26 15:22:19 +00009936 // A non captured touchpad should have a mouse and touchpad source.
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009937 mFakePolicy->setPointerCapture(false);
9938 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
9939 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Harry Cutts16a24cc2022-10-26 15:22:19 +00009940 ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009941}
9942
9943TEST_F(MultiTouchInputMapperTest, Process_UnCapturedTouchpadPointer) {
9944 std::shared_ptr<FakePointerController> fakePointerController =
9945 std::make_shared<FakePointerController>();
9946 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
9947 fakePointerController->setPosition(0, 0);
9948 fakePointerController->setButtonState(0);
9949
9950 // prepare device and capture
Michael Wrighta9cf4192022-12-01 23:46:39 +00009951 prepareDisplay(ui::ROTATION_0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009952 prepareAxes(POSITION | ID | SLOT);
9953 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
9954 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009955 mFakePolicy->setPointerController(fakePointerController);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009956 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9957 // run uncaptured pointer tests - pushes out generic events
9958 // FINGER 0 DOWN
9959 processId(mapper, 3);
9960 processPosition(mapper, 100, 100);
9961 processKey(mapper, BTN_TOUCH, 1);
9962 processSync(mapper);
9963
9964 // start at (100,100), cursor should be at (0,0) * scale
9965 NotifyMotionArgs args;
9966 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9967 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
9968 ASSERT_NO_FATAL_FAILURE(
9969 assertPointerCoords(args.pointerCoords[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
9970
9971 // FINGER 0 MOVE
9972 processPosition(mapper, 200, 200);
9973 processSync(mapper);
9974
9975 // compute scaling to help with touch position checking
9976 float rawDiagonal = hypotf(RAW_X_MAX - RAW_X_MIN, RAW_Y_MAX - RAW_Y_MIN);
9977 float displayDiagonal = hypotf(DISPLAY_WIDTH, DISPLAY_HEIGHT);
9978 float scale =
9979 mFakePolicy->getPointerGestureMovementSpeedRatio() * displayDiagonal / rawDiagonal;
9980
9981 // translate from (100,100) -> (200,200), cursor should have changed to (100,100) * scale)
9982 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9983 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
9984 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 100 * scale, 100 * scale, 0,
9985 0, 0, 0, 0, 0, 0, 0));
9986}
9987
9988TEST_F(MultiTouchInputMapperTest, WhenCapturedAndNotCaptured_GetSources) {
9989 std::shared_ptr<FakePointerController> fakePointerController =
9990 std::make_shared<FakePointerController>();
9991
Michael Wrighta9cf4192022-12-01 23:46:39 +00009992 prepareDisplay(ui::ROTATION_0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009993 prepareAxes(POSITION | ID | SLOT);
9994 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009995 mFakePolicy->setPointerController(fakePointerController);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009996 mFakePolicy->setPointerCapture(false);
9997 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9998
Harry Cutts16a24cc2022-10-26 15:22:19 +00009999 // An uncaptured touchpad should be a pointer device, with additional touchpad source.
10000 ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010001
Harry Cutts16a24cc2022-10-26 15:22:19 +000010002 // A captured touchpad should just have a touchpad source.
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010003 mFakePolicy->setPointerCapture(true);
10004 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
10005 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
10006}
10007
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +000010008// --- BluetoothMultiTouchInputMapperTest ---
10009
10010class BluetoothMultiTouchInputMapperTest : public MultiTouchInputMapperTest {
10011protected:
10012 void SetUp() override {
10013 InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL, BUS_BLUETOOTH);
10014 }
10015};
10016
10017TEST_F(BluetoothMultiTouchInputMapperTest, TimestampSmoothening) {
10018 addConfigurationProperty("touch.deviceType", "touchScreen");
Michael Wrighta9cf4192022-12-01 23:46:39 +000010019 prepareDisplay(ui::ROTATION_0);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +000010020 prepareAxes(POSITION | ID | SLOT | PRESSURE);
10021 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10022
10023 nsecs_t kernelEventTime = ARBITRARY_TIME;
10024 nsecs_t expectedEventTime = ARBITRARY_TIME;
10025 // Touch down.
10026 processId(mapper, FIRST_TRACKING_ID);
10027 processPosition(mapper, 100, 200);
10028 processPressure(mapper, RAW_PRESSURE_MAX);
10029 processSync(mapper, ARBITRARY_TIME);
10030 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10031 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithEventTime(ARBITRARY_TIME))));
10032
10033 // Process several events that come in quick succession, according to their timestamps.
10034 for (int i = 0; i < 3; i++) {
10035 constexpr static nsecs_t delta = ms2ns(1);
10036 static_assert(delta < MIN_BLUETOOTH_TIMESTAMP_DELTA);
10037 kernelEventTime += delta;
10038 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
10039
10040 processPosition(mapper, 101 + i, 201 + i);
10041 processSync(mapper, kernelEventTime);
10042 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10043 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
10044 WithEventTime(expectedEventTime))));
10045 }
10046
10047 // Release the touch.
10048 processId(mapper, INVALID_TRACKING_ID);
10049 processPressure(mapper, RAW_PRESSURE_MIN);
10050 processSync(mapper, ARBITRARY_TIME + ms2ns(50));
10051 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10052 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
10053 WithEventTime(ARBITRARY_TIME + ms2ns(50)))));
10054}
10055
10056// --- MultiTouchPointerModeTest ---
10057
HQ Liue6983c72022-04-19 22:14:56 +000010058class MultiTouchPointerModeTest : public MultiTouchInputMapperTest {
10059protected:
10060 float mPointerMovementScale;
10061 float mPointerXZoomScale;
10062 void preparePointerMode(int xAxisResolution, int yAxisResolution) {
10063 addConfigurationProperty("touch.deviceType", "pointer");
10064 std::shared_ptr<FakePointerController> fakePointerController =
10065 std::make_shared<FakePointerController>();
10066 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
10067 fakePointerController->setPosition(0, 0);
10068 fakePointerController->setButtonState(0);
Michael Wrighta9cf4192022-12-01 23:46:39 +000010069 prepareDisplay(ui::ROTATION_0);
HQ Liue6983c72022-04-19 22:14:56 +000010070
10071 prepareAxes(POSITION);
10072 prepareAbsoluteAxisResolution(xAxisResolution, yAxisResolution);
10073 // In order to enable swipe and freeform gesture in pointer mode, pointer capture
10074 // needs to be disabled, and the pointer gesture needs to be enabled.
10075 mFakePolicy->setPointerCapture(false);
10076 mFakePolicy->setPointerGestureEnabled(true);
10077 mFakePolicy->setPointerController(fakePointerController);
10078
10079 float rawDiagonal = hypotf(RAW_X_MAX - RAW_X_MIN, RAW_Y_MAX - RAW_Y_MIN);
10080 float displayDiagonal = hypotf(DISPLAY_WIDTH, DISPLAY_HEIGHT);
10081 mPointerMovementScale =
10082 mFakePolicy->getPointerGestureMovementSpeedRatio() * displayDiagonal / rawDiagonal;
10083 mPointerXZoomScale =
10084 mFakePolicy->getPointerGestureZoomSpeedRatio() * displayDiagonal / rawDiagonal;
10085 }
10086
10087 void prepareAbsoluteAxisResolution(int xAxisResolution, int yAxisResolution) {
10088 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
10089 /*flat*/ 0,
10090 /*fuzz*/ 0, /*resolution*/ xAxisResolution);
10091 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
10092 /*flat*/ 0,
10093 /*fuzz*/ 0, /*resolution*/ yAxisResolution);
10094 }
10095};
10096
10097/**
10098 * Two fingers down on a pointer mode touch pad. The width
10099 * of the two finger is larger than 1/4 of the touch pack diagnal length. However, it
10100 * is smaller than the fixed min physical length 30mm. Two fingers' distance must
10101 * be greater than the both value to be freeform gesture, so that after two
10102 * fingers start to move downwards, the gesture should be swipe.
10103 */
10104TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthSwipe) {
10105 // The min freeform gesture width is 25units/mm x 30mm = 750
10106 // which is greater than fraction of the diagnal length of the touchpad (349).
10107 // Thus, MaxSwipWidth is 750.
10108 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
10109 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10110 NotifyMotionArgs motionArgs;
10111
10112 // Two fingers down at once.
10113 // The two fingers are 450 units apart, expects the current gesture to be PRESS
10114 // Pointer's initial position is used the [0,0] coordinate.
10115 int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125;
10116
10117 processId(mapper, FIRST_TRACKING_ID);
10118 processPosition(mapper, x1, y1);
10119 processMTSync(mapper);
10120 processId(mapper, SECOND_TRACKING_ID);
10121 processPosition(mapper, x2, y2);
10122 processMTSync(mapper);
10123 processSync(mapper);
10124
10125 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10126 ASSERT_EQ(1U, motionArgs.pointerCount);
10127 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10128 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010129 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010130 ASSERT_NO_FATAL_FAILURE(
10131 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
10132
10133 // It should be recognized as a SWIPE gesture when two fingers start to move down,
10134 // that there should be 1 pointer.
10135 int32_t movingDistance = 200;
10136 y1 += movingDistance;
10137 y2 += movingDistance;
10138
10139 processId(mapper, FIRST_TRACKING_ID);
10140 processPosition(mapper, x1, y1);
10141 processMTSync(mapper);
10142 processId(mapper, SECOND_TRACKING_ID);
10143 processPosition(mapper, x2, y2);
10144 processMTSync(mapper);
10145 processSync(mapper);
10146
10147 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10148 ASSERT_EQ(1U, motionArgs.pointerCount);
10149 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10150 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010151 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010152 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
10153 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
10154 0, 0, 0, 0));
10155}
10156
10157/**
10158 * Two fingers down on a pointer mode touch pad. The width of the two finger is larger
10159 * than the minimum freeform gesture width, 30mm. However, it is smaller than 1/4 of
10160 * the touch pack diagnal length. Two fingers' distance must be greater than the both
10161 * value to be freeform gesture, so that after two fingers start to move downwards,
10162 * the gesture should be swipe.
10163 */
10164TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthLowResolutionSwipe) {
10165 // The min freeform gesture width is 5units/mm x 30mm = 150
10166 // which is greater than fraction of the diagnal length of the touchpad (349).
10167 // Thus, MaxSwipWidth is the fraction of the diagnal length, 349.
10168 preparePointerMode(5 /*xResolution*/, 5 /*yResolution*/);
10169 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10170 NotifyMotionArgs motionArgs;
10171
10172 // Two fingers down at once.
10173 // The two fingers are 250 units apart, expects the current gesture to be PRESS
10174 // Pointer's initial position is used the [0,0] coordinate.
10175 int32_t x1 = 100, y1 = 125, x2 = 350, y2 = 125;
10176
10177 processId(mapper, FIRST_TRACKING_ID);
10178 processPosition(mapper, x1, y1);
10179 processMTSync(mapper);
10180 processId(mapper, SECOND_TRACKING_ID);
10181 processPosition(mapper, x2, y2);
10182 processMTSync(mapper);
10183 processSync(mapper);
10184
10185 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10186 ASSERT_EQ(1U, motionArgs.pointerCount);
10187 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10188 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010189 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010190 ASSERT_NO_FATAL_FAILURE(
10191 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
10192
10193 // It should be recognized as a SWIPE gesture when two fingers start to move down,
10194 // and there should be 1 pointer.
10195 int32_t movingDistance = 200;
10196 y1 += movingDistance;
10197 y2 += movingDistance;
10198
10199 processId(mapper, FIRST_TRACKING_ID);
10200 processPosition(mapper, x1, y1);
10201 processMTSync(mapper);
10202 processId(mapper, SECOND_TRACKING_ID);
10203 processPosition(mapper, x2, y2);
10204 processMTSync(mapper);
10205 processSync(mapper);
10206
10207 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10208 ASSERT_EQ(1U, motionArgs.pointerCount);
10209 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10210 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010211 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010212 // New coordinate is the scaled relative coordinate from the initial coordinate.
10213 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
10214 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
10215 0, 0, 0, 0));
10216}
10217
10218/**
10219 * Touch the touch pad with two fingers with a distance wider than the minimum freeform
10220 * gesture width and 1/4 of the diagnal length of the touchpad. Expect to receive
10221 * freeform gestures after two fingers start to move downwards.
10222 */
10223TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) {
10224 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
10225 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10226
10227 NotifyMotionArgs motionArgs;
10228
10229 // Two fingers down at once. Wider than the max swipe width.
10230 // The gesture is expected to be PRESS, then transformed to FREEFORM
10231 int32_t x1 = 100, y1 = 125, x2 = 900, y2 = 125;
10232
10233 processId(mapper, FIRST_TRACKING_ID);
10234 processPosition(mapper, x1, y1);
10235 processMTSync(mapper);
10236 processId(mapper, SECOND_TRACKING_ID);
10237 processPosition(mapper, x2, y2);
10238 processMTSync(mapper);
10239 processSync(mapper);
10240
10241 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10242 ASSERT_EQ(1U, motionArgs.pointerCount);
10243 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10244 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010245 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010246 // One pointer for PRESS, and its coordinate is used as the origin for pointer coordinates.
10247 ASSERT_NO_FATAL_FAILURE(
10248 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
10249
10250 int32_t movingDistance = 200;
10251
10252 // Move two fingers down, expect a cancel event because gesture is changing to freeform,
10253 // then two down events for two pointers.
10254 y1 += movingDistance;
10255 y2 += movingDistance;
10256
10257 processId(mapper, FIRST_TRACKING_ID);
10258 processPosition(mapper, x1, y1);
10259 processMTSync(mapper);
10260 processId(mapper, SECOND_TRACKING_ID);
10261 processPosition(mapper, x2, y2);
10262 processMTSync(mapper);
10263 processSync(mapper);
10264
10265 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10266 // The previous PRESS gesture is cancelled, because it is transformed to freeform
10267 ASSERT_EQ(1U, motionArgs.pointerCount);
10268 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
10269 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10270 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
10271 ASSERT_EQ(1U, motionArgs.pointerCount);
10272 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10273 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10274 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010275 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010276 ASSERT_EQ(2U, motionArgs.pointerCount);
10277 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN, motionArgs.action & AMOTION_EVENT_ACTION_MASK);
10278 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010279 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010280 // Two pointers' scaled relative coordinates from their initial centroid.
10281 // Initial y coordinates are 0 as y1 and y2 have the same value.
10282 float cookedX1 = (x1 - x2) / 2 * mPointerXZoomScale;
10283 float cookedX2 = (x2 - x1) / 2 * mPointerXZoomScale;
10284 // When pointers move, the new coordinates equal to the initial coordinates plus
10285 // scaled moving distance.
10286 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
10287 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
10288 0, 0, 0, 0));
10289 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], cookedX2,
10290 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
10291 0, 0, 0, 0));
10292
10293 // Move two fingers down again, expect one MOVE motion event.
10294 y1 += movingDistance;
10295 y2 += movingDistance;
10296
10297 processId(mapper, FIRST_TRACKING_ID);
10298 processPosition(mapper, x1, y1);
10299 processMTSync(mapper);
10300 processId(mapper, SECOND_TRACKING_ID);
10301 processPosition(mapper, x2, y2);
10302 processMTSync(mapper);
10303 processSync(mapper);
10304
10305 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10306 ASSERT_EQ(2U, motionArgs.pointerCount);
10307 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10308 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010309 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010310 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
10311 movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
10312 0, 0, 0, 0, 0));
10313 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], cookedX2,
10314 movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
10315 0, 0, 0, 0, 0));
10316}
10317
Harry Cutts39b7ca22022-10-05 15:55:48 +000010318TEST_F(MultiTouchPointerModeTest, TwoFingerSwipeOffsets) {
10319 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
10320 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10321 NotifyMotionArgs motionArgs;
10322
10323 // Place two fingers down.
10324 int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125;
10325
10326 processId(mapper, FIRST_TRACKING_ID);
10327 processPosition(mapper, x1, y1);
10328 processMTSync(mapper);
10329 processId(mapper, SECOND_TRACKING_ID);
10330 processPosition(mapper, x2, y2);
10331 processMTSync(mapper);
10332 processSync(mapper);
10333
10334 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10335 ASSERT_EQ(1U, motionArgs.pointerCount);
10336 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10337 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
10338 ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET));
10339 ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET));
10340
10341 // Move the two fingers down and to the left.
10342 int32_t movingDistance = 200;
10343 x1 -= movingDistance;
10344 y1 += movingDistance;
10345 x2 -= movingDistance;
10346 y2 += movingDistance;
10347
10348 processId(mapper, FIRST_TRACKING_ID);
10349 processPosition(mapper, x1, y1);
10350 processMTSync(mapper);
10351 processId(mapper, SECOND_TRACKING_ID);
10352 processPosition(mapper, x2, y2);
10353 processMTSync(mapper);
10354 processSync(mapper);
10355
10356 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10357 ASSERT_EQ(1U, motionArgs.pointerCount);
10358 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10359 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
10360 ASSERT_LT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET), 0);
10361 ASSERT_GT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET), 0);
10362}
10363
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000010364TEST_F(MultiTouchPointerModeTest, WhenViewportActiveStatusChanged_PointerGestureIsReset) {
10365 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
10366 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
10367 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10368 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
10369
10370 // Start a stylus gesture.
10371 processKey(mapper, BTN_TOOL_PEN, 1);
10372 processId(mapper, FIRST_TRACKING_ID);
10373 processPosition(mapper, 100, 200);
10374 processSync(mapper);
10375 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10376 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
10377 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
10378 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
10379 // TODO(b/257078296): Pointer mode generates extra event.
10380 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10381 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
10382 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
10383 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
10384 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10385
10386 // Make the viewport inactive. This will put the device in disabled mode, and the ongoing stylus
10387 // gesture should be disabled.
10388 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
10389 viewport->isActive = false;
10390 mFakePolicy->updateViewport(*viewport);
10391 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
10392 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10393 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
10394 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
10395 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
10396 // TODO(b/257078296): Pointer mode generates extra event.
10397 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10398 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
10399 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
10400 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
10401 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10402}
10403
Arthur Hung6d5b4b22022-01-21 07:21:10 +000010404// --- JoystickInputMapperTest ---
10405
10406class JoystickInputMapperTest : public InputMapperTest {
10407protected:
10408 static const int32_t RAW_X_MIN;
10409 static const int32_t RAW_X_MAX;
10410 static const int32_t RAW_Y_MIN;
10411 static const int32_t RAW_Y_MAX;
10412
10413 void SetUp() override {
10414 InputMapperTest::SetUp(InputDeviceClass::JOYSTICK | InputDeviceClass::EXTERNAL);
10415 }
10416 void prepareAxes() {
10417 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
10418 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
10419 }
10420
10421 void processAxis(JoystickInputMapper& mapper, int32_t axis, int32_t value) {
10422 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, axis, value);
10423 }
10424
10425 void processSync(JoystickInputMapper& mapper) {
10426 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
10427 }
10428
Michael Wrighta9cf4192022-12-01 23:46:39 +000010429 void prepareVirtualDisplay(ui::Rotation orientation) {
Arthur Hung6d5b4b22022-01-21 07:21:10 +000010430 setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH,
10431 VIRTUAL_DISPLAY_HEIGHT, orientation, VIRTUAL_DISPLAY_UNIQUE_ID,
10432 NO_PORT, ViewportType::VIRTUAL);
10433 }
10434};
10435
10436const int32_t JoystickInputMapperTest::RAW_X_MIN = -32767;
10437const int32_t JoystickInputMapperTest::RAW_X_MAX = 32767;
10438const int32_t JoystickInputMapperTest::RAW_Y_MIN = -32767;
10439const int32_t JoystickInputMapperTest::RAW_Y_MAX = 32767;
10440
10441TEST_F(JoystickInputMapperTest, Configure_AssignsDisplayUniqueId) {
10442 prepareAxes();
10443 JoystickInputMapper& mapper = addMapperAndConfigure<JoystickInputMapper>();
10444
10445 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
10446
Michael Wrighta9cf4192022-12-01 23:46:39 +000010447 prepareVirtualDisplay(ui::ROTATION_0);
Arthur Hung6d5b4b22022-01-21 07:21:10 +000010448
10449 // Send an axis event
10450 processAxis(mapper, ABS_X, 100);
10451 processSync(mapper);
10452
10453 NotifyMotionArgs args;
10454 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10455 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
10456
10457 // Send another axis event
10458 processAxis(mapper, ABS_Y, 100);
10459 processSync(mapper);
10460
10461 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10462 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
10463}
10464
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010465// --- PeripheralControllerTest ---
Chris Yee2b1e5c2021-03-10 22:45:12 -080010466
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010467class PeripheralControllerTest : public testing::Test {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010468protected:
10469 static const char* DEVICE_NAME;
10470 static const char* DEVICE_LOCATION;
10471 static const int32_t DEVICE_ID;
10472 static const int32_t DEVICE_GENERATION;
10473 static const int32_t DEVICE_CONTROLLER_NUMBER;
Dominik Laskowski2f01d772022-03-23 16:01:29 -070010474 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
Chris Yee2b1e5c2021-03-10 22:45:12 -080010475 static const int32_t EVENTHUB_ID;
10476
10477 std::shared_ptr<FakeEventHub> mFakeEventHub;
10478 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -070010479 std::unique_ptr<TestInputListener> mFakeListener;
Chris Yee2b1e5c2021-03-10 22:45:12 -080010480 std::unique_ptr<InstrumentedInputReader> mReader;
10481 std::shared_ptr<InputDevice> mDevice;
10482
Dominik Laskowski2f01d772022-03-23 16:01:29 -070010483 virtual void SetUp(ftl::Flags<InputDeviceClass> classes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010484 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070010485 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -070010486 mFakeListener = std::make_unique<TestInputListener>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010487 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -070010488 *mFakeListener);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010489 mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes);
10490 }
10491
10492 void SetUp() override { SetUp(DEVICE_CLASSES); }
10493
10494 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -070010495 mFakeListener.reset();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010496 mFakePolicy.clear();
10497 }
10498
Siarhei Vishniakou2935db72022-09-22 13:35:22 -070010499 std::list<NotifyArgs> configureDevice(uint32_t changes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010500 if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
10501 mReader->requestRefreshConfiguration(changes);
10502 mReader->loopOnce();
10503 }
Siarhei Vishniakou2935db72022-09-22 13:35:22 -070010504 return mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010505 }
10506
10507 std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
10508 const std::string& location, int32_t eventHubId,
Dominik Laskowski2f01d772022-03-23 16:01:29 -070010509 ftl::Flags<InputDeviceClass> classes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010510 InputDeviceIdentifier identifier;
10511 identifier.name = name;
10512 identifier.location = location;
10513 std::shared_ptr<InputDevice> device =
10514 std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
10515 identifier);
10516 mReader->pushNextDevice(device);
10517 mFakeEventHub->addDevice(eventHubId, name, classes);
10518 mReader->loopOnce();
10519 return device;
10520 }
10521
10522 template <class T, typename... Args>
10523 T& addControllerAndConfigure(Args... args) {
10524 T& controller = mDevice->addController<T>(EVENTHUB_ID, args...);
10525
10526 return controller;
10527 }
10528};
10529
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010530const char* PeripheralControllerTest::DEVICE_NAME = "device";
10531const char* PeripheralControllerTest::DEVICE_LOCATION = "BLUETOOTH";
10532const int32_t PeripheralControllerTest::DEVICE_ID = END_RESERVED_ID + 1000;
10533const int32_t PeripheralControllerTest::DEVICE_GENERATION = 2;
10534const int32_t PeripheralControllerTest::DEVICE_CONTROLLER_NUMBER = 0;
Dominik Laskowski2f01d772022-03-23 16:01:29 -070010535const ftl::Flags<InputDeviceClass> PeripheralControllerTest::DEVICE_CLASSES =
10536 ftl::Flags<InputDeviceClass>(0); // not needed for current tests
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010537const int32_t PeripheralControllerTest::EVENTHUB_ID = 1;
Chris Yee2b1e5c2021-03-10 22:45:12 -080010538
10539// --- BatteryControllerTest ---
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010540class BatteryControllerTest : public PeripheralControllerTest {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010541protected:
10542 void SetUp() override {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010543 PeripheralControllerTest::SetUp(DEVICE_CLASSES | InputDeviceClass::BATTERY);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010544 }
10545};
10546
10547TEST_F(BatteryControllerTest, GetBatteryCapacity) {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010548 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010549
Harry Cuttsa5b71292022-11-28 12:56:17 +000010550 ASSERT_TRUE(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY));
10551 ASSERT_EQ(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY).value_or(-1),
10552 FakeEventHub::BATTERY_CAPACITY);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010553}
10554
10555TEST_F(BatteryControllerTest, GetBatteryStatus) {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010556 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010557
Harry Cuttsa5b71292022-11-28 12:56:17 +000010558 ASSERT_TRUE(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY));
10559 ASSERT_EQ(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY).value_or(-1),
10560 FakeEventHub::BATTERY_STATUS);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010561}
10562
10563// --- LightControllerTest ---
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010564class LightControllerTest : public PeripheralControllerTest {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010565protected:
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010566 void SetUp() override {
10567 PeripheralControllerTest::SetUp(DEVICE_CLASSES | InputDeviceClass::LIGHT);
10568 }
Chris Yee2b1e5c2021-03-10 22:45:12 -080010569};
10570
Chris Ye85758332021-05-16 23:05:17 -070010571TEST_F(LightControllerTest, MonoLight) {
10572 RawLightInfo infoMono = {.id = 1,
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010573 .name = "mono_light",
Chris Ye85758332021-05-16 23:05:17 -070010574 .maxBrightness = 255,
10575 .flags = InputLightClass::BRIGHTNESS,
10576 .path = ""};
10577 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010578
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010579 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010580 InputDeviceInfo info;
10581 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010582 std::vector<InputDeviceLightInfo> lights = info.getLights();
10583 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010584 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10585 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10586
10587 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_BRIGHTNESS));
10588 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
10589}
10590
10591TEST_F(LightControllerTest, MonoKeyboardBacklight) {
10592 RawLightInfo infoMono = {.id = 1,
10593 .name = "mono_keyboard_backlight",
10594 .maxBrightness = 255,
10595 .flags = InputLightClass::BRIGHTNESS |
10596 InputLightClass::KEYBOARD_BACKLIGHT,
10597 .path = ""};
10598 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
10599
10600 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10601 InputDeviceInfo info;
10602 controller.populateDeviceInfo(&info);
10603 std::vector<InputDeviceLightInfo> lights = info.getLights();
10604 ASSERT_EQ(1U, lights.size());
10605 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
10606 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010607
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010608 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_BRIGHTNESS));
10609 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010610}
10611
10612TEST_F(LightControllerTest, RGBLight) {
10613 RawLightInfo infoRed = {.id = 1,
10614 .name = "red",
10615 .maxBrightness = 255,
10616 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED,
10617 .path = ""};
10618 RawLightInfo infoGreen = {.id = 2,
10619 .name = "green",
10620 .maxBrightness = 255,
10621 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN,
10622 .path = ""};
10623 RawLightInfo infoBlue = {.id = 3,
10624 .name = "blue",
10625 .maxBrightness = 255,
10626 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE,
10627 .path = ""};
10628 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
10629 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
10630 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
10631
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010632 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010633 InputDeviceInfo info;
10634 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010635 std::vector<InputDeviceLightInfo> lights = info.getLights();
10636 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010637 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10638 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10639 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
10640
10641 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10642 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
10643}
10644
10645TEST_F(LightControllerTest, CorrectRGBKeyboardBacklight) {
10646 RawLightInfo infoRed = {.id = 1,
10647 .name = "red_keyboard_backlight",
10648 .maxBrightness = 255,
10649 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED |
10650 InputLightClass::KEYBOARD_BACKLIGHT,
10651 .path = ""};
10652 RawLightInfo infoGreen = {.id = 2,
10653 .name = "green_keyboard_backlight",
10654 .maxBrightness = 255,
10655 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN |
10656 InputLightClass::KEYBOARD_BACKLIGHT,
10657 .path = ""};
10658 RawLightInfo infoBlue = {.id = 3,
10659 .name = "blue_keyboard_backlight",
10660 .maxBrightness = 255,
10661 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE |
10662 InputLightClass::KEYBOARD_BACKLIGHT,
10663 .path = ""};
10664 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
10665 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
10666 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
10667
10668 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10669 InputDeviceInfo info;
10670 controller.populateDeviceInfo(&info);
10671 std::vector<InputDeviceLightInfo> lights = info.getLights();
10672 ASSERT_EQ(1U, lights.size());
10673 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
10674 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10675 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
10676
10677 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10678 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
10679}
10680
10681TEST_F(LightControllerTest, IncorrectRGBKeyboardBacklight) {
10682 RawLightInfo infoRed = {.id = 1,
10683 .name = "red",
10684 .maxBrightness = 255,
10685 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED,
10686 .path = ""};
10687 RawLightInfo infoGreen = {.id = 2,
10688 .name = "green",
10689 .maxBrightness = 255,
10690 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN,
10691 .path = ""};
10692 RawLightInfo infoBlue = {.id = 3,
10693 .name = "blue",
10694 .maxBrightness = 255,
10695 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE,
10696 .path = ""};
10697 RawLightInfo infoGlobal = {.id = 3,
10698 .name = "global_keyboard_backlight",
10699 .maxBrightness = 255,
10700 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GLOBAL |
10701 InputLightClass::KEYBOARD_BACKLIGHT,
10702 .path = ""};
10703 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
10704 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
10705 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
10706 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoGlobal));
10707
10708 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10709 InputDeviceInfo info;
10710 controller.populateDeviceInfo(&info);
10711 std::vector<InputDeviceLightInfo> lights = info.getLights();
10712 ASSERT_EQ(1U, lights.size());
10713 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10714 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10715 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010716
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010717 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10718 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010719}
10720
10721TEST_F(LightControllerTest, MultiColorRGBLight) {
10722 RawLightInfo infoColor = {.id = 1,
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010723 .name = "multi_color",
Chris Yee2b1e5c2021-03-10 22:45:12 -080010724 .maxBrightness = 255,
10725 .flags = InputLightClass::BRIGHTNESS |
10726 InputLightClass::MULTI_INTENSITY |
10727 InputLightClass::MULTI_INDEX,
10728 .path = ""};
10729
10730 mFakeEventHub->addRawLightInfo(infoColor.id, std::move(infoColor));
10731
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010732 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010733 InputDeviceInfo info;
10734 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010735 std::vector<InputDeviceLightInfo> lights = info.getLights();
10736 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010737 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10738 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10739 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
10740
10741 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10742 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
10743}
10744
10745TEST_F(LightControllerTest, MultiColorRGBKeyboardBacklight) {
10746 RawLightInfo infoColor = {.id = 1,
10747 .name = "multi_color_keyboard_backlight",
10748 .maxBrightness = 255,
10749 .flags = InputLightClass::BRIGHTNESS |
10750 InputLightClass::MULTI_INTENSITY |
10751 InputLightClass::MULTI_INDEX |
10752 InputLightClass::KEYBOARD_BACKLIGHT,
10753 .path = ""};
10754
10755 mFakeEventHub->addRawLightInfo(infoColor.id, std::move(infoColor));
10756
10757 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10758 InputDeviceInfo info;
10759 controller.populateDeviceInfo(&info);
10760 std::vector<InputDeviceLightInfo> lights = info.getLights();
10761 ASSERT_EQ(1U, lights.size());
10762 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
10763 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10764 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010765
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010766 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10767 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010768}
10769
10770TEST_F(LightControllerTest, PlayerIdLight) {
10771 RawLightInfo info1 = {.id = 1,
10772 .name = "player1",
10773 .maxBrightness = 255,
10774 .flags = InputLightClass::BRIGHTNESS,
10775 .path = ""};
10776 RawLightInfo info2 = {.id = 2,
10777 .name = "player2",
10778 .maxBrightness = 255,
10779 .flags = InputLightClass::BRIGHTNESS,
10780 .path = ""};
10781 RawLightInfo info3 = {.id = 3,
10782 .name = "player3",
10783 .maxBrightness = 255,
10784 .flags = InputLightClass::BRIGHTNESS,
10785 .path = ""};
10786 RawLightInfo info4 = {.id = 4,
10787 .name = "player4",
10788 .maxBrightness = 255,
10789 .flags = InputLightClass::BRIGHTNESS,
10790 .path = ""};
10791 mFakeEventHub->addRawLightInfo(info1.id, std::move(info1));
10792 mFakeEventHub->addRawLightInfo(info2.id, std::move(info2));
10793 mFakeEventHub->addRawLightInfo(info3.id, std::move(info3));
10794 mFakeEventHub->addRawLightInfo(info4.id, std::move(info4));
10795
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010796 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010797 InputDeviceInfo info;
10798 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010799 std::vector<InputDeviceLightInfo> lights = info.getLights();
10800 ASSERT_EQ(1U, lights.size());
10801 ASSERT_EQ(InputDeviceLightType::PLAYER_ID, lights[0].type);
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010802 ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10803 ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010804
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010805 ASSERT_FALSE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10806 ASSERT_TRUE(controller.setLightPlayerId(lights[0].id, LIGHT_PLAYER_ID));
10807 ASSERT_EQ(controller.getLightPlayerId(lights[0].id).value_or(-1), LIGHT_PLAYER_ID);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010808}
10809
Michael Wrightd02c5b62014-02-10 15:10:22 -080010810} // namespace android